Issue in accessing POST parameters in web api controller in MVC 3 - asp.net-mvc-3

I am hitting the controller the controller with the following url :
"http://localhost/api/controller/1/2"
In the controller I have the following methods:
[HttpPost]
public void PostMethod2(string a,string b)
[HttpPost]
public void PostMethod()
The controller is actually hitting the PostMethod() but I dont know how to read the parameter values 1 and 2.
Is there any other better way of calling it?

You can add your custom route for this method in Global.asax.cs
routes.MapRoute("PostMethod2",
"api/mycontroller/{a}/{b}",
new { contorller = "mycontroller", action="PostMethod2"}
);
Or if you're using ASP.NET MVC Web Api you can hook your route in RouteConfig.cs in App_Start folder like so:
routes.MapHttpRoute(
name: "PostMethod2",
routeTemplate: "api/mycontroller/{a}/{b}",
);

Related

How to set up routes correctly for webapi controller so id is picked up as part of url instead of querystring

I'm having an issue with getting urls to resolve to my controllers properly by getting the id from the url rather than a querystring parameter. I have a .net webapi project set up with the following folder structure.
Root
Controllers
v1
Partner
CompaniesController
PersonController
QuoteController
So as you can see the CompaniesController is in the Partner folder while the other controllers are in the v1 folder. I'm also using a RoutePrefix on my CompaniesController such as...
[EnableCors("*", "*", "*")]
[RoutePrefix("api/v1/partner/companies")]
public class CompaniesController : BaseApiController{
[Route("contact")]
[HttpPost]
public IHttpActionResult Contact(string id)
{
}
}
The issue I'm running into is that the following url returns a 404.
https://localhost:44322/api/v1/partner/companies/contact/9da093ef-57a5-4da0-bd0e-5ac97cf304e2
But the following url works fine and calls the find method
https://localhost:44322/api/v1/partner/companies/contact?id=9da093ef-57a5-4da0-bd0e-5ac97cf304e2
I thought it might be my routeconfig file, so I added this to it but still doesn't act as expected.
routes.MapRoute(
name: "Partner",
url: "api/v1/partner/{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Any idea what I need to change to get this working with the id as part of the url rather than a querystring parameter?
In case anyone else runs into this, I solved this by changing the route attribute on the method. So what used to look like [Route("contact")] now is [Route("contact/{id}")].

Troubleshoot to trigger web api action method

I work on my web api project.
I have two get action methods in controller.
Here the controller:
namespace Playground.Web.Controllers.API
{
[RoutePrefix("api/DamageEvent/{actionType}")]
public class DamageEventController : ApiController
{
#region API methods
[HttpGet]
public async Task<IHttpActionResult> GetDamageEvent(int damageEventId = 0)
{
//some logic
}
[HttpGet]
[Route("{ddd:int}")]
public async Task<IHttpActionResult> GetDamageEvent2(int ddd = 0)
{
//some logic
}
#endregion
}
}
Here WebApiConfig defenition:
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}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Formatters.JsonFormatter.SerializerSettings.DateFormatString = "dd/MM/yyyy";
}
}
Here the example of URL in fiddler compose to trigger web api action:
http://localhost/playground/api/DamageEvent/GetDamageEvent2/?ddd=22
I expect that for the URL above the GetDamageEvent2 web api action will be fired. But instead GetDamageEvent action method is fired.
Why GetDamageEvent2 not fired? Any idea what do I am missing?
==============================Update================================
After I red answer from Nkosi
I made some changes to my code, I added to class WebApiConfig new route:
config.Routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
And here the changes in action type:
namespace Playground.Web.Controllers.API
{
[RoutePrefix("api/DamageEvent")]
public class DamageEventController : ApiController
{
#region API methods
[HttpGet]
[Route("GetDamageEvent/{damageEventId}")]
public async Task<IHttpActionResult> GetDamageEvent(int damageEventId = 0)
{
//some logic
}
[HttpGet]
[Route("GetDamageEvent2/{ddd}")]
public async Task<IHttpActionResult> GetDamageEvent2(int ddd = 0)
{
//some logic
}
#endregion
}
}
After I make the changes above the I tryed to fire the both actions and it worked.
But the problem now is when I try to call another actions in another controllers, For example:
http://localhost/playground/api/Contracts/1
I get 404 error.
So I guess the error occures because of the new route template.
So my question how can I fix the error above and to take the new route template into consideration only when the URI try to access to DamageEventController?
You are mixing attribute routing and convention based routing.
Nothing matches your RoutePrefix because there are no actions in the controller that has both a {actionType} and {ddd} templates.
But your stated URL...
api/DamageEvent/GetDamageEvent2/?ddd=22
...matches the DefaultApi convention based route for GetDamageEvent in the route table because it does not have a [RouteAttribute] and it defaults back the convention where...
api/{controller=DamageEvent}/{id=GetDamageEvent2/?ddd=22}
Take a look at Routing in ASP.NET Web API to understand the convention based routing.
and also Attribute Routing in ASP.NET Web API 2
Each entry in the routing table contains a route template. The default
route template for Web API is "api/{controller}/{id}". In this
template, "api" is a literal path segment, and {controller} and {id}
are placeholder variables.
When the Web API framework receives an HTTP request, it tries to match
the URI against one of the route templates in the routing table. If no
route matches, the client receives a 404 error. For example, the
following URIs match the default route:
/api/DamageEvent
/api/DamageEvent/1
/api/DamageEvent/GetDamageEvent2/?ddd=22
Once a matching route is found, Web API selects the controller and the
action:
To find the controller, Web API adds "Controller" to the value of the {controller} variable.
To find the action, Web API looks at the HTTP method, and then looks for an action whose name begins with that HTTP method name. For
example, with a GET request, Web API looks for an action that starts
with "Get...", such as "GetDamageEvent". This
convention applies only to GET, POST, PUT, and DELETE methods. You can
enable other HTTP methods by using attributes on your controller.
We’ll see an example of that later.
Other placeholder variables in the route template, such as {id}, are mapped to action parameters.
To get your stated route to work you need to update your route templates. Either the attribute route or add a new convention route to the route table

