为什么不复杂类型的列表绑定到文本框在一个表中显示更改模型在MVC 4? [英] Why won't a List of complex types bound to TextBoxes in a table show changes to the model in MVC 4?

查看:156
本文介绍了为什么不复杂类型的列表绑定到文本框在一个表中显示更改模型在MVC 4?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了似乎pretty简单的一个问题,但我一直没能找到解决的办法。我创建了一个ReportModel对象,它是在视图模型。该ReportModel包含FinancialHistory对象的列表。我填充对象,并使用默认绑定视图的形式内文本框的表显示它们(这工作正常)。然后,用户可以提交表单从不同的数据源刷新FinancialHistory对象,更换什么pviously $ P $与新的结果列表。当新的返回结果,我可以看到,该模型包含预期的新价值,但是当HTML渲染,原来的金额仍然会出现。如果新的结果包含了比原来更多的清单对象(如例所示code)所示,添加的行确实出现了正确的价值观。所以,如果原来有2个目的和刷新列表具有3,将所得的HTML表示第一2行使用旧值与第3行的新的值。

下面是模式:

 公共类ReportModel
{
    公共字符串账户号码{搞定;组; }
    公众的IList< FinancialHistory> FinancialHistories {搞定;组; }
} 公共类FinancialHistory
{
    公共FinancialHistory()
    {
        ID = Guid.Empty;
    }    公众的Guid标识{搞定;组; }
    公众的DateTime TransactionDate {搞定;组; }
    公共小数总金额{搞定;组; }
}

