Action method was not found on controller - c#

Despite a ton of questions similar to this one, none seem relevant, so
I have an action with this signature
[HttpPost]
public ActionResult SaveOrder(PizzaOrder pizza, Guid? id){
...
}
I am trying to submit a form with a button. I have verified that the button sends a POST to
https://my/controller/url/SaveOrder?id=...
It also appears that the PizzaOrder data is being posted correctly.
But, my action never gets hit. Instead, MVC throws an exception
A public action method 'SaveOrder' was not found on controller
'Controllers.PizzaController'.
Why?

POST does not send form data in the URL querystring.

There can only be one cause and that's exactly what its saying. The url is wrong. To test this, use the browser developer tools and check to see what the url the page is posting to and what the actual url is. Controller vs PizzaController? or.... you are doing a GET to a POST. POST doesn't have SaveOrder?id=.

The request you are trying is GET not POST as you are passing parameters with Querystring ?id=... Try after removing [HttpPost] attribute

Related

#Url.Action("Action","Controller") calls both post and get method with same name

I have a controller where there are two action methods with same name with HttpPost and HttpGet as shown below , when link with #Url.Action("DoSomething","Controller") is called then both the method are invoked , how do I call only GET method?
Is there anyway to pass type GET or POST in #URL.Action or any other way?
[HttpGet]
public ActionResult DoSomething(int ? MyParam)
{
}
[HttpPost]
public ActionResult DoSomething(MyModel Model)
{
}
In Razor View When I build a link like
JustDoIt
Then it calls both POST and GET methods, even after specifiying parameter as int and not the model
Try adding post in the form declaration:
#using (Html.BeginForm("DoSomething","Controller", FormMethod.Post))
{
}
or using HTML:
<form action="#Url.Action("DoSomething","Controller")" method="POST">
...
</form>
The HTTP verb POST/GET will route your request to the appropriate action. The default is GET.
I think that you maybe getting Url.Action() confused with Html.Action() (apologies if I'm wrong). As someone mentioned in the comments, Url.Action() will just render a URL based on the parameters which is intended for say building anchor tags. Html.Action() on the other hand will invoke an action when building the page for the response at server side which I'm guessing is what your referring too.
If that's the case, then you will need to specify the Action's parameters for DoSomething() by specifying the route values like so:
#Html.Action("DoSomething", "Home", new {MyParam = 2} )
The result of DoSomething(int MyParam) would be injected into the page. Html.Action is not intended to call a POST so it's not possible to use this on an Action which has been decorated with the POST verb.
Issue was I was having one more ajax request to check if the page has been loaded completely to show progress bar, when removed that portion of the code from layout, It has been working fine without calling any action method twice.

Receive error "The requested resource does not support http method 'GET'" when update

I am building an API. But I receive the following error.
The requested resource does not support http method 'GET'
My request is a HTTP PUT and I'm trying to update my database. I have searched for many days but I can't find an answer. Below is my request code. Please help me. Thanks in advance.
request
Code in Controller
[HttpPut]
public void CGNATObjUpdate(int ID)
{
Library.Instances.Value.CGNATObjUpdate(ID);
}
You need to send PUT request aswell. [HttpPut] Allows your method to be triggered for PutRequests only, but in your example you just put link into browser and this simple GET request. Try to use something like Postman to send correct request.
Another way is to check that your controller alows to trigger action by name, for this you need to configure routing for your controller. Just set
[Route("api/[controller]/[action]")]
public class CGNATUpdateApiController : Controller
{
}
Now you can call Action by name, otherwise you will not be able to call Controller action by it`s name, and you need to call Controller:
/api/CGNATUpdateApi?ID=3
just with correct method (PUT) and it will call first PUT method in controller.

MVC 4 edit route parameter in controller

I'm having a little problem i hope someone can help me with.
on ASP.net MVC 4 (C#) i need to be able to edit the parameters of my route from my controller.
example the request url is
MyController/MyAction/param1/param2
now from MyAction I need to edit the returned url so that it displays
MyController/MyAction/Modifiedparam1/Modifiedparam2
The purpose of this is to translate the parameters that i retrieve from my database from language changes.
Please use redirect result for this (in MyAction on some condition):
return RedirectToAction("MyAction", { param1Name = Modifiedparam1, param2Name = Modifiedparam2 };
Basically you cannot modify url in controller. Urls is something send by the browser to invoke some action. You may just say browser to redirect user to another url.
Don't fight with framework. It will fight back sooner or later. Instead follow mvc principles, redirect from controller action or filters/interceptors to do so.

MVC Form Submit - Redirecting to an action that is not accessible from the browser directly

I am learning MVC 3 after hours right now and last night I ran into an issue that seems like it would be very simple to solve but I can't seem to locate a solution for it.
I have a simple contact form. The end user fills out the form and submits it. When they submit the form I redirect the end user to a different action in the same controller which renders an "inquiry submitted" page/view which is basically a "Thank you page".
The controller is setup like so.
public ActionResult ContactUs()
{
return View();
}
[HttpPost]
public ActionResult ContactUs(ContactInfo contactInfo)
{
if (!ModelState.IsValid)
{
return View();
}
//perform some business logic
return RedirectToAction("InquirySubmitted",contactInfo);
}
public ActionResult InquirySubmitted(ContactInfo contactInfo)
{
return View(contactInfo);
}
The problem:
I do not want end users navigating directly to the InquirySubmitted action via the browser.
I only want the ContactUs action in the controller to be able to send users to the InquirySubmitted View.
I have attempted to make the InquirySubmitted action private so that only the controller can call it like so:
private ActionResult InquirySubmitted(ContactInfo contactInfo)
But this produces an error which I fully understand because I am forcing the browser to request InquirySubmitted by using RedirectToAction().
So my question is simply: What is the best "MVC 3 style" solution to this issue.
You will need to put logic in your InquirySubmitted ActionResult in order to prevent users from viewing the page if they are not supposed to.
You are already passing the InquirySubmitted method your model (ContactInfo). Could you simply inspect the data passed to the method and if it is absent then redirect the user to an error page (or some other page of your choice)?
An alternate solution would be to set a boolean in session that indicates that the user completed the "ContactUs" form. Then you could check for that session object within InquirySubmitted.
First, I would have to say.. Who cares if someone can navigate directly to the Inquiry submitted page? Is there any confidential information, or something sensitive there? If not, so what? What does it hurt?
However, if you're determined to do so. The answer to your question of "How to make an action not accessible directly from the browser" is that You can simply use Html.Action() to render the page, and then decorate the action method with a [ChildActionOnly] attribute.
This doesn't actually solve the problem though, since making the action indirectly accessible only answers your question, not solves your problem. Ultimately, you need to redirect the user to a url to load the page, so you will need some logic that determines if they can view the page or not. This is
Not sure if this still applies in MVC3, but in MVC2 it worked.
your global.asax file has your url structuring in it. You can add your InquirySubmitted to the list of urls that isn't accessible there.

ASP.NET MVC: What is the correct way to redirect to pages/actions in MVC?

I am fairly new to MVC but not sure exactly which Redirect... replaces the standard redirect used in WebForms is the standard Response.Redirect()
For instance, I need to redirect to other pages in a couple of scenarios:
WHen the user logs out (Forms signout in Action) I want to redirect to a login page.
In a Controller or base Controller event e.g. Initialize, I want to redirect to another page (AbsoluteRootUrl + Controller + Action)
It seems that multiple redirects get called in some cases which causes errors, something to do with the fact a page is already being redirected? How can cancel the current request and just redirect?
Update:
The answer to this question (System.Web.Mvc.Controller Initialize) indicates that Initialize should not be used and OnActionExecuting should be used?
Any comments on why Initialize should not be used or why OnAuthorization is not a better option?
More Info:
This blog post (http://blog.wekeroad.com/blog/aspnet-mvc-securing-your-controller-actions/) indicates that OnActionExecuting is useful for authentication (as indicated in the link above) I guess adding this to that event in the base Controller class is fine as every page runs an Action in MVC so shouldn't make much difference and having the ability to redirect should be easier. This does make sense, but it also seems to make sense to me that things could be done in an event before this event and makes we question what those events are for? Will be giving OnActionExecuting a go..
1) When the user logs out (Forms signout in Action) I want to redirect to a login page.
public ActionResult Logout() {
//log out the user
return RedirectToAction("Login");
}
2) In a Controller or base Controller event eg Initialze, I want to redirect to another page (AbsoluteRootUrl + Controller + Action)
Why would you want to redirect from a controller init?
the routing engine automatically handles requests that come in, if you mean you want to redirect from the index action on a controller simply do:
public ActionResult Index() {
return RedirectToAction("whateverAction", "whateverController");
}
1) To redirect to the login page / from the login page, don't use the Redirect() methods. Use FormsAuthentication.RedirectToLoginPage() and FormsAuthentication.RedirectFromLoginPage() !
2) You should just use RedirectToAction("action", "controller") in regular scenarios..
You want to redirect in side the Initialize method? Why? I don't see why would you ever want to do this, and in most cases you should review your approach imo.. If you want to do this for authentication this is DEFINITELY the wrong way (with very little chances foe an exception)
Use the [Authorize] attribute on your controller or method instead :)
UPD:
if you have some security checks in the Initialise method, and the user doesn't have access to this method, you can do a couple of things:
a)
Response.StatusCode = 403;
Response.End();
This will send the user back to the login page.
If you want to send him to a custom location, you can do something like this (cautios: pseudocode)
Response.Redirect(Url.Action("action", "controller"));
No need to specify the full url. This should be enough.
If you completely insist on the full url:
Response.Redirect(new Uri(Request.Url, Url.Action("action", "controller")).ToString());
RedirectToAction("actionName", "controllerName");
It has other overloads as well, please check up!
Also, If you are new and you are not using T4MVC, then I would recommend you to use it!
It gives you intellisence for actions,Controllers,views etc (no more magic strings)

Categories