2

我遇到了一个看起来很简单的问题,但我一直无法找到解决方案。我创建了一个 ReportModel 对象,它是视图中的模型。ReportModel 包含一个 FinancialHistory 对象的列表。我使用默认绑定填充对象并在视图中的表单内的文本框表中显示它们(这可以正常工作)。然后,用户可以提交表单以从不同的数据源刷新 FinancialHistory 对象,用新结果替换之前列表中的内容。返回新结果时,我可以看到模型包含预期的新值,但是在呈现 HTML 时,仍然出现原始金额。如果新结果包含比原始列表更多的对象(如示例代码中所示),则添加的行会显示正确的值。所以,

以下是模型:

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

在 Home/Index 视图中,我使用 HTML.TextBoxFor() 将列表中每个 FianancialHistory 对象的属性绑定到表中的文本框。这是索引视图:

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

对于这个例子,我在控制器中的操作方法非常简单。最初,Index 方法使用 2 个 FinancialHistory 对象填充列表。Refresh 方法用 3 个不同数量的新对象替换原来的 2 个对象。

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

1 回答 1

1

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);
}
于 2013-03-30T18:02:25.113 回答