WebApi does not accept post (404 error) - asp.net-mvc

I have a MVC4 web project with WebAPI enabled.
I want to post data to the API controller but the post is not working, I am getting a 404 every time (breakpoint inside the Add method is not hit)....
Here is the code:
public class IncidentSessionLogController : ApiController
{
[HttpPost]
public void Add(MyInputDTO inputData)
{
}
}
I use action based routing:
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "ControllerAndAction",
routeTemplate: "api/{controller}/{action}");
config.Routes.MapHttpRoute(
name: "ControllerAndActionAndId",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional });
}
I use Fiddler to post the data:
http://localhost:42901/api/IncidentSessionLog/Add
My site is hosted in IIS express for development currently, I add the JSON object literal in the request body in Fiddler.

Fixed it, thanks to my collegue !
The MVC routing(which I forgot to post originally), was interfering with the API routing, so I have to add a constraint to the MVC routing :
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Game", action = "Start", id = UrlParameter.Optional },
constraints: new { controller = #"^((?!(api)).)*$" });

Related

How to Implement Method in Web API

I have a web API controller:
public List<mytable> Get(string filter1, string filter2){
...
}.
I need to create another method named
List<drpSubject> GetSubject(){
...
}.
My WebApiConfig.cs like this
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
// routeTemplate: "api/{controller}/{id}",
routeTemplate: "{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute("DefaultApiWithAction", "{controller}/{action}");
}
But now I get error message "Multiple actions were found that match the request..." . It only works when there is one Get(). How to create web api that can take multiple actions? Thanks.
There are multiple ways to configure routing.
You could change
"{controller}/{id}",
to
"{controller}/{action}/{id}",
More at Routing by Action Name.

Why can't navigate to web api controller

