Search code examples
c#controllerasp.net-mvc-5asp.net-routing

Posting objects containing other models


I've been searching for a way to post all the information of a model which contains other models and I believe I can just send the object to my view and go off of the 50 examples I've looked at and can render everything just fine.

Here's my model I'm talking about named Equipment.

public int id { get; set; }
public String name { get; set; }
public ManufacturerItem manufacturerItem { get; set; }
public EquipmentType equipmentType { get; set; }
public SupportItem supportItem{ get; set; }
public Placement placement{ get; set; }
public Boolean status { get; set; }
public DateTime endOfLife{ get; set; }
public String notes{ get; set; }
public Purchase purchase{ get; set; }
public Boolean mes{ get; set; }
public DateTime reviewedDate{ get; set; }

Based on the tons of examples I've read I know I can render these like this:

@Html.EditorFor(model => model.name)
@Html.EditorFor(model => model.manufacturerItem.model.name)

In other research I did stumble upon building forms for deep View Model graphs in ASP.NET MVC which I may consider in using, but that was posted back in MVC 2 days. I'm using MVC 5. So I don't know how relative that is today.

So let's say I have another model named Book with {id, Title, Author} and you could edit the book name and author. Now in this model, on edit, my controller could be as such:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include="ID,Title,Author)"] Book book)
{  ... -insert code- ...}

Going off of this idea, what would be my controller method signature be for the Equipment model? Do I include the other objects as their own types?

I'm not using EF or linq-to-sql because I have to use stored procedures. So I want to get all this information neatly packaged and passed off to the repository that will take care of parameter assignment and calling of the stored procedure.


Solution

  • Going off of this idea, what would be my controller method signature be for the Equipment model?

    Have you tried using the following signature:

    [HttpPost]
    public ActionResult Edit(Equipment model)
    {
        ...
    }
    

    By the way if your view doesn't contain a form allowing to edit all the properties of the Equipment model object graph you may consider using a view model containing only the properties that are included as input fields in your form. Then on the server you will get the corresponding Equipment instance from your backend using the id, update only the properties that were sent from the HTML form and save the results back.

    For example:

    [HttpPost]
    public ActionResult Edit(EquipmentViewModel model)
    {
        Equipment equipement = backend.GetById(model.Id);
        // set the properties that are coming from the UI:
        equipment.name = model.Name;
        equipment.supportItem = model.SupportItem;
        ...
    
        // save the updated entity back
        backend.Update(equipment);
    }
    

    In this example the EquipmentViewModel will contain only the properties that you have corresponding input fields in your view and which the user is supposed to edit and not the entire domain model object graph.