I am doing a SPA with web api as the backend and AngularJS as the SPA.
I am using attribute routing in WebApi2. The problem is when I do any http request that matches the following skeleton, it throws me a 404 NOT Found.
Request: http://localhost:63915/api/cab/delete/2
Request:
Error:
WebApiConfig Code:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
RouteDeclaration:
[RoutePrefix("api/driver")]
public class DriverController : ApiController
{
[POST("new")]
public bool NewDriver(DriverModel driver)
{
return new DatabaseService().CreateNewDriver(driver);
}
[GET("all")]
public List<DriverModel> GetAllDrivers()
{
return new DatabaseService().GetDriverList();
}
[DELETE("delete/{id}")]
public bool Delete(int id)
{
return new DatabaseService().DeleteDriver(id);
}
}
If I do something like api/driver/delete?id=2 and change the route to [DELETE("delete")] it works.
Is everything all right with my config ?
I think the problem might be with my config only. Please tell me what I am missing to make the route work.
I added another route to the WebApiConfig and it works!
config.Routes.MapHttpRoute(
name: "ComplexApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Related
I am new to MVC and C#, so sorry if this question seems too basic.
I have trouble with calling 'action' in web api.
I don't know why my method below always throws an error:
"No HTTP resource was found that matches the request URI 'https://localhost:44358/api/RollUp/TrainingImage".
While other methods ([HttpGet]) run normally
public class RollUpController : ApiController
{
.
.
. orther method
[HttpPost]
public string TrainingImage(string name)
{
return name;
}
}
This is the file webApiConfig.cs:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
This is the result when I test it by PostMan : test by postman
I cannot figure out why one my attribute routing isn't working, the first action method works but not the second one.
Here is my setup:
public class ActivMobileController : ApiController
{
[HttpGet]
[Route("api/ActivMobile/Impact/{token}")]
public IHttpActionResult Impact(string token)
{
...
}
[HttpGet]
[Route("api/ActivMobile/Attachments/{id}")]
public IHttpActionResult Attachments(string id)
{
...
}
}
here is my WebApiConfig:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Reference: https://learn.microsoft.com/en-us/aspnet/web-api/overview/security/enabling-cross-origin-requests-in-web-api
config.EnableCors(new EnableCorsAttribute(CloudConfigurationManager.GetSetting("AllowOrigins"), "*", "*"));
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
Here is the URL im testing and it gives 404 Error
http://localhost:60105/api/ActivMobile/Attachments/39E522838A652508112E9AD1E0E831C7
You're specifying API twice when it's already in your default template
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Remove the redundant Api/activMobile from your routes
[Route("Impact/{token}")]
public IHttpActionResult Impact(string token)
{
...
}
[HttpGet]
[Route("Attachments/{id}")]
public IHttpActionResult Attachments(string id)
{
...
}
When i am hitting the url:
http://localhost/api/adxxx/getDeals/?input=2
I get the following error:
"Message": "No HTTP resource was found that matches the request URI
'http://localhost/api/adxxx/getDeals/?input=2'.",
"MessageDetail": "No type was found that matches the controller
named 'adxxx'."
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.DependencyResolver = new UnityResolver(UnityBootstrapper.Initialise());
config.EnableCors();
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "xxx.services",
routeTemplate: "webapi/{controller}/{action}"
);
config.Routes.MapHttpRoute(
name: "xxx.services_new",
routeTemplate: "api/{controller}/{action}",
defaults: new { id = RouteParameter.Optional }
);
FluentValidationModelValidatorProvider.Configure(config);
}
}
[Route("api/adxxx/getDeals/")]
public IHttpActionResult GetDeals(int input)
{
//code here
}
How do i resolve this? Very similar apis having different route are working fine.
This happened when i have added fluent validation to my api. That updated my System.Web.Http.dll to v5.2.3.0
Correct your route config for allow parameter
[Route("api/adxxx/getDeals/{input}")]
public IHttpActionResult GetDeals(int input)
{
//code here
}
and then you can request it by
http://localhost/api/adxxx/getDeals/2
I have my MVC 4 Project API Routing configured as follow:
WebApiConfig.cs:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
var company = System.Configuration.ConfigurationManager.AppSettings["DbCompany"];
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "MyApp/"+ company +"/{id}",
defaults: new { controller = "main" , id = RouteParameter.Optional }
);
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/plain"));
}
}
and MainController.cs contains the following methods:
public JToken Get(string id)
{
...
}
public JToken Get()
{
...
}
[HttpPost]
public JToken DoQuery([FromBody] String query)
{
...
}
public void Post([FromBody] JObject JsonObject)
{
...
}
What I would like to achieve is for any route that is not :
route: /MyApp/MyComp/DoQuery
method: POST
ContextType: text/plain
Returns: JToken
To use normal Get/Post of the main controller
Otherwise use DoQuery in the main controller.
Seems like all you are missing is the special case route to map to DoQuery.
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
var company = System.Configuration.ConfigurationManager.AppSettings["DbCompany"];
config.Routes.MapHttpRoute(
name: "DoQuery",
routeTemplate: "MyApp/"+ company +"/DoQuery",
defaults: new { controller = "main", action = "DoQuery" }
);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "MyApp/"+ company +"/{id}",
defaults: new { controller = "main" , id = RouteParameter.Optional }
);
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/plain"));
}
}
I need to use multiple POST-requests in web API but get an error: "Multiple actions were found that match the request..."
I have 2 POST-requests in my controller:
public void PostStart([FromBody]string value)
{
CookieHeaderValue cookie = Request.Headers.GetCookies("user").FirstOrDefault();
...
}
public void PostLogin([FromBody]string value)
{
CookieHeaderValue cookie = Request.Headers.GetCookies("user").FirstOrDefault();
...
}
My route file looks like this currently:
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "apistart",
routeTemplate: "Home/api/values/start/{id}",
defaults: new { action = "PostStart", id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "apilogin",
routeTemplate: "Home/api/values/login/{id}",
defaults: new { action = "PostLogin", id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
If I remove on of the requests from the controller, everything works fine, so my routes seem valid, but when both of requests are present, router can't find the right one.
Any thoughts?
I've tried alredy to use another default route but it changes nothing:
routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
You can use [HttpPost] attribute to specify request method:
[HttpPost]
public void Start([FromBody]string value)
{
CookieHeaderValue cookie = Request.Headers.GetCookies("user").FirstOrDefault();
...
}
[HttpPost]
public void Login([FromBody]string value)
{
CookieHeaderValue cookie = Request.Headers.GetCookies("user").FirstOrDefault();
...
}
That will allows you to use as many post actions as you want with using default action-based route rule.
routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
You should use RouteAttribute to make it work:
[Route("start")]
public void PostStart([FromBody]string value)
{
CookieHeaderValue cookie = Request.Headers.GetCookies("user").FirstOrDefault();
...
}
[Route("login")]
public void PostLogin([FromBody]string value)
{
CookieHeaderValue cookie = Request.Headers.GetCookies("user").FirstOrDefault();
...
}
WebApi doesn't take into consideration method name, only first word to resolve http method. Thats why you have error which says about "Multiple actions..." - there are two actions which can handle POST request.