在家庭/索引视图,我用HTML.TextBoxFor()到列表中的每个FianancialHistory对象的属性绑定到一个文本框的表。下面是Index视图:

  @model SimpleExample.Models.ReportModel<表ID =FormSave方法=后NAME =FormSave行动=/首页/刷新>@ Html.LabelFor(型号=> model.AccountNumber)@ Html.TextBoxFor(型号=> model.AccountNumber)<表类=表的风格=宽度:95%>
    &所述; TR>
        < TD>日期和LT; / TD>
        < TD>度< / TD>
    < / TR>    @ {
        如果(Model.FinancialHistories!= NULL)
        {
            对于(INT指数= 0;&指数LT = Model.FinancialHistories.Count - 1;指数++)
            {
            &所述; TR>
                < TD> @ Html.TextBoxFor(型号=> model.FinancialHistories [指数] .TransactionDate,{0:MM / DD / YYYY},新{@ReadOnly =真})< / TD>
                < TD> @ Html.TextBoxFor(型号=> model.FinancialHistories [指数] .TotalAmount,{0:#,#00},新{@ReadOnly =真})< / TD>
                < TD> @ Html.HiddenFor(型号=> model.FinancialHistories [指数] .ID)LT; / TD>
            < / TR>
            }
        }
     }< /表>
<输入类型=提交ID =提交值=刷新级=提交/>
< /表及GT;

有关该例子中,在控制器我的动作方法是很简单的。最初,索引方法填充与2 FinancialHistory对象名单。刷新方法取代了原来的2个对象3个新的对象,不同的金额。

 公共类HomeController的:控制器
{
    公众的ActionResult指数()
    {
        ReportModel reportModel =新ReportModel();        reportModel.AccountNumber =123456789;        IList的< FinancialHistory> financialHistories =新的List< FinancialHistory>();
        financialHistories.Add(新FinancialHistory
                                    {
                                        ID = Guid.NewGuid(),
                                        TransactionDate = DateTime.Parse(3/1/2010),
                                        总金额= 1000.00M
                                    });        financialHistories.Add(新FinancialHistory
                                    {
                                        ID = Guid.NewGuid(),
                                        TransactionDate = DateTime.Parse(4/1/2011),
                                        总金额= 2000.00M
                                    });        reportModel.FinancialHistories = financialHistories;        返回查看(reportModel);
    }    公众的ActionResult刷新(ReportModel reportModel)
    {
        FinancialHistoryRepository financialHistoryRepository =新FinancialHistoryRepository();        IList的< FinancialHistory> financialHistories =新的List< FinancialHistory>();
        financialHistories.Add(新FinancialHistory
                                    {
                                        ID = Guid.Empty,
                                        TransactionDate = DateTime.Parse(3/1/2010),
                                        总金额= 1111.11M
                                    });
        financialHistories.Add(新FinancialHistory
                                    {
                                        ID = Guid.Empty,
                                        TransactionDate = DateTime.Parse(4/1/2011),
                                        总金额= 2222.22M
                                    });
        financialHistories.Add(新FinancialHistory
                                    {
                                        ID = Guid.Empty,
                                        TransactionDate = DateTime.Parse(2012年5月1日),
                                        总金额= 3333.33M
                                    });        reportModel.FinancialHistories = financialHistories;        返回视图(指数,reportModel);
    }
}


解决方案

这是HTML佣工的工作原理,是由设计。当渲染它们首先寻找在ModelState中有关值,之后在模型中。您正在修改中的POST控制器动作模型的值,但该值ModelState中仍然含有将用于旧值。如果要修改一个POST操作,如果你打算重新显示了同样的观点,你应该删除该ModelState中的原始值模型的值:

 公众的ActionResult刷新(ReportModel reportModel)
{
    //清除原贴值,使他们没有得到回升
    //由帮手
    ModelState.Clear();    FinancialHistoryRepository financialHistoryRepository =新FinancialHistoryRepository();
    ...
    返回视图(指数,reportModel);
}

I have run into an issue that seems pretty simple, but I have not been able to find a solution. I have created a ReportModel object that is the model in the view. The ReportModel contains a list of FinancialHistory objects. I populate the objects and display them in a table of textboxes within a form in the view using default binding (This works correctly). The user can then submit the form to refresh the FinancialHistory objects from a different datasource, replacing what was previously in the list with the new results. When the new results are returned, I can see that the model contains the expected new values, but when the HTML is rendered, the original amounts still appear. If the new results contains more objects than the original list (as shown in the example code), the added rows do appear with the correct values. So, if the original had 2 objects and the refreshed list has 3, the resulting HTML shows the first 2 rows with the old values and a 3rd row with the new values.

Here are the models:

public class ReportModel
{
    public string AccountNumber { get; set; }
    public IList<FinancialHistory> FinancialHistories { get; set; } 
}

 public class FinancialHistory
{
    public FinancialHistory()
    {
        Id = Guid.Empty;
    }

    public Guid Id { get; set; }
    public DateTime TransactionDate { get; set; }
    public decimal TotalAmount { get; set; }
}

In the Home/Index view, I use HTML.TextBoxFor() to bind the properties of each FianancialHistory object in the list to textboxes in a table. Here is the Index view:

@model SimpleExample.Models.ReportModel

<form id="FormSave" method="post" name="FormSave" action="/Home/Refresh">

@Html.LabelFor(model => model.AccountNumber) @Html.TextBoxFor(model => model.AccountNumber)

<table class="table" style="width: 95%">
    <tr>
        <td >Date</td>
        <td >Amount</td>
    </tr>

    @{
        if (Model.FinancialHistories != null)
        {                   
            for (int index = 0; index <= Model.FinancialHistories.Count - 1; index++)
            {              
            <tr>
                <td>@Html.TextBoxFor(model => model.FinancialHistories  [index].TransactionDate, "{0:MM/dd/yyyy}", new { @readonly = "true" })</td>
                <td>@Html.TextBoxFor(model => model.FinancialHistories[index].TotalAmount, "{0:#,#.00}", new { @readonly = "true" })</td>
                <td>@Html.HiddenFor(model => model.FinancialHistories[index].Id)</td>
            </tr>
            }
        }
     }

</table>
<input type="submit" id="submit" value="Refresh" class="submit" />
</form>

For this example, my action methods in the controller are very simple. Initially, the Index method populates the list with 2 FinancialHistory Objects. The Refresh method replaces the original 2 objects with 3 new objects, with different amounts.

public class HomeController : Controller
{
    public ActionResult Index()
    {
        ReportModel reportModel = new ReportModel();

        reportModel.AccountNumber = "123456789";

        IList<FinancialHistory> financialHistories = new List<FinancialHistory>();
        financialHistories.Add(new FinancialHistory
                                    {
                                        Id = Guid.NewGuid(),
                                        TransactionDate = DateTime.Parse("3/1/2010"),
                                        TotalAmount = 1000.00M
                                    });

        financialHistories.Add(new FinancialHistory
                                    {
                                        Id = Guid.NewGuid(),
                                        TransactionDate = DateTime.Parse("4/1/2011"),
                                        TotalAmount = 2000.00M
                                    });

        reportModel.FinancialHistories = financialHistories;

        return View(reportModel);
    }

    public ActionResult Refresh(ReportModel reportModel)
    {
        FinancialHistoryRepository financialHistoryRepository = new FinancialHistoryRepository();

        IList<FinancialHistory> financialHistories = new List<FinancialHistory>();
        financialHistories.Add(new FinancialHistory
                                    {
                                        Id = Guid.Empty,
                                        TransactionDate = DateTime.Parse("3/1/2010"),
                                        TotalAmount = 1111.11M
                                    });
        financialHistories.Add(new FinancialHistory
                                    {
                                        Id = Guid.Empty,
                                        TransactionDate = DateTime.Parse("4/1/2011"),
                                        TotalAmount = 2222.22M
                                    });
        financialHistories.Add(new FinancialHistory
                                    {
                                        Id = Guid.Empty,
                                        TransactionDate = DateTime.Parse("5/1/2012"),
                                        TotalAmount = 3333.33M
                                    });

        reportModel.FinancialHistories = financialHistories;

        return View("Index",reportModel);
    }
}

解决方案

That's how HTML helpers work and is by design. When rendering they are first looking in the ModelState for values and after that in the model. You are modifying the values of your model in the POST controller action, but the ModelState values still contain the old values which will be used. If you want to modify values of your model in a POST action you should remove the original values from the ModelState if you intend to redisplay the same view:

public ActionResult Refresh(ReportModel reportModel)
{
    // clear the original posted values so that they don't get picked up
    // by the helpers
    ModelState.Clear();

    FinancialHistoryRepository financialHistoryRepository = new FinancialHistoryRepository();
    ...
    return View("Index",reportModel);
}

这篇关于为什么不复杂类型的列表绑定到文本框在一个表中显示更改模型在MVC 4?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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