I have a webapi2 project and I want to selfhost this api in another project and call the methods with a httpClient. Here is my code:
namespace TestSelfHosting.Controllers
{
public class ProductsController : ApiController
{
[HttpGet]
public string GetProduct()
{
return "test";
}
}
}
And the code from the test project:
namespace TestSelfHosting.Tests
{
public class Startup
{
public void Configuration(IAppBuilder appBuilder)
{
// Configure Web API for self-host.
HttpConfiguration config = new HttpConfiguration();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
appBuilder.UseWebApi(config);
}
}
}
namespace TestSelfHosting.Tests
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
const string baseAddress = "http://localhost:9000/";
// Start OWIN host
using (WebApp.Start<Startup>(url: baseAddress))
{
// Create HttpCient and make a request to api/values
HttpClient client = new HttpClient();
var response = client.GetAsync(baseAddress + "api/products").Result;
var content = response.Content.ReadAsStringAsync().Result;
}
}
}
}
But when I'm calling client.GetAsync method, is throwing an error (404, not found). Is this possible to achieve or am I doing something wrong?
I've followed the tutorial from here
Have you referenced your webapi2 project in the self-host project (test project)?
If not, go to your self-host project -> references -> add reference -> locate your webapi2.dll and add it (you must build your webapi2 project beforehand to “generate” the dll file)
Related
I have a simple self-hosted OWIN ASP.NET API as seen in the code below.
I need to run this over https. Is it as simple as changing the BaseAddress and installing a self-signed certificate as given here:
https://chavli.com/how-to-configure-owin-self-hosted-website-with-ssl/
If not, what's the simplest way of configuring SSL for this case ?
internal class Program
{
private static string BaseAddress = "http://localhost:9005/";
private static void Main(string[] args)
{
var app = WebApp.Start<Startup>(url: BaseAddress);
Console.ReadLine();
}
}
public class Startup
{
// This code configures Web API. The Startup class is specified as a type
// parameter in the WebApp.Start method.
public void Configuration(IAppBuilder appBuilder)
{
// Configure Web API for self-host.
HttpConfiguration config = new HttpConfiguration();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "{controller}/",
defaults: new { id = RouteParameter.Optional }
);
appBuilder.UseWebApi(config);
}
}
I am having difficulties to understand how WebAPI routing is working. This is what my controller looks like:
[RoutePrefix("order-mgmt")]
public class OrderController : ApiController
{
[HttpGet]
[Route("execute")]
public HttpResponse ExecOrder(string clordid)
{
// ...
return Request.CreateResponse(HttpStatusCode.NoContent);
}
[HttpGet]
[Route("reject")]
public HttpResponse RejectOrder(string clordid)
{
// ...
return Request.CreateResponse(HttpStatusCode.NoContent);
}
}
And this is my Startup class and configuration
public class Startup
{
public void Configuration(IAppBuilder appBuilder)
{
// Configure Web API for self-host.
var config = new HttpConfiguration();
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
appBuilder.UseWebApi(config);
}
}
I was expecting that I am able to reach public HttpResponseMessage ExecOrder(string clordid) via http://localhost:port/api/order-mgmt/execute?clordid=<clordidstring>.
This however doesn't work. The controller is still only reachable via api/order/execute. I really don't get what I am doing wrong here. Any help is greatly appreciated.
try removing [RoutePrefix("order-mgmt")]
then do it like this
[Route("api/order-mgmt/execute/{clordid}")]
public HttpResponse ExecOrder(string clordid)
// then you can reach it in this route
// api/order-mgmt/execute/YOUR_STRING
I have a web api that runs in a WPF C# application. I have used Owin to implement it. If I send request by using /api prefix then it works as I expected.
http://localhost:8080/api/test/config?no=7
However, I need to remove the /api prefix. If I try the request below it does not work when I tried example code below.
http://localhost:8080/test/config?no=7
Is it possible to remove api word from requests?
Here is my code:
WebApp.Start<Startup>(url: "http://*:8080/");
class Startup
{
Type ValuesControllerType = typeof(TestController);
public void Configuration(IAppBuilder Builder)
{
var Instance = new HttpConfiguration();
Instance.MapHttpAttributeRoutes();
Instance.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "{controller}/{action}/{request}",
defaults: new { request = RouteParameter.Optional }
);
Builder.UseWebApi(Instance);
}
}
[RoutePrefix("test")]
public class TestController : ApiController
{
[HttpGet]
[Route("config")]
public string Config(string No)
{
try
{
return No;
}
catch (Exception e)
{
return string.Empty;
}
}
}
I tried the answer in C# web api route for a webservice but did not work.
I get following error:
HTTP Error 503. The service is unavailable.
On the Rest api open your WebApiConfig.cs you should find the following code:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}"
);
Try removing api from there
I faced the same problem in .Net Core 2 WebAPI project
here is my solution
[Produces("application/json")]
[Route("[controller]")]
public class DefaultController : Controller
{
[Route("getUser")]
public IActionResult GetUsers()
{
return Ok();
}
}
the address is http://localhost:port/default/getuser
I have two web API project DLLs in one solution.
Structure of my Project Solution:
In my solution, the projects are located as follows:
1) Base Solution
2) Base Web API
3) Module Web API
Hence, my solution is something like a BASE solution which contains many MODULES. Each Modules can contain its own Web APIs. Also, my Base Solution contains its own Web API
This is our structure.
My Problem:
It is working fine in my local run solution. When I host it to the IIS, it is working for few hours and then it stops working by throwing the error message "Error 404 found". When I try to access through URL directly which is something like "http://127.0.0.1:51/Products/Get", not working.
Visual Studio version:
Visual Studio Professional - 2015
IIS Version:
IIS - 7.5.7600
My approach:
I have a simple project which simulates this scenario. It has the same problem with my original project.
Web API For Base Module:
WepApiConfig under App_Start:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
Base API Controller:
public class ValuesController : ApiController
{
// GET api/values
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/values/5
public string Get(int id)
{
return "value";
}
}
WebApiConfig.cs For Module Web API:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
// Web API routes
//config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultModuleApi",
routeTemplate: "api/module/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
Module API Controller:
public class ModulesController : ApiController
{
// GET api/values
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/values/5
public string Get(int id)
{
return "value";
}
}
NOTE from the above code:
The difference between the two APIConfig files is :
For Module Code:
routeTemplate: "api/module/{controller}/{action}/{id}"
For Base Code:
routeTemplate: "api/{controller}/{action}/{id}"
Global.asax:
namespace BaseSln
{
public class Global : HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
//GlobalConfiguration.Configure(WebApiConfig.Register);
var typesWithMyAttribute =
from a in AppDomain.CurrentDomain.GetAssemblies()
from t in a.GetLoadableTypes().Where(t1 => t1.Name == "WebApiConfig"
&& t1.GetMethod("Register") != null
&& t1.GetMethod("Register").IsStatic)
select new { Type = t, MethodInfo = t.GetMethod("Register") };
//register all the Routes
foreach (var type in typesWithMyAttribute)
{
var mi = type.MethodInfo;
Action<HttpConfiguration> action = null;
try
{
action = Delegate.CreateDelegate(typeof(Action<HttpConfiguration>), mi) as Action<HttpConfiguration>;
}
catch
{
//ignore the errors for now... should be handled somewhere else or logged.
}
if (action != null) GlobalConfiguration.Configure(action);
}
}
}
}
What I tried with the above project:
After hosting in IIS, I tried to access the path which is something like this:
For Base API:
http://localhost:51600/api/Values/Get
Returns:
value1
value2
For Module API
http://localhost:51600/api/Modules/Get
Returns:
value1
value2
My problem:
After sometime, when I try to access the same link, I am unable to get that. It says
status 404. Not Found
I have been working on this issue for 3 days, and I couldn't resolve the problem.
I have searched many articles in stackoverflow, but no luck.
Kindly help me to get rid off from this.
Thanks.
Can you check the GlobalConfiguration.Configuration.Routes in the Base Solution if you have all the routes for both the Base Web API and the Module Web API?
Thanks to the help of some users on this site, I got my test application working and am now starting to write the actual application I need.
I have a C# application which uses OWIN to host a ASP.NET Web API. I need the application to supply information about other open applications. I have programmed it nearly exactly the same as my test/example program which I got working, but changed a few names.
When I try to access `http://localhost:9000/api/applications I get an error message:
<Error>
<Message>
No HTTP resource was found that matches the request URI 'http://localhost:9000/api/applications'.
</Message>
<MessageDetail>
No type was found that matches the controller named 'applications'.
</MessageDetail>
</Error>
`The Server class is the main class:
namespace Server
{
public class Server
{
public const string baseAddress = "http://localhost:9000/";
static void Main(string[] args)
{
ApplicationManager.getManager().AddApplication(new Application(1, "Chrome", 0.5f));
ApplicationManager.getManager().AddApplication(new Application(2, "Windows Media Player", 1.0f));
ApplicationManager.getManager().AddApplication(new Application(3, "Minecraft", 1.0f));
using (WebApp.Start<Startup>(url: baseAddress))
{
Console.ReadKey();
}
}
}
}
This is a my Web API config class:
namespace Server
{
public class Startup
{
public void Configuration(IAppBuilder appBuilder)
{
HttpConfiguration config = new HttpConfiguration();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
appBuilder.UseWebApi(config);
}
}
}
And here is my controller:
namespace Server.Api.Controllers {
public class ApplicationController : ApiController
{
public IEnumerable<Application> Get()
{
return ApplicationManager.getManager().GetApplications();
}
public IHttpActionResult Get(int id)
{
Application app = ApplicationManager.getManager().GetApplication(id);
if (app == null)
{
return NotFound();
}
return Ok(app);
}
} }
The Application object just contains a few properties and constructors. The ApplicationManager class just adds applications to a list of applications, which is used by the controller.
Replace http://localhost:9000/api/applications by http://localhost:9000/api/application. Last letter s caused this issue. Hope this helps!
I was facing this problem as well. After struggling a lot I realized that my Controller class was private which was causing the issue.