ASP.NET MVC ModelBinder bug:绑定请求变量“id”模型的属性“Id”

发布于 2024-10-23 14:36:50 字数 941 浏览 1 评论 0原文

我正在使用 MVC 3 Final RTM。

给定

这条路线:

context.MapRoute(
    "Blog_Posts",
    "Blog/Posts/{id}/{slug}",
    new { controller = "Posts", action = "Index", slug = UrlParameter.Optional }
);

在帖子页面上,例如/blog/posts/2/some-slug,我将部分视图与Comment模型绑定:

@Html.Partial("_CommentEditor", new Comment())

Comment 有一个 public int Id {get;设置;}

在部分视图中,我有这个:

@Html.HiddenFor(comment => comment.Id)

为什么它显示这个?

<input type="hidden" value="2" name="Id" id="Id" data-val-required="The Id field is required." data-val-number="The field Id must be a number." data-val="true">

以及为什么当我将 Comment 上的 Id 更改为 CommentId 它的值是否正确为 0

我认为默认模型绑定器绑定到路由的 {id}

I am using MVC 3 final RTM.

Given

This route:

context.MapRoute(
    "Blog_Posts",
    "Blog/Posts/{id}/{slug}",
    new { controller = "Posts", action = "Index", slug = UrlParameter.Optional }
);

And on a post's page, e.g. /blog/posts/2/some-slug I bind a partial view with a Comment model:

@Html.Partial("_CommentEditor", new Comment())

And Comment has a public int Id {get; set;}.

And in the partial view, I have this:

@Html.HiddenFor(comment => comment.Id)

Why does it display this?

<input type="hidden" value="2" name="Id" id="Id" data-val-required="The Id field is required." data-val-number="The field Id must be a number." data-val="true">

And why when I change Id on Comment to CommentId does it correctly have a value of 0?

Me thinks the default model binder is binding to the {id} of the route.

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

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

发布评论

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

评论(4

笑红尘 2024-10-30 14:36:50

发生这种情况是因为当您使用 HiddenFor 等 HTML 帮助程序时,它们首先查看路由数据和模型状态,然后再查看模型。因此,他们在您的路线数据中找到参数 id=2 并在您传递的模型中使用该值而不是 id=0。

That's happens because when you are using HTML helpers such as HiddenFor they first look at route data and model state and after that in the model. So they find in your route data a parameter id=2 and use this value instead of the id=0 in the model you are passing.

桃扇骨 2024-10-30 14:36:50

这是一个错误,也可能不是,因为下面的实现逻辑;

在Asp.NET MVC中,视图引擎使用ViewData(它是变量,类型是“ViewDataDictionary”)。这个ViewData有2个属性“ModelState”保存路由值,“Model”保存我们的实际模型对象。

  1. 视图引擎查看“ModelState”对象以检索属性值。
  2. 如果在步骤 1 中找到则返回值。
  3. 否则查看“模型”对象以检索属性的值。

在上面的情况下,路由具有属性“id”,其值保存在“ModelState”中,因此它从“ModelState”而不是绑定模型返回值。

对于上述场景,任何输入控件都会呈现意外的值。

分辨率是:

<div class="postData" value='@Model.Id'/>

//use below jquery function to retrieve data
var postedData = $('.postData');

It is a bug or it might not because of below implemented logic;

In Asp.NET MVC, a View engine uses ViewData (it is variable and its type is "ViewDataDictionary"). And this ViewData has 2 properties "ModelState" that holds routing values, and "Model" that holds our actual model object.

  1. A View engine looks into "ModelState" object retrieving value of a property.
  2. If found in step 1 then return value.
  3. Else looks into "Model" object to retrieve value for a property.

In above case, route has property "id" and its value are saved in "ModelState" so it return value from "ModelState" instead of binded model.

For above scenario, any input control renders with unexpected value.

Resolution is:

<div class="postData" value='@Model.Id'/>

//use below jquery function to retrieve data
var postedData = $('.postData');
茶花眉 2024-10-30 14:36:50

如果您使用 linq to sql,则无法手动设置标记为由数据库提供的字段。

If you're using linq to sql, fields marked as provided by database cannot be set manually.

攒眉千度 2024-10-30 14:36:50

尝试:

Try @Html.Partial("_CommentEditor", new Comment{Id = 0}) 

Try:

Try @Html.Partial("_CommentEditor", new Comment{Id = 0}) 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文