I use Web API for the first time to connect my mobile app to Web API.
I have MVC 5 project and I have created API folder and inside I have created ProductsController.
namespace DDD.WebUI.API
{
public class ProductsController : ApiController
{
public string GetAllProducts()
{
return "Hello From WebAPI";
}
}
}
And I have tried to access this method from browser:
http://localhost:21879/DDD.WebUI/API/products/GetAllProducts
But I get 404.
It's probably something stupid but can't figure it :(
UPDATE
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "DefaultApi",
url: "API/{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
UPDATE 2
I have a little progress:
I have update Application_Start() with:
GlobalConfiguration.Configure(WebApiConfig.Register);
RouteConfig.RegisterRoutes(RouteTable.Routes);
In WebApiConfig I have:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
I still store API controller in Project/Api/ProductsController
But now I can access it but still can't get value from it:
http://localhost:21879/api/products/getallproducts
But error I get is:
<Error>
<Message>The request is invalid.</Message>
<MessageDetail>
The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.String Get(Int32)' in 'GSL.WebUI.Api.ProductsController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
</MessageDetail>
</Error>
I had the same problem. Watch the order in which you register your routes in Global.asax.cs.
This works:
GlobalConfiguration.Configure(WebApiConfig.Register);
RouteConfig.RegisterRoutes(RouteTable.Routes);
This doesn't:
RouteConfig.RegisterRoutes(RouteTable.Routes);
GlobalConfiguration.Configure(WebApiConfig.Register);
If you use that way of routing, you need to specify the allowed Http methods for the action:
public class ProductsController : ApiController
{
[HttpGet]
public string GetAllProducts()
{
return "Hello From WebAPI";
}
}
You can get all the information regarding API routing from this link: http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api
I think looking at your update your action requires id which is of non-nullable int and you are not supplying it just modify url as http://localhost:21879/API/products/GetAllProducts/2 here '2' is assigned to 'id' and it will work.
In WebApiConfig modify route as :
config.Routes. MapHttpRoute (
name: "DefaultApi" ,
routeTemplate: "api/{controller}/{action}/{id}" ,
defaults: new { id = RouteParameter . Optional }
);
Just change this Mvc Route :
routes. MapRoute(
name: "DefaultApi" ,
url: "API/{controller}/{action}/{id}" ,
defaults: new { controller = "Home" , action = "Index" , id = UrlParameter .Option
);
with this :
routes. MapRoute(
name: "DefaultApiMvc" ,
url: "APIMvc/{controller}/{action}/{id}" ,
defaults: new { controller = "Home" , action = "Index" , id = UrlParameter .Option
);
because otherwise Mvc and Api routes will conflict with each other...

ASP.NET Web API Routing in ApiController

I've been struggling with my routing for some time now and after a few days of trying to Google the solution without luck, I'm hoping someone may be able to shine some light on my problem.
I have the following routes in my WebApiConfig:
config.Routes.MapHttpRoute(
name: "AccountStuffId",
routeTemplate: "api/Account/{action}/{Id}",
defaults: new { controller = "Account", Id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "AccountStuffAlias",
routeTemplate: "api/Account/{action}/{Alias}",
defaults: new { controller = "Account", Alias = RouteParameter.Optional }
);
and the following controller methods:
[HttpGet]
public Account GetAccountById(string Id)
{
return null;
}
[HttpGet]
public Account GetAccountByAlias(string alias)
{
return null;
}
If I call:
/API/Account/GetAccountById/stuff then it properly calls GetAccountById.
But if I call /API/Account/GetAccountByAlias/stuff then nothing happens.
Clearly order matters here because if I switch my declarations of my routes in my WebApiConfig, then /API/Account/GetAccountByAlias/stuff properly calls GetAccountByAlias, and /API/Account/GetAccountById/stuff does nothing.
The two [HttpGet] decorations are part of what I found on Google, but they don't seem to resolve the issue.
Any thoughts? Am I doing anything obviously wrong?
Edit:
When the route fails, the page displays the following:
<Error>
<Message>
No HTTP resource was found that matches the request URI 'http://localhost:6221/API/Account/GetAccountByAlias/stuff'.
</Message>
<MessageDetail>
No action was found on the controller 'Account' that matches the request.
</MessageDetail>
</Error>
You should be able to just have the following route:
config.Routes.MapHttpRoute(
name: "AccountStuffId",
routeTemplate: "api/Account/{action}/{Id}",
defaults: new { controller = "Account", Id = RouteParameter.Optional }
);
and do the following for your actions:
[HttpGet]
public Account GetAccountById(string Id)
{
return null;
}
[HttpGet]
public Account GetAccountByAlias([FromUri(Name="id")]string alias)
{
return null;
}
Is there a reason you need to be declaring two different routes?
Look at the guide at: http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api
They have one default route and going by the example all you need in your config is
routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);

Separate MVC and webAPI controller route

I have created a WebApi project, which has multiple WebApi controllers. As per my requirement I have to add an MVC controller to my WebApi project. My client side code is making an ajax request to that MVC controller with {ControllerName/ActionMethodName}. I have multiple routes in my global.asax file:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
routes.MapHttpRoute(
name: "ActionRoute",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Below is my ReportServiceBaseController:
protected virtual ReportServiceBase CreateReportService();
[HttpPost]
public JsonResult LoadDocumentInfo(LoadDocumentInfoRequest request);
[HttpPost]
public JsonResult LoadDocumentMapInfo(LoadDocumentMapInfoRequest request);
[HttpPost]
public JsonResult LoadDocumentMapInfoFull(LoadDocumentMapInfoFullRequest request);
[HttpPost]
public JsonResult LoadPageInfo(LoadPageInfoRequest request);
I am inheriting that controller in a ReportService controller:
public class ReportServiceController : ReportServiceBaseController
{
protected override PerpetuumSoft.Reporting.WebViewer.Server.ReportServiceBase CreateReportService()
{
return new ServiceClass();
}
}
The client side URL which is making the request:
"http://" + hostName + "/ReportService/LoadDocumentInfo"
I think the WebApi route is suppressing the MVC Controller route. How can I separate the MVC Controller route from the WebApi route?
You can create a new config class of WebApi, ApiRouteConfig.cs, within App_Start.
namespace Mvc4App
{
public class ApiRouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapHttpRoute(
name: "ActionRoute",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
}
Then, edit Global.asax.cs, to call ApiRouteConfig.RegisterRoutes(RouteTable.Routes);

Adding Routes for WebAPI in MVC 4

I've got a WebApi Controller and want to add a route.
Here is my Controller ...
public class ExtraInformationController : ApiController
{
private readonly ExtraInformationRepository _extraInfoRepository = new ExtraInformationRepository();
public ExtraInformation Get(int assetId)
{
return _extraInfoRepository.GetByAssetID(assetId).FirstOrDefault();
}
}
Heres my route ...
routes.MapHttpRoute(
"ExtraInformation",
"api/ExtraInformation/{assetId}",
new { controller = "ExtraInformation", action = "Get" }
);
I want to be able to call ...
api/ExtraInformation/4
But I'm getting ...
No HTTP resource was found that matches the request URI 'http://localhost:35188/api/ExtraInformation/4'.No action was found on the controller 'ExtraInformation' that matches the request.
Can anyone assist please?
Using the generic default route should be enough looking at your example. I would swap it for this and give it a try.
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);

Resources