ASP.Net MVC строго типизирует частичные представления и унаследованные свойства - PullRequest
3 голосов
/ 30 января 2012

Я создаю веб-приложение с MS MVC 3 и столкнулся с проблемой, возможно, из-за дыры в моем понимании привязки модели.

Во-первых, у меня достаточно стандартная модель (для краткости опущены несущественные элементы, имена изменены для защиты конфиденциальности невинных объектов):

public class ModelBase
{
    public int Id { get; set; }
}

 public class Order : ModelBase
{
    public List<Product> Products { get; set; }
}

public class Product : ModelBase
{
    public int OrderId { get; set;}
}

Для отображения и редактирования этих данных у меня естьПредставление строго типизировано в класс Order, содержащее частичное представление, строго типизированное в класс Product.Верхняя часть частичного вида выглядит следующим образом:

@model Product

@Html.ValidationSummary(true)
@Html.HiddenFor(model => model.Id)
@Html.HiddenFor(model => model.OrderId)
//loads of actual editable properties

Я вставляю частичное в основной вид следующим образом:

@Html.Partial("EditorTemplates/Product", Model.Products.First())

... и когда представление отображается вВ браузере скрытый ввод «Id» содержит Id заказа, а не Id продукта, который я ожидаю и нуждаюсь: (

Чего мне не хватает? Может ли это быть исправлено без изменения структуры модели?а взгляды?

Ответы [ 2 ]

3 голосов
/ 31 января 2012

При изменении моего тестового проекта я могу подтвердить, что

/ Home / Index? Id = 33

или

/ Home / Index / 33

НЕ перезаписывает значение модели.Вы можете удалить этот параметр из URL?

1 голос
/ 30 января 2012

Вы должны были бы изменить структуру.

Вы можете либо поместить частичное содержимое в главное представление, либо строго ввести частичное в Заказ, а не в Продукт, либо создать скрытое поле с помощью Html.Hidden ().MVC не помещает полный путь к элементу в HiddenFor относительно модели в вашем посте.

т.е.В html вы увидите

<input type="hidden" name="Id" />

, но вы действительно хотите

<input type="hidden" name="Products[0].Id" />

, чтобы различать поля и элементы.остается, когда вы пытаетесь POST два разных скрытых ввода с тем же именем, однако я также написал тестовый проект, который работает до клиента.

Надеюсь, это поможет:

Контроллер

public ActionResult Index()
        {
            Order order = new Order() { Id = 1 };
            order.Products = new List<Product>() { new Product() { Id = 3, OrderId = 1 } };
            return View("Order",order);
        }

Модели

public class Order : IdentityBase
    {
        public List<Product> Products { get; set; }
    }

    public class Product : IdentityBase
    {
        public int OrderId { get; set; }
    }

 public class IdentityBase
    {
        public int Id { get; set; }
    }

Вид

@model MvcApplication1.Models.Order

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <title>Order</title>
</head>
<body>
    <div>
        @Html.HiddenFor(model => model.Id)
        @foreach (MvcApplication1.Models.Product product in Model.Products)
        {
            <div class="product">
                @Html.Partial("Product", product)
            </div>
        }
    </div>
</body>
</html>

Частичный вид

@model MvcApplication1.Models.Product

@Html.ValidationSummary(true)
@Html.HiddenFor(model => model.Id)
@Html.HiddenFor(model => model.OrderId)

HTML-код клиента

<!DOCTYPE html> 
<html>
<head>    
    <title>Order</title>    
</head>    
<body>    
    <div>    
       <input id="Id" name="Id" type="hidden" value="1" />    
       <div class="product"> 
                <input id="Id" name="Id" type="hidden" value="3" />    
                <input id="OrderId" name="OrderId" type="hidden" value="1" />    
       </div>
    </div>
</body>

...