ASP.NET MVC POST Parameters in the url - asp.net-mvc

url : /jobs/UpdateJobResults/GUIDHERE
When I do a post to the below function the guid id is always blank, can I use the above format to POST the GUID in the url (as the form body has the results dictionary) ?
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UpdateJobResults(Guid Id, Dictionary<string, object> results)
{
}

You can try revising your Html.BeginForm by passing this as a route value...
Html.BeginForm("myAction", "myController", new { Id = myGuid });
Obviously where myGuid is your param.
If your routing is setup correctly, MVC will know to post your form with this value in the URL (and/or querystring) rather than in the Request.Form data...
Good luck!

I believe that MVC uses Convert.ChangeType for conversions. This method does not support Guids. My recommendation would be to change the parameter to a string and convert it in the method.

Yes, the 3rd parameter of the default route is id. In most of the examples that is an integer, but a Guid should work.
Did you try it with the id parameter as a string instead of a Guid? Normally MVC is smart enough to give you the type of object you're looking for, but I haven't tried it with a Guid. Expecting id to be a string might work. Then at least you'd know your routing was working.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UpdateJobResults(string id, Dictionary<string, object> results)
{
}
Are you using the default route or have you set up your own routes?
Edit: So, you're using your own routes. Please edit your question to include those. Also, you say it works for the GET, but not for the POST. What does your action look like that is hit with the GET request? I think we're going to need more information in order to help with this one. Are you sure the client requests contain the Guid in the url?

ended up being the model binder created was looking in the form for the guid on the post rather than the query string

Related

Attribute Routing with RoutingParameter

