I'm sending 2 different models to the same action, for eg. I'm either sending the ContactEdit or GeneralEdit model to the same action. The action will need to determine which model is sent. Is there a way to do this? I have no problem passing a query param to tell which model was passed, but is there a way to do something like:
[HttpPost]
public ActionResult SingleUser(Part part)
{
if(part == Part.General)
GeneralEditModel model = Model as GeneralEditModel;
else
ContactEditModel model = Model as ContactEditModel;
//....
}
You can name your elements and use a bind prefix. I believe if your method takes two parameters as two object types, the one will just be null if it's not found. See
MVC - Model binding with multiple entities on the same page
Related
I have such action:
[ObjectRequired]
public ActionResult Campaign(int? id, SomeClass object = null)
{
...
}
What i need is to route to this action:
a) with only int parameter (.../Campaign/12345)
b) with no parametes (optionally) (.../Campaign)
MVC error says, that there is no nonparametric constructor (if delete "object" parameter - it's ok). But i cant delete "object" parameter, because i need to check some values and pass value from [ObjectRequired] attribute like this:
filterContext.ActionParameters["object"] = _someObject;
I don't want to use constructions like ViewData. Where's the right way?
I'm not 100% on what I'm about to say but I'll say it as if I am...
You can't pass an object through to a get. You could pass back parameters and use a custom route handler to build the object for you.
You could also hold the object in data and use Entity Framework to get the model.
You could also use TempData, but that's similar to ViewData.
You could also hold it in their Session.
I have an action where the request is being generated from a kendo ui grid's Create event. The information is all being posted correctly, and the model binder works properly expect in any case where the action parameter name is 'model'
If the action is defined like this:
[HttpPost]
public ActionResult Create(ModelType post)
{
}
Everything works properly.
If instead though, the action looks like this:
[HttpPost]
public ActionResult Create(ModelType model) //changed parameter Name to model
{
}
I get an invalid model state and this message:
System.Web.Mvc.ModelError
The parameter conversion from type 'System.String' to type
'MyApp.Common.Models.ModelType' failed because no type converter can convert between
these types."
This only seems to affect actions coming from the Kendo UI grid, normal MVC action posts work regardless of the name of the action parameter.
I was able to create a new project with a small test model and recreate this behavior as well.
Can anyone shine some light on what is going on here?
Most probably the current "ModelType" contains property with name "Model" and the Default MVC ModelBinder tries to bind the "Model" property to the model variable. You should change the variable name from the action parameters to one that is not contained in the current model.
I'm curious how this works. In MVC you can call View() and pass a model as a parameter, but RedirectToAction (one of its incarnations at least) takes a 'routeValues' object, which appears to be the closest match.
If your model is passed in this parameter will that model type be available in the subsequent action method? Or are there caveats involved that might prevent accurate translation in some circumstances?
If you need to pass in some-what complex objects to an action after a redirect, you probably want to use either a Session or TempData:
From "What is ASP.NET MVC TempData"
ASP.NET MVC TempData dictionary is used to share data between
controller actions. The value of TempData persists until it is read or
until the current user’s session times out
By default TempData uses a Session to persist the information, however, as with much of MVC, this is an extensibility point, where you can plug in a Cookie-based provider if you prefer.
You cannot pass a model object in there but you can pass individual properties that will map to a model in the action that you redirect to.
That works by building up the url to redirect to using the properties, and the model binder in the receiving action.
Redirect... methods cause client-side-and-back trip, so - no, the model will not be available.
I think this is what you want :
Save your model in a Tempdata
RequestModel rq = new RequestModel()
....assign something to your model..
TempData["request"] = rq;
return Redirect("RequestAcknowledgement");
Now create an Action Result for the view you are redirecting to and pass your TempData back to a model. Then return the model to a view.
public ActionResult RequestAcknowledgement()
{
RequestsModel request = (RequestsModel)TempData["request"];
return View(request);
}
What should I do, when I need one ViewModel class to be passed to the asp-page (containing various data to display) and another Model class I need to be submitted (through the form tag) back to the server?
Nest the "Other View Model" inside the main View Model. Then bind the controls of the form to the sub-model's properties.
Action Method Signature:
[HttpPost]
public ActionResult Foo(SubModel model) { /* ... */ }
You can use a Custom Model Binder to bind the Input Model based on the form generated by output model.
Check this link for more information:
http://buildstarted.com/2010/09/12/custom-model-binders-in-mvc-3-with-imodelbinder/
ASP.NET MVC 3 Model Binding Resources
If the properties of the two view models are more or less same then the default model binder will take care else you have to go for a custom model binder.
The other options if you have to create the html fields with the names of the ViewModel properties that you are going to bind on post.
public ActionResult RenderMyThing(IList<String> strings)
{
return View("RenderMyView");
}
How do I pass in strings?
routes.MapRoute("MyRoute", "RenderMyThing.aspx", new { controller = "My", action = "RenderMyThing" });
Is there a way I could pass in strings here?
Secondly, how does ASP.NET MVC know that action is my action, and controller is my controller. Like I saw this in samples, and it does work, but isn't it just an anonymous object with no type?
This is the provenance of model binding: the framework needs to have some instruction as to how to turn a "request", which comes out of the routing context, query string, forms collection, etc., into the parameters that your action method wants.
The DefaultModelBinder will generate a list if it sees that you have multiple key-value pairs with the same key (and appropriately typed/convertible values) - for the details, Phil wrote a good post about this:
If you need fancier binding requirements, you can implement a custom model binder and explicitly define how route values and the other bits get translated into objects (or collections of objects).