Binding the Model variable to an Action Method in ASP.NET MVC3

19,209

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" />
Share:
19,209
CiccioMiami
Author by

CiccioMiami

Updated on June 04, 2022

Comments

  • CiccioMiami
    CiccioMiami almost 2 years

    I have a controller HomeController with the following action 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
    CiccioMiami over 11 years
    Thanks! 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
    Justin Harvey over 11 years
    Aah, 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
    CiccioMiami over 11 years
    According 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
    CiccioMiami over 11 years
    Thansk! Can you make a concrete example please?
  • CiccioMiami
    CiccioMiami over 11 years
    Hence the best solution is to create a custom model binder, isn't it?
  • Justin Harvey
    Justin Harvey over 11 years
    No, 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
    dove over 11 years
    yes. 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
    dove over 11 years
    note 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
    CiccioMiami over 11 years
    Great! That's exactly what I was looking for! I can just +1 but you deserve a +100 my friend!
  • anastaciu
    anastaciu almost 3 years
    I 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?