I currently have a set of action methods in a web api controller that use Attribute Routing.
[RoutePrefix("Paper")]...
[Route("Shape/Octagon/{id:minlength(1)}]
public IEnumerable<sampleShape> PostactionName(string id){..}
[Route("Shape/Hexagon/{id:minlength(1)}]]
public IEnumerable<sampleShape> PostactionName(string id){..}
which would work for the following URIs
api/Paper/Shape/Octagon/"1,2,3"
api/Paper/Shape/Hexagon/"3,2,1"
but becomes unusable once the id parameter becomes to long. Is there anyway to have routing use the parameter id as a form data rather than part of the URI but still keep the Route attribute.
You can use FromBody attribute to let the engine know that parameter will come from post body
[RoutePrefix("Paper")]...
[Route("Shape/Octagon"}]
public IEnumerable<sampleShape> PostactionName([FromBody]string id){..}
[Route("Shape/Hexagon"}]]
public IEnumerable<sampleShape> PostactionName([FromBody]string id){..}

ASP.NET MVC catch URL parameter in Controller

I've defined such a controller ViewProfile.
I want to use it for the next syntax to access public user info in my project.
/ViewProfile/Sammy
/ViewProfile/Billy
etc...
But I don't know how to handle the 2-nd parameter in URL.
I've tried to use:
[HttpGet]
public ActionResult Index(string query)
{
...
return View();
}
But in the debugger, string query is always empty.
I have read about routines mapping, but really don't understand how would it help me with the determination of id or other parameters.
I read in ASP.NET MVC Book that to get the parameter directly in the controller action just name it as ID.
ASP.NET MVC lets you easily do this without having to confi gure
anything extra. ASP .NET MVC’s default routing convention is to treat
the segment of a URL after the action method name as a parameter named
ID. If your action method has a parameter named ID, then ASP.NET MVC
will automatically pass the URL segment to you as a parameter.
I just tried a sample app and it worked fine for me. The string i entered in the URL did get passed on to the ID parameter in the action.
Also what i noticed is that you should provide your URL as viewprofile/index/1 or
viewprofile/index/somestring.
YOu seem to be skipping the action part.

Should a PUT identifier come from the URL or from the HTTP request data?

This question is probably a dupe, but I couldn't find a similar one (not sure exactly what to search for).
Say I have a restful resource URL like this:
/my/items/6/edit
There is a form at this page which allows me to edit my #6 item. When I submit the form, it POSTS to /my/items/6, with a PUT X-HTTP-Method-Override header.
My question is, where should the server handler get the value "6" from? Should it get it from the URL? Or from the HTTP POST data (say the id was rendered as a hidden input field on the form)?
It seems to me like it should come from the URL. However this makes it a little more trouble to get it out. For example in .NET MVC, you might get it like this from a controller action method:
var id = int.Parse(ControllerContext.RouteData.Values["id"].ToString());
...which seems like more trouble than it's worth. However, if we get it out of the HTTP POST data, then technically you could post/put data for my item #6 to /my/items/7, and the server would still save the item data under id #6.
Are there any standard practices here?
Check this: http://www.codeproject.com/Articles/190267/Controllers-and-Routers-in-ASP-NET-MVC-3
I'm not a .net developer, though best practice in all platforms is to map your URI template to controller. Router must parse and prepare such information and pass it to your function/method.
It should definitely come from the URL. In ASP.NET MVC, if you had a route defined like this:
routes.MapRoute(
"Default",
"/my/{controller}/{id}/{action}",
new { controller = "items", action = "Index" }
);
You would be able to reference the ID from the ActionResult method signature, like this:
[HttpPut]
public ActionResult Index(int id, MyItemEditModel model)
{
// id would be 6 if the URL was /my/items/6/
// and the model need not contain the id
...

RedirectToAction not passing all parameters

I have these two methods in the same Controller, the first passing two parameters to the second.
When debugging, the list (model.RequestedProducts) passed is correct (not empty) but on the second method, only idOR is read correctly, List<OCS> RequestedProducts is empty.
[HttpPost]
public ActionResult Index(int idOR, ViewModel model, string add, string remove, string send)
{
//...
return RedirectToAction("Done",
new { idOR = idOR,
RequestedProducts = model.RequestedProducts});
}
public ActionResult Done(int IdOR, List<OCS> RequestedProducts)
{ ...
What am I missing?
Is there maybe a better way to do it? (other than Redirect to Action)
Thank you
When you use RedirectToAction you are returning a message to the client to request a new URL probably something like /controller/action/id. You Routes will define how the URL is formed. I am guessing you have the default route defined and in your case MVC has no way of knowing how to deserialise your RequestedProducts type into a URL and then bind it back into a List type.
Instead you could use the TempData object to pass data between to Action requests.
The TempData property value is stored in session state. Any action method that is called after the TempDataDictionary value is set can get values from the object and then process or display them. The value of TempData persists until it is read or until the session times out.
This MSDN article explains it all.

ASP.NET MVC Login ReturnUrl always NULL?

Using Forms Authentication in ASP.NET MVC when trying to log back into a site, it puts a ReturnUrl parameter in the query string. My Logon action method accepts a "returnUrl" string. However it seems that returnUrl string is always null, even when it is clearly in the query string. Any thoughts on why this might be the case or a possible fix?
This tends to happen when you're using one generic logon form, but you're explicitly specifying the Controller and ActionMethod (which is causing a form post, but losing the querystring)
Just to clarify, this is what your code should look like in your BeginForm:
Html.BeginForm("LogOn", "Account", new { ReturnUrl = Request.QueryString["ReturnUrl"] })
EDIT: This is by design as RickAnd mentions in comments below. However it doesn't allow for the UI pattern of being deep in a site, clicking on LogOn, then returning to the page you were previously on, if it allows anonymous users. It's a commonly requested pattern. David Allen's approach to LogOff would also work nicely for a clean redirect at LogOn.
Maybe you don't include the ReturnURL parameter into you login form's action attribute, thus posting to a URL without that parameter?
Basically, The Asp.net MVC has some hidden features. For Example when you pass variable 'id' to controller action, it interprets 'id' as default identifier and puts it on browser query with fore slash.By using another name instead of 'id' we will see '?' rather than fore slash. Because of setting the 'id' name on RegisterRoutes method on global.asax file.
In this Problem you have created a custom data passer to controller by using this code:
using(Html.BeginForm("LogOn", "Account", FormMethod.Post))
{
//form fields
}
So Asp.net MVC ignores other useful data to pass to controller action, and we'll see returnUrl always null.
While, by using this, Asp.net MVC acts Correctly and returnUrl is mounted:
using(Html.BeginForm())
{
//form fields in LogOn View
}
By the way, When we use custom data passer to controller action, must pass another data manually like this:
using(Html.BeginForm("LogOn", "Account", new {ReturnUrl = Request.QueryString["ReturnUrl"] }))
{
//form fields
}
There are two ways I can think of to deal with logon and logoff scenarios.
Dave Beer outlined one way, above.
There is another approach that works in many situations. I used it when I coded the NerdDinner tutorial. The tutorial provides us with a logoff function that logs you off and takes you home. I did not want that. I wanted to return to the page I was on before I logged off. So I modified my Account controller logoff action to look like this
public ActionResult LogOff()
{
FormsService.SignOut();
return Redirect(Request.UrlReferrer.ToString());
}
You can get fancier and pass in a returnUrl and test for it, in case you want to override this behavior. But I don't need that. This achieves the desired result. The Logon can work similarly. Maybe there are ways to use the MVC framework to do this for me, but until I learn them, this is VERY simple and works reliably.
Try the following:
public static MvcForm BeginForm(this HtmlHelper htmlHelper, string id)
{
string formAction = htmlHelper.ViewContext.HttpContext.Request.RawUrl;
TagBuilder tagBuilder = new TagBuilder("form");
tagBuilder.MergeAttribute("id", id);
tagBuilder.MergeAttribute("action", formAction);
tagBuilder.MergeAttribute("method", HtmlHelper.GetFormMethodString(FormMethod.Post), true);
HttpResponseBase httpResponse = htmlHelper.ViewContext.HttpContext.Response;
httpResponse.Write(tagBuilder.ToString(TagRenderMode.StartTag));
return new MvcForm(htmlHelper.ViewContext.HttpContext.Response);
}
First ensure you have set the login url in the web.config, Next, ensure your Signin Form does not contain anything like action, for example:
View:
If you specify action you will always get null for return url:
Controller:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SignIn(string userName, string password, bool? rememberMe, string returnUrl)
{
}

Resources