MVC4 HTML TextBoxFor工作不修改后视图模型 [英] MVC4 HTML TextBoxFor Not Working After Modifying ViewModel

查看:121
本文介绍了MVC4 HTML TextBoxFor工作不修改后视图模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有我真的不明白的问题。我有其中有一个列表作为公共成员一个非常简单的模型。每当我的控制器从回发的模型删除了一个元素似乎是TextBoxFor()HTML佣工不拿起变化。这些助手似乎缓存的东西,但我不能把我的手指上。

一个演示/摄制可以在这里找到: http://broken.azurewebsites.net

摄制


  1. 导航到 http://broken.azurewebsites.net

  2. 注意4列值填充基于零值

  3. 点击测试按钮,回来后,我删除列表中的第一项的页

  4. 的通知真正的价值观是正确的,0元已被删除,但这里的问题是通过TextBoxFor呈现的值()。我想不通为什么它是呈现0时仍然该元素不再存在。


模式

 公共类ItemViewModel
{
    公共字符串描述{搞定;组; }
    公共小数? {金额获得;组; }
}公共类TestViewModel
{
    公共TestViewModel()
    {
        项目=新的List< ItemViewModel>();
    }    公开名单< ItemViewModel>项目{搞定;组; }
}

控制器

 公共类HomeController的:控制器
{
    公众的ActionResult指数()
    {
        VAR模型=新TestViewModel();        为(变量I = 0; I&下; 4;我+ +)
        {
            model.Items.Add(新ItemViewModel {说明= i.ToString(),金额= I});
        }        返回查看(模型);
    }    [HttpPost]
    公众的ActionResult指数(TestViewModel模型)
    {
        model.Items.RemoveAt(0);        返回查看(模型);
    }}

查看

  @model Demo.Models.TestViewModel
@using(Html.BeginForm())
{
    <表>
        <&THEAD GT;
            <tr><td>Description</td><td>Amount</td><td>Real-Description</td><td>Real-Amount</td></tr>
        &LT; / THEAD&GT;
        &LT;&TBODY GT;
            @for(VAR I = 0; I&LT; Model.Items.Count;我++)
            {
                VAR II = I;
                &所述; TR&GT;
                    &所述; TD&GT; @ Html.TextBoxFor(M =&GT; m.Items [Ⅱ]。说明)下; / TD&GT;
                    &所述; TD&GT; @ Html.TextBoxFor(M =&GT; m.Items [Ⅱ] .Amount)所述; / TD&GT;
                    &LT; TD&GT; @ Model.Items [II]。说明&LT; / TD&GT;
                    &所述; TD&GT; @ Model.Items [Ⅱ] .Amount&下; / TD&GT;
                &LT; / TR&GT;
            }
        &LT; / TBODY&GT;
    &LT; /表&gt;
    &LT;按钮和GT;测试与LT; /按钮&GT;
}


解决方案

如下更改后的索引方法所需的行为:

  [HttpPost]
    公众的ActionResult指数(TestViewModel模型)
    {
       ModelState.Clear();       model.Items.RemoveAt(0);       返回查看(模型);
    }

下面的原因:

该TextBoxFor结合在ModelState中的发表值而不是模型值。因此,在您的应用程序,当你按下测试按钮,文本框绑定到他们已经和模型值改变即使没有更新上回发的值。对于恩,如果在第一行的文本框都显示0,他们甚至会后回来后仍然绑定到该值与基础模型是有值1。这种行为背后的原因是验证。如果你期待在文本框和用户输入SomeTextValue一个int,模型绑定将无法绑定到int属性,这将是在验证错误的状态。这样,你会希望用户看到上面写着的SomeTextValue不是整数的错误。请输入一个整数的,因为你所期望的用户输入的值在那里。

里克施特拉尔完美解释了它在这个博客帖子

<一个href=\"http://www.west-wind.com/weblog/posts/2012/Apr/20/ASPNET-MVC-Postbacks-and-HtmlHelper-Controls-ignoring-Model-Changes\">http://www.west-wind.com/weblog/posts/2012/Apr/20/ASPNET-MVC-Postbacks-and-HtmlHelper-Controls-ignoring-Model-Changes

和以下品牌威尔逊:

http://forums.asp.net/post/3688022.aspx

I have an issue which I really just don't understand. I have a very simple model which has a List as a public member. Whenever my controller removes an element from the model on postback the TextBoxFor() HTML helpers do not seem to pick up the changes. These helpers appear to be caching something but I cannot put my finger on it.

A Demo/Repro can be found here: http://broken.azurewebsites.net

Repro

  1. Navigate to http://broken.azurewebsites.net
  2. Notice the 4 column values populated with zero based values
  3. Hit the "test" button to POST back the page where I remove the first item in the list
  4. Notice The "real" values are correct and the 0 element has been removed, however the problem here is with the values rendered via TextBoxFor(). I cannot figure out why it is rendering 0 still when that element no longer exists.


Models

public class ItemViewModel
{
    public string Description { get; set; }
    public decimal? Amount { get; set; }
}

public class TestViewModel
{
    public TestViewModel()
    {
        Items = new List<ItemViewModel>();
    }

    public List<ItemViewModel> Items { get; set; }
}

Controller

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var model = new TestViewModel();

        for (var i = 0; i < 4; i++)
        {
            model.Items.Add(new ItemViewModel { Description = i.ToString(), Amount = i });
        }

        return View(model);
    }

    [HttpPost]
    public ActionResult Index(TestViewModel model)
    {
        model.Items.RemoveAt(0);

        return View(model);
    }

}

View

@model Demo.Models.TestViewModel
@using (Html.BeginForm())
{
    <table>
        <thead>
            <tr><td>Description</td><td>Amount</td><td>Real-Description</td><td>Real-Amount</td></tr>
        </thead>
        <tbody>
            @for (var i = 0; i < Model.Items.Count; i++)
            {
                var ii = i;
                <tr>
                    <td>@Html.TextBoxFor(m => m.Items[ii].Description)</td>
                    <td>@Html.TextBoxFor(m => m.Items[ii].Amount)</td>
                    <td>@Model.Items[ii].Description</td>
                    <td>@Model.Items[ii].Amount</td>
                </tr>
            } 
        </tbody>
    </table>
    <button>Test</button>
}

解决方案

Change your post index method as below for the desired behavior:

    [HttpPost]
    public ActionResult Index(TestViewModel model)
    {
       ModelState.Clear();     

       model.Items.RemoveAt(0);

       return View(model);
    }

Here's why:

The TextBoxFor binds to the post value in the ModelState instead of model value. So in your application, when you hit Test button, the text boxes are bound to the value they already have and don't get updated on postback even after the model values are changed . For ex, If the text boxes in first row are showing 0 and they will remain bound to that value even after post back and the underlying model is having value 1. The reason behind this behavior is validation. If you are expecting an int in the text box and user inputs "SomeTextValue",the model binder won't be able to bind to the int property and it will be in a state of validation error. You then would want the user to see an error that says "SomeTextValue" is not an integer. Please enter an integer because you'd expect the user entered value to be there.

Rick Strahl explains it perfectly in this blog post

http://www.west-wind.com/weblog/posts/2012/Apr/20/ASPNET-MVC-Postbacks-and-HtmlHelper-Controls-ignoring-Model-Changes

And Brand Wilson below:

http://forums.asp.net/post/3688022.aspx

这篇关于MVC4 HTML TextBoxFor工作不修改后视图模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