Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
169 views
in Technique[技术] by (71.8m points)

c# - Saving multiple objects from MVC view

I'm writing my first MVC3 application which is a simple order tracking application. I would like to edit the order and the details at the same time. When I edit the order the ActionResult for the Edit returns the order and the associated line (i'm using EF as well).

public ActionResult Edit(int id)
    {            
        // Get the order with the order lines
        var orderWithLines = from o in db.Orders.Include("OrderLines")
                                where o.ID == id
                                select o;

        // Not sure if this is the best way to do this.
        // Need to find a way to cast to "Order" type
        List<Order> orderList = orderWithLines.ToList();
        Order order = orderList[0];

        // Use ViewData rather than passing in the object in the View() method.
        ViewData.Model = order;
        return View();            
    }

The order and the lines display with no issue but when I save the page I do not get any of the lines passed back to the controller. Only the order. Here is the View code.

    @model OrderTracker.Models.Order

@{
    ViewBag.Title = "Edit";
}

<h2>Edit</h2>

@using (Html.BeginForm())
{
    <fieldset>
        <legend>Order</legend>   

        @Html.HiddenFor(model => model.ID)
        @Html.HiddenFor(model => model.UserId)

        <div>
            @Html.LabelFor(model => model.OrderDate)
        </div>
        <div>
            @Html.EditorFor(model => model.OrderDate)
        </div>
        <div>
            @Html.LabelFor(model => model.Description)
        </div>
        <div>
            @Html.EditorFor(model => model.Description)
        </div>                   

        <table>
            <tr>
                <th>
                    Description
                </th>
                <th>
                    Quantity
                </th>
                <th>
                    Weight
                </th>
                <th>
                    Price
                </th>
                <th></th>
            </tr>
        @foreach (var line in Model.OrderLines)
        { 
            <tr>
                <td>
                    @Html.EditorFor(modelItem => line.Description)
                </td> 
                <td>
                    @Html.EditorFor(modelItem => line.Quantity)
                </td> 
                <td>
                    @Html.EditorFor(modelItem => line.Weight)
                </td> 
                <td>
                    @Html.EditorFor(modelItem => line.Price)
                </td>
            </tr>
        }
        </table>


        <p>
            <input type="submit" value="Save" />
        </p> 

    </fieldset>    
}

Can I please get some guidance on the best way to save the line data as well as the order data.

Thanks.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The issue that you are facing is related to the names generated by the ICollection<T> controls. Here is a detailed discussion by Phil Haack and a solution by him (in terms of an @Html extension method; download the sample project from the link given at the end of his blog post). This post targets MVC/MVC2; however it is still applicable with MVC3.

Alternatively if you don't want to follow the hack, you can opt for a EditorTemplate for your OrderLine entity model.

Here are the steps.

1) Create Editor template under (Views ->Shared -> EditorTemplates -> OrderLine.cshtml) It is important to create a folder named EditorTemplates under Shared, and the template name should be same as the EntityModel for which you want to create the templete; hence the name OrderLine.cshtml)

enter image description here

2) Code for OrderLine.cshtml

@model OrderTracker.Models.OrderLine
@{
    Layout = null;
}

<!DOCTYPE html>
@Html.HiddenFor(modelItem => Model.id)
<tr>
<td>
    @Html.EditorFor(modelItem => Model.Description)
</td> 
<td>
    @Html.EditorFor(modelItem => Model.Quantity)
</td> 
<td>
    @Html.EditorFor(modelItem => Model.Weight)
</td> 
<td>
    @Html.EditorFor(modelItem => Model.Price)
</td>
</tr>

3) Edit your View with this code (note that I've used EditorFor for OrderLines collection)

@model OrderTracker.Models.Order

@{
    ViewBag.Title = "Edit";
}

<h2>Edit</h2>

@using (Html.BeginForm())
{
    <fieldset>
        <legend>Order</legend>   

        @Html.HiddenFor(model => model.ID)
        @Html.HiddenFor(model => model.UserId)

        <div>
            @Html.LabelFor(model => model.OrderDate)
        </div>
        <div>
            @Html.EditorFor(model => model.OrderDate)
        </div>
        <div>
            @Html.LabelFor(model => model.Description)
        </div>
        <div>
            @Html.EditorFor(model => model.Description)
        </div>                     
        <div>
        <table>
            <tr>
                <th>
                    Description
                </th>
                <th>
                    Quantity
                </th>
                <th>
                    Weight
                </th>
                <th>
                    Price
                </th>
            </tr>
            @Html.EditorFor(model => model.OrderLines)
            </table>
        </div>
        <p>
            <input type="submit" value="Save" />
        </p> 

    </fieldset>    
}

4) Now on post back you will see the values

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...