Prepend a custom parameter before {controller} in ASP.NET WebApi route

I want to create a route template for Owin WebApi like this:
cfg.Routes.MapHttpRoute(
"API Default", "{myparam}/{controller}/{action}",
new { id = RouteParameter.Optional });
Because I have controllers defined that need a parameter before the controller selection.
I have tried to remove the parameter and set it into RoutePrefixAttribute on controller but it doesn't work.
{controller} must be the first dynamic parameter of the route?
I would use some form of attribute based routing to go to different controllers based on {myparam}.
First controller:
[Route("param1/customer/{id}")]
public IEnumerable<Order> GetOrdersByCustomer(int id) { ... }
Second controller:
[Route("param2/customer/{id}")]
public IEnumerable<Order> GetOrdersByCustomer(int id) { ... }
More information can be found here: Attribute Based WebAPI Routing
Delete RoutePrefix attribute and set the first parameter dynamic in your action Route attribute like the example below:
[HttpGet, Route("{myparam}/books/{bookId:int:min(1)}")]
public HttpResponseMessage Get(string myparam, int bookId)
{
...
}

aspnet webapi method that takes Project/42/Children - how?

I can't figure out how to write the method signature for a REST(ish) AJAX call in Aspnet WebAPI.
My route is recognised but I get a "No HTTP resource was found that matches the request URI..."
I try to do a REST(ish) call like
http://mysite.com/api/Project/42/Children
and my idea is to have the server return all children of project 42.
My route is:
config.Routes.MapHttpRoute(
name: "DefaultApiWithAction",
routeTemplate: "api/{controller}/{id}/Children",
defaults: new { action="Children"}
);
and my method signature is:
public class ProjectController : ApiController {
[HttpGet]
public IEnumerable<Project> Children(int projectID) {
...
Why isn't my method recognised?
I am also not sure I am doing the right "restish" thing here.
Modify your action parameter name from 'proejctID' to 'id'
public IEnumerable Children(int id)

How to do asp.net webapi routing when it comes to custom models?

I am developing an ASP.Net WebApi application and facing some difficulties with routing. I have following code in my WebApi controller.
public class UserRegistrationServiceWebApiController : ApiController
{
[HttpPost]
public void RegisterUser(RegisterUser registerUser)
{
/*Some code here*/
}
[HttpPost]
public void ConfirmUserPassword(UserPasswordConfirmModel userPasswordData)
{
/*Some code here*/
}
}
In my RouteConfig.cs, I have given the routes like this.
routes.MapHttpRoute(
name: "UserRegistrationApi",
routeTemplate: "api/{controller}/{action}/{firstName}/{lastName}/{email}/{phoneNo}/{company}"
);
routes.MapHttpRoute(
name: "UserPasswordConfirmationApi",
routeTemplate: "api/{controller}/{action}/{userId}/{password}"
);
The attributes here (firstName, lastName etc) are getting filled properly from the client-side and I can see them in server-side when I call these two actions separately. But when both actions are in the controller, it says it cannot identify which action to pick. This is obviously because of the custom objects i am filling in the server-side (RegisterUser model and UserPasswordConfirmModel model). So there is a conflict there.
This is because of the routing problem. Appreciate any kind of help.
Thanks in advance.
Actually I found out the problem is with the conflict of two actions in the same controller. If I use these two actions separately they work fine. I do not know how to handle when we have two actions in the same controller like above.
I looked in to custom parameter binding, but I do not think that is the problem since my actions work fine separately.
Thanks.
A short answer, do not have two actions on the same controller. But if you want to, use specific routes (add a constraint). Also, is there a reason to have the password in the url?
routes.MapHttpRoute(
name: "UserRegistrationApi",
routeTemplate: "api/{controller}/{action}/{firstName}/{lastName}/{email}/{phoneNo}/{company}",
constraints = new { action = "RegisterUser" }
);
routes.MapHttpRoute(
name: "UserPasswordConfirmationApi",
routeTemplate: "api/{controller}/{action}/{userId}/{password}",
constraints = new { action = "ConfirmUserPassword" }
);

Resources