MVC Post 提交遇到的奇怪大难题!!!

大悟飞天 2011-10-29 11:37:06

[HttpGet]
public ActionResult Index()
{
Employee emp=new Employee
{
Name="老员工"
};
return View(emp);
}
[HttpPost]
public ActionResult Index(Employee emp)
{
emp.Name = "新员工";
return View(emp);
}


上面的代码,当我运行第一个Index方法:

1.在页面上点击submit按钮,提交到下面这个Index方法后
2.获取到一个自定义的Employee类型参数emp,我在方法中修改emp的Name属性
3.然后在页面上用@Html.EditorFor(e=>e.Name)输出
4.照理,这里应该输出Name的值是"新员工",但是,实际上,我在页面上得到却还是Name="老员工"!!
5.我把输出方法改成@Model.Name,输出的就是"新员工"!!

请教各位大大,这是为什么,是什么原理?
...全文
378 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
大悟飞天 2011-10-31
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 sandy945 的回复:]
既然有探索精神为什么不看看上下文,这篇文章的环境是ASP.NET MVC Beta版.

你的环境是否和文中一致。

你的问题和文中想讲述的不是一个问题,但是那篇文中的评论到是简要的说了流程,那才和你的问题有关联。

“不好讲究竟是设计上的原因还是一些其它方面的失误”

作者写这句话 是想表明 这个问题他没确定。
[/Quote]
分给你吧,虽然还没有非常明确的答案,但大概知道为什么了!感谢大大的关注!!
大悟飞天 2011-10-30
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 keepfool 的回复:]
引用 1 楼 dinglang_2009 的回复:

@Html.EditorFor(e=>e.Name)输出 和 @Model.Name不一样
说明前者输出的可能是缓存过的旧数据。

这个和缓存一点儿关系都没有。
[/Quote]
经过多种测试,确实和缓存没关系,感觉可能跟Post上来的数据FormCollection有关系,好像Html.EditorFor(x=>x.Name)会先在FormCollection中查找是否包含键Name,有就把键Name的值输出来,而不是去找Model中的Name。。不过具体我还不敢确定,请大大们帮帮忙!!这算不算mvc3的BUG?
keepfool 2011-10-30
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 dinglang_2009 的回复:]

@Html.EditorFor(e=>e.Name)输出 和 @Model.Name不一样
说明前者输出的可能是缓存过的旧数据。
[/Quote]
这个和缓存一点儿关系都没有。
keepfool 2011-10-30
  • 打赏
  • 举报
回复
MVC,视图部分我就不说了,视图用于输出你的name,但这个实际的Model部分你根本就没有更改。
你Post到Index(Employee emp)....然后在这里你的代码只相当于修改了一个局部变量而已,你这个emp对象并没有关联到数据库。
请确保你的数据库中对应的Employee对象也已经更改。
阿非 2011-10-30
  • 打赏
  • 举报
回复
不是BUG,是因为两个操作的不是同一实例。

使用 ModelState.SetModelValue


ModelState.SetModelValue("Name", new ValueProviderResult("新员工", "新员工", null));
阿非 2011-10-30
  • 打赏
  • 举报
回复
既然有探索精神为什么不看看上下文,这篇文章的环境是ASP.NET MVC Beta版.

你的环境是否和文中一致。

你的问题和文中想讲述的不是一个问题,但是那篇文中的评论到是简要的说了流程,那才和你的问题有关联。

“不好讲究竟是设计上的原因还是一些其它方面的失误”

作者写这句话 是想表明 这个问题他没确定。

chen_ya_ping 2011-10-30
  • 打赏
  • 举报
回复
要不贴出你的Html代码看看
MSDNXGH 2011-10-30
  • 打赏
  • 举报
回复

[HttpPost]
public ActionResult Index(Employee emp)
{
emp=new Employee();
emp.Name = "新员工";
return View(emp);
}

大悟飞天 2011-10-30
  • 打赏
  • 举报
回复
终于找到真正的答案了,为了不让更多程序猿们走弯路,贴出来大家看吧:

在Post方式下慎用HtmlHelper

其实这部分才是真正让我想写此文的原因。不好讲究竟是设计上的原因还是一些其它方面的失误,总之这个HtmlHelper并非完全可以取代直接在页面上写下HTML的这种做法。就在离我们最近的这个示例中:

<%--<%=Html.Hidden("models.Index", current.ToString()) %>--%>
<input type ="hidden" name="models.index" value = "<%= current.ToString() %>"/>
我们可以用上面绿色的这行代码替换正常的这行代码,并同样执行以上的示例。在第一次执行的时候,一切都很正常,同样包括了在第一次PostBack中。但是第二次就出现了囧样了。

我们所期待的HTML:

<input id="models[200].Id" name="models[200].Id" type="hidden" value="200" />

变成了:

<input id="models[200].Id" name="models[200].Id" type="hidden" value="200,201,202,203,204" />

这必然导致严重的错误。经过分析我发现,因为第一次回发的时候value正常,因此不会出错,而随后由于HtmlHerper.Hidden方法在执行的时候,如果ModelState中有值,就将这些值转换为逗号分隔的字符作为我们的目标值,而上文中通过current.ToString()所传入的value直接被忽略了。也就是这点原因导致了这里的value并未生效,因此就出现了严重的偏差,而带给开发者的就是诸多的莫名其妙。

其实不仅是Html.Hidden方法,HtmlHelper中的很多方法准确地讲就是除了CheckBox以外的调用了InputHelper的方法都有问题,而所有的Helper方法都调用了这个InputHelper,因此就不约而同地出现了这些错误。

if (isCheckBox) {
// Helpers that take isChecked as parameter should never look at ViewData
if (useViewData) {
isChecked = htmlHelper.EvalBoolean(name);
}
tagBuilder.MergeAttribute("value", Convert.ToString(value, CultureInfo.CurrentUICulture));
}
else {
tagBuilder.MergeAttribute("value", attemptedValue ?? ((useViewData) ? htmlHelper.EvalString(name) : Convert.ToString(value, CultureInfo.CurrentUICulture)));
}
以上这行代码的加粗部分就是导致这个问题的核心。

准确得讲,这个问题并非任何时候都发生,它只有在满足

1、回发,也就是数据有机会叠加的情况;

2、重复name,也就是从Form[name]能取出一个集合而不是单一元素的时候发生。

只有这二者同时兼备才会发生如上的不可预测的错误。

现在看来这显然是个不小的Issue,因为既然框架被设计为支持集合,而且这种设计基于多个重名元素,那么这种错误必将发生。但是这个方法在InputExtensions中,准确地讲这是框架提供者为我们写的一个比较好的范例而已,我们有必要自行扩充这样的方法。当然一般情况并没有这个必要,因为我们完全可以通过直接写入HTML的方式来避免这种叠加现象,这里只希望大家都能够有所注意。

丁码农 2011-10-29
  • 打赏
  • 举报
回复
@Html.EditorFor(e=>e.Name)输出 和 @Model.Name不一样
说明前者输出的可能是缓存过的旧数据。

62,073

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