I am developing a web api but it can not hit it. Error shows 404 not Found.
Web Api
using Atea.Azure.ApiMangement.Business;
using System.Web.Http;
namespace Azure_API_Delegation_Portal.Controllers
{
[RoutePrefix("api/apim")]
public class ApimController : ApiController
{
private readonly ISubscriptionService _subscriptionService;
[HttpGet]
[Route("{string:productId}")]
public bool GetProductSubscribe(string productId)
{
return _subscriptionService.IsSubscribed(productId);
}
}
}
How I call an API https://localhost:44300/api/apim/ldkjfk232
Web API Route
using System.Web.Http;
namespace Azure_API_Delegation_Portal
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
}
Image
I am missing this line of code in Application_Start() function in "Global.asax" file.
GlobalConfiguration.Configure(WebApiConfig.Register);
Fix your route template. It is string by default so no need for the string constraint
//GET api/apim/ldkjfk232"
[HttpGet]
[Route("{productId}")]
public bool GetProductSubscribe(string productId)
Also note that the constraint goes after the placeholder name like this example
[Route("{paramaterName:int}")]
Read more about attribute routing here : Attribute Routing in ASP.NET Web API 2
It will show you how to properly configure your web api.
Related
I am using Owin self-hosting with WebAPI2.
I have two controller classes and using attribute routing.
One of them has following signature:
[RoutePrefix("api/v1/devices")]
public class DeviceController : ApiController
{
[HttpPost]
[Route("")]
public async Task<HttpResponseMessage> DevicePresence()
{
...
}
[HttpGet]
[Route("updates/{deviceID}")]
public HttpResponseMessage GetDeviceUpdates(string deviceID)
{
...
}
}
This one is working fine and action methods get triggered.
The other Controller has below signature:
[RoutePrefix("device/class")]
public class RemoteController : ApiController
{
[HttpGet]
[Route("remotehost")]
public HttpResponseMessage RemoteHost()
{
...
}
[HttpGet]
[Route("version")]
public HttpResponseMessage GetVersion()
{
...
}
}
When I try to connect to any of these I get 503 (Service Unavailable) response.
My Startup class is initialized as below:
public class Startup
{
public static void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
config.MapHttpAttributeRoutes();
config.Formatters.Add(new JsonMediaTypeFormatter());
config.Formatters.Remove(config.Formatters.XmlFormatter);
config.EnsureInitialized();
app.UseWebApi(config);
}
}
I tried to use the conventional routing as well but still the same problem.
config.Routes.MapHttpRoute(
name: "RemoteApi",
routeTemplate: "device/{controller}/{action}"
);
public class ClassController : ApiController
{
public HttpResponseMessage GetVersion()
{
...
}
}
This is also throwing 503 status code
If I change the Route prefix in the second controller as below then it's working:
[RoutePrefix("api/v1/device/class")]
public class RemoteController : ApiController
{
...
}
As per my requirement, I couldn't change the endpoints.
I am not sure what's wrong here and any help would be much appreciated.
Your RemoteController throws an exception because you do not follow naming conventions of WEB API.
Your RemoteHost() method which is a get method has to have a "Get" prefix, so its name is supposed to actually be GetRemoteHost().
That should solve it.
In case you want to alter the naming conventions, you can modify route definitions in the global.asax file:
Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { action = "get", id = RouteParameter.Optional }
);
Hope that helped.
I realized it was not a problem with webapi or routing.
Actually, I was adding a firewall exception for the URL's and somehow it was not getting removed from firewall settings and keeps an entry in DACL.
I removed this from cmd prompt and now everything works fine.
Sorry for bothering...
When using the following routes:
config.Routes.MapHttpRoute(
name: "new_device",
routeTemplate: "api/v1/devices",
defaults: new { controller = "Devices", action = "new_device" }
);
config.Routes.MapHttpRoute(
name: "devices_list",
routeTemplate: "api/v1/devices",
defaults: new { controller = "Devices", action = "devices_list", httpMethod = new HttpMethodConstraint(HttpMethod.Get) }
);
The controller looks as follows:
public class DevicesController : ApiController
{
[HttpPost]
[ResponseType(typeof(IHttpActionResult))]
[Route("api/v1/devices")]
[ActionName("new_device")]
[ValidateModel]
public IHttpActionResult NewDevice([System.Web.Http.FromBody] Device device )
{
...
}
[HttpGet]
[ResponseType(typeof(IHttpActionResult))]
[Route("api/v1/devices")]
[ActionName("devices_list")]
[ValidateModel]
public List<Device> GetAllDevices()
{
...
}
My expectation would be that the router would find the correct route based on the HttpMethod used since even it's using the same URI it is using a different HttpMethod.
But instead it fails with the following:
"Message": "The requested resource does not support http method 'GET'."
My guess is because it fins a match with the URI and then checks if the method if the same.
Is there a way to achieve using the same URI with different Http Method which is by the way REST guidelines? Am I missing something?
Ok , I check your whole code. I think you are trying to achieve the calls in complicated way.
Following code is for the configuration :
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/v1/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
and follwoing is your controller code :
public class DevicesController : ApiController
{
[HttpPost]
[ResponseType(typeof(IHttpActionResult))]
[ActionName("newDevice")]
public IHttpActionResult NewDevice([System.Web.Http.FromBody] Device device)
{
return null;
}
[HttpGet]
[ResponseType(typeof(IHttpActionResult))]
[ActionName("devices_list")]
public List<Device> GetAllDevices()
{
return null;
}
}
I removed ValidateModel. I think it's your custom attribute or somehow related with built in nuget package.
Anyways, execute the calls with Postman or any HTTP client tool. It should work , as it was working at my end with above mentioned code.
Example Calls:
https://localhost:44370/api/v1/devices/devices_list = > Get.
https://localhost:44370/api/v1/devices/newDevice => Post. Provide body as post call for the object.
My Web API on an Asp.Net MVC web app is returning 404 error when receiving requests that don't specify any controller.
The calls that are returning 404 error are:
https://myWebApp/api/
The goal would be to handle these type of requests without returning error and return something like "true" or "new EmptyResult()".
Current routing for the Web API includes the following in WebApiConfig.cs
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Filters.Add(new IdentityBasicAuthenticationAttribute());
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
While I have routes explicitly defined for each API controller:
[IdentityBasicAuthentication]
[Authorize]
public class myApi1Controller : ApiController
{
[HttpGet]
[Route("api/myApi1")]
public string Get(string id) { ... }
}
I have tried to route these calls to a default API or MVC controller without success.
My current RouteConfig for the MVC app is:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "myWebApp.Controllers" }
);
}
}
The order in which these are called is:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
Create a controller to handle that route so it does not fail with not found
Like
[RoutePrefix("api")]
public class MyEmptyController : ApiController {
//GET api
[HttpGet]
[Route("")]
public IHttpActionResult Get() {
return StatusCode(HttpStatusCode.NoContent); //204
}
}
Using attribute routing as it is already enabled via config.MapHttpAttributeRoutes(); in WebApiConfig
Your route config is different from your WebApi config and I don't know the order that you are calling them.
in your RouteConfig:
url: "{controller}/{action}/{id}",
which means: http://localhost:PORTNUMBER/myApi1/ACTION
in your WebApiConfig
routeTemplate: "api/{controller}/{id}",
(method and id are optionals)
which means: http://localhost:PORTNUMBER/api/myApi1/?id=value
change your WebApiConfig, and you even will be able to avoid using the Route tag in your controller :
[IdentityBasicAuthentication]
[Authorize]
public class myApi1Controller : ApiController
{
[HttpGet]
public string Get(string id) {
return "works!";
}
}
Edit:
Keep every thing the same, Invoke your default GET method from:
http://localhost:PORTNUMBER/api/myApi1
i'm using asp.net web api. And my problem is "Multiple actions were found that match the request" but i set route template already and in my controller i have 2 POST action
**WebApiConfig**
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Formatters.JsonFormatter.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
}
}
And this is my controller
1. [Route("{InsertRoadMap}")]
[HttpPost]
public mdRoadMapCallBack InsertRoadMap(mdEvent _mdEvent){
mdRoadMapCallBack _mdRoadMapCallBack = new mdRoadMapCallBack();
return _mdRoadMapCallBack;
}
2. [Route("{UpdateRoadMap}")]
[HttpPost]
public mdRoadMapCallBack UpdateRoadMap(mdEvent _mdEvent)
{
mdRoadMapCallBack _mdRoadMapCallBack = new mdRoadMapCallBack();
return _mdRoadMapCallBack;
}
What is wrong ? Please help. Thank you so much
The Route attribute doesn't seems to be implemented correctly.
Use it like this instead -
[Route("api/mycontroller/InsertRoadMap")]
[Route("api/mycontroller/UpdateRoadMap")]
Now you can browse like this - http://server/api/mycontroller/InsertRoadMap
You can also use RoutePrefix attribute at controller level so that you do not have to repeat api for every method.
[RoutePrefix("api")]
And then you can set routes like -
[Route("mycontroller/InsertRoadMap")]
[Route("mycontroller/UpdateRoadMap")]
See here and here some more information on attribute routing
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