Binding the Model variable to an Action Method in ASP.NET MVC3
Solution 1
I usually add the following to my model:
public class MyViewModel
{
public string Name { get; set; }
public string Surname { get; set; }
public bool IsPeriod { get; set; }
public RouteValueDictionary RouteValues
{
get
{
var rvd = new RouteValueDictionary();
rvd["name"] = Name;
rvd["surname"] = Surname;
rvd["isPeriod"] = IsPeriod;
return rvd;
}
}
}
Then you can simply use the RouteValues property in your Url.Action() call.
<img src="@Url.Action("DisplayData", "Home", Model.RouteValues)" alt="Image" />
Or if your prefer less (explicit) code, ignore the model changes and simply do this:
<img src="@Url.Action("DisplayData", "Home", new RouteValueDictionary(Model)" alt="Image" />
Solution 2
It will not serialize your entire object to the query string you must set each value explicitly, i.e.
new { nameFilter = @Model.Name, @Model.Surname, @Model.IsPeriod }
You only need provide nameFilter if your parameter is not called Name in your routing.
Solution 3
You are trying to create an img src link using an entire view model, I don't think this is really what you want.
Instead, you would pass the Id of whatever the model represents as a query string parameter on the link (filters). So for example using...
<img src="@Url.Action("DisplayData", "Home", new { filters = Model.Id })" alt="Image" />
To render something like...
<img src="/Home/DisplayData?filters=1" alt="Image" />
Then you can use the Id in your action to look up whatever the resource is you are trying to display.
Solution 4
If you want to pass model the way you described then you must override ToString() method of your ViewModel class, because this is the reason why passing your ViewModel object to Url.Action method returns such a link. Also, if you want to pass your ViewModel to Action, you must prepare link in the form of "http://url/Action?Name=x&Surname=y&IsPerion=0" so ModelBinder can recognize it and bind to Action parameter.
Solution 5
Did you try this,
<img src="@Url.Action("DisplayData", "Home", Model)" alt="Image" />
CiccioMiami
Updated on June 04, 2022Comments
-
CiccioMiami almost 2 years
I have a controller
HomeController
with the followingaction method
:[HttpPost] public ActionResult DisplayData(MyViewModel myViewModel) { // Do something with myViewModel }
The
ViewModel
:public class MyViewModel { public string Name { get; set; } public string Surname { get; set; } public bool IsPeriod { get; set; } }
And the following
View
@model AppName.ViewModels.MyViewModel @{ Html.RenderPartial("MyPartialView", Model); } <img src="@Url.Action("DisplayData", "Home", new { myViewModel = Model })" alt="Image" />
I use the Url.Action how it is described here but what I get in the DisplayData action method is null. In the source code I got:
<img src="/Home/DisplayData?filters=AppName.ViewModels.MyViewModel" alt="Image" />
so it is passing actually the type instead of the values.
The
ViewModel
instead is correctly passed to the partial view. What am I doing wrong? -
CiccioMiami over 11 yearsThanks! It is not my case. I do not need to retrieve some values from the database, but I need the parameters specified in MyViewModel to compute a set of values, create a graph with those values and send it to the View as an image
-
Justin Harvey over 11 yearsAah, I see. The thing is, Url.Action is not designed to take a model as a parameter. You could instead manually add each model field as a route parameter which if named correctly should bind to your model before the action executes.
-
CiccioMiami over 11 yearsAccording to your example if I have let's say 15 variables that I need to pass to the action method I have to list them explicitly?
-
CiccioMiami over 11 yearsThansk! Can you make a concrete example please?
-
CiccioMiami over 11 yearsHence the best solution is to create a custom model binder, isn't it?
-
Justin Harvey over 11 yearsNo, I don't really see how that would help. The issue is in the construction of your URL, regardless of whether you custom bind or not. You could, on the other hand, create a custom Url.Action extension, that iterates all of a model's properties and writes them out in the query string.
-
dove over 11 yearsyes. but you might think about doing a post in that case as that's more than a regular GET which is meant to be idempotent. In a post you can post the entire model regularly. If you're fixed on a GET then do the ToString() as @krajew4 suggests
-
dove over 11 yearsnote that a GET is meant to get an entity and not to perform a search, that would more be a POST, unless they are filters that consistently bring back the same results.
-
CiccioMiami over 11 yearsGreat! That's exactly what I was looking for! I can just +1 but you deserve a +100 my friend!
-
anastaciu almost 3 yearsI was thinking of using this, but it appears that the passed model does not take into account changes made in properties in that view, thoughts?