ASP.NET MVC Routing with Model Parameter - asp.net-mvc

I have an action method in a controller that I'm calling via Ajax. The specification is:
[HttpPost]
public ActionResult SomeFunction(FormCollection form)
This works fine without any special routing configuration.
However, if I try to use a model as the parameter instead of the FormCollection, thus:
[HttpPost]
public ActionResult SomeFunction(SomeModel model)
I get a 500 error because the function can't be found.
What do I need to put in the RouteConfig to get this to work?

I would recommend using Help plugin: http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/creating-api-help-pages
When using POST I would specify signature as such:
#region POST
[Route("")]
public IHttpActionResult Post([FromBody]Contact newContact)

Related

How to pass object as parameter in Web Api

I want to pass object as parameter in my web api GET and POST method. My code is,
[HttpGet]
[Route("mytest/list/{model}")]
public IHttpActionResult GetAllTypes(TestModel model)
{
//my logic here
}
When I call this, console get an error its not found. I tried this,
[HttpGet]
[Route("mytest/list/{model?}")]
public IHttpActionResult GetAllTypes(TestModel model)
{
//my logic here
}
But, the parameter object gets null value.
Don't pass an object via GET.
POST an object and use [HttpPost] attribute.
If you're really want to do it via GET , you can use this :
[HttpGet]
public IHttpActionResult GetAllTypes([FromUri] TestModel model)

Route attribute hides actions

Why Route attribute hides|applied to other methods?
[HttpGet]
[Route("Issues/ReportIssue")]
public ActionResult ReportIssue()
Action without Route attribute stops working
[HttpPost]
public ActionResult ReportIssue(IssueModel viewModel)
jQuery returns "Not found" error
If rename Post action or add Route attribute, all works. Is there are any priority rules for a Route attribute?
I tried following code sample -
[HttpGet]
[Route("Products/Create")]
public ActionResult Create()
{
ProductCategory category = new ProductCategory();
category.ProductCategoryId = 1;
return View(category);
}
[HttpPost]
public ActionResult Create(ProductCategory category)
{
return View(category);
}
And I could see this working properly without any issues. The controller name in my case is "Product", and the below code works if I specify route attribute as "Products/Create" (different from controller name), or "Product/Create". So not sure, why you would be facing the issue.
The Get and Post actions should work without route attribute as well, as they were working. Attribute routing is something newly added in MVC 5, and is there to give more control over the routes. But still, this is not mandatory to use. The traditional routes should work fine.
Take a look of - http://blogs.msdn.com/b/webdev/archive/2013/10/17/attribute-routing-in-asp-net-mvc-5.aspx article.

Why mvc attribute routing on HttpGet action also effect HttpPost without a routing attribute, is it a bug?

I have two actions, one for HttpGet with this signature:
[Route("NewsLetter/SelectEmail/{page?}")]
[HttpGet]
public ActionResult SelectEmail(int? page, string priCat, string secCat)
{
...
}
And one for HttpPost with this signature:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SelectEmail(int id)
{
...
}
After setting the aforementioned route for HttpGet method, I've noticed that the other method with HttpPost has stopped working, after digging around I've realized that the route for HttpGet also set itself for HttpPost, and it didn't work until I explicitly set a routing attribute for it:
[Route("NewsLetter/SelectEmail/{id}")]
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SelectEmail(int id)
{
...
}
I wanted to know, is it a bug?, if it's not, is there anyway to set a routing attribute for a [HttpGet] without also effecting the corresponding [HttpPost]?
You can't using POST and GET at the same time, because your Action will accept requests with any HTTP methods.
Try use AcceptVerbsAttribute to restrict HTTP methods in your RouteTable.
https://msdn.microsoft.com/en-us/library/system.web.mvc.acceptverbsattribute(v=vs.118).aspx

Overloaded Action Method not found at Runtime from test

I have two action methods :
public ActionResult Edit(int id)
{
}
public ActionResult Edit(Modelname model, string[] strParam)
{
}
And I am calling the Edit(Modelname,string[]) from the unit test.
var actionResult = controller.Edit(model, strParam);
The code compiles at runtime , but when i debug the test method it gives me a method not found "MissingMethodException" . I tried commenting the Edit(int id) method and then debugging, still the same thing. Other tests are running fine, any help appreciated.
You have an ambiguous match for action methods in your controller. While it will compile just fine, ASP.NET MVC can't decide which method to use at runtime and it throws an exception. You need to make sure they respond to different type of HTTP requests or rename one of them.
I can't be sure with the info you provided but if the second method is processing a POST request, using HttpPost filter will solve the problem:
public ActionResult Edit(int id)
{
}
[HttpPost]
public ActionResult Edit(Modelname model, string[] strParam)
{
}
If that's not the case, renaming is the other solution. If you have a good reason not to do that, ASP.NET MVC provides ActionName filter to override the method name for ASP.NET MVC pipeline:
public ActionResult Edit(int id)
{
}
[ActionName("EditModel")]
public ActionResult Edit(Modelname model, string[] strParam)
{
}
This will make http://example.org/controller/EditModel hit the second method.

Test a Nullable Guid

I'm using ASP.NET MVC + C# and I have two controller action as follows:
public ActionResult Edit(Guid? id)
{
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(SomeModel model)
{
}
Now, in the browser I can navigate to the [GET] /controller/edit with no id and get an null argument exception (as expected), but what I'd like to know is how do I replicate this scenario in a unit test?
I have a GET and a POST version of the edit method so I can't feed controller.Edit(null) to test it as the code won't compile.
Thanks in advance!
One option would be to use the ActionName attribute to keep the URL the same, but have different method names.
[HttpGet]
[ActionName("Edit")]
public ActionResult GetEditForm(Guid? id)
{
...
}
[HttpPost]
[ActionName("Edit")]
public ActionResult SaveEditForm(SomeModel model)
{
...
}
Then you could of course call the right method from your unit test, and the routing bits of ASP.NET take care of getting the right method called.

Resources