ASP.Net MVC 强类型部分视图和继承属性

发布于 2024-12-29 16:13:19 字数 859 浏览 6 评论 0原文

我正在使用 MS MVC 3 构建一个 Web 应用程序,但遇到了一个问题,可能是由于我对模型绑定的理解存在漏洞。

首先,我有一个相当标准的模型(为简洁起见,省略了不相关的内容,更改了名称以保护无辜对象的隐私):

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我期望和需要的产品:(

我缺少什么?可以在不改变模型和视图结构的情况下修复它吗?

I'm building a web-application with MS MVC 3 and have run into an issue, probably due to a hole in my understanding of model-binding.

Firstly, I have a fairly standard model (irrelevant stuff omitted for brevity, names changed to protect the privacy of innocent objects):

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;}
}

For displaying and editing these, I have a View strongly typed to the Order class, containing a Partial View which is strongly typed to the Product class. The top of the partial view looks like this:

@model Product

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

I insert the partial into the main view like this:

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

...and when the view is rendered in the browser, the "Id" hidden input contains the Id of the Order, not the Id of the Product that I expect and need :(

What am I missing? Can it be fixed without changing the structure of the model and views?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

樱花细雨 2025-01-05 16:13:19

在更改我的测试项目时,我可以确认

/Home/Index?id=33

/Home/Index/33

确实会覆盖模型值。你能从 url 中删除这个参数吗?

On changing my test project I can confirm that

/Home/Index?id=33

or

/Home/Index/33

DOES overwrite the model value. Can you remove this parameter from the url?

肤浅与狂妄 2025-01-05 16:13:19

你必须改变结构。

您可以将部分内容放入主视图中,或者将部分内容强式键入订单而不是产品,或者使用 Html.Hidden() 构造隐藏字段。 MVC 不会将相对于后期操作中的模型的 HiddenFor 中项目的完整路径放入其中。

IE。在 html 中,您会看到

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

但您确实想要

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

区分字段和项目。


当您尝试发布两个具有相同名称的不同隐藏输入时,上述问题仍然存在,但是我还编写了一个可以在客户端运行的测试项目。

希望这有帮助:

控制器

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>

You'd have to change the structure.

You could either put the partial content into the main view, or strongly type the partial to the Order not the Product, or construct the hidden field using Html.Hidden(). MVC is not putting the whole path to the item in the HiddenFor relative to the model in your post action.

ie. In the html you would see

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

but you really want

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

in order to distinguish the fields and items.


The above problem still remains when you attempt to POST two different hidden inputs with the same name, however I also wrote a test project that works as far as the client.

Hope this helps:

Controller

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

Models

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; }
    }

View

@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>

Partial View

@model MvcApplication1.Models.Product

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

Client 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>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文