2011-04-09 115 views
1

如果这是MVC3的问题,那么会有关于此的帖子,但我找不到任何内容。我一定做错了什么。我有一个简单的视图(Index.cshtml),它使用for循环遍历列表。在每次迭代中,我输出两个文本输入,其中一个列表项中的值。MVC3 - 使用编辑器的问题

@{Html.BeginForm();} 
@Html.Encode("\n") 
@for (int i = 0; i < Model.SortOptions.Count; i++) 
{ 
    @Html.TextBoxFor(m => m.SortOptions[i].ColumnName); 
    @Html.Encode("\n"); 
    @Html.TextBoxFor(m => m.SortOptions[i].Direction); 
    @Html.Encode("\n"); 
} 
<input type="submit" value="Submit" /> 
@{Html.EndForm();} 

我有两个控制器的视图,一个用于GET请求,一个用于POST。 POST版本将不同的项目添加到列表中的GET版本。这是问题出现的地方。页面重新加载后,文本框与GET页面上加载的页面具有相同的值。

起初我以为它一定是缓存问题,但如果我修改代码(如下所示),手动添加文本输入并将值注入到html中,则新值将发送到浏览器。

@{Html.BeginForm();} 
@Html.Encode("\n") 
@for (int i = 0; i < Model.SortOptions.Count; i++) 
{ 
    var columnNameName = string.Format("SortOptions[{0}].ColumnName", i); 
    var columnNameID = string.Format("SortOptions_{0}__ColumnName", i); 
    var directionName = string.Format("SortOptions[{0}].Direction", i); 
    var directionID = string.Format("SortOptions_{0}__Direction", i); 

<input type="hidden" name="@columnNameName" id="@columnNameID" value="@Model.SortOptions[i].ColumnName" /> 
<input type="hidden" name="@directionName" id="@directionID" value="@Model.SortOptions[i].Direction" /> 

} 
<input type="submit" value="Submit" /> 
@{Html.EndForm();} 

我已经通过代码来确保模型在发送到视图时包含期望值。我甚至通过查看视图中的代码来检查列表的值。它似乎有正确的值,但是当我在浏览器中查看它时,它具有应该与页面响应GET请求时相对应的值。这是编辑器模板的问题吗?我刚开始使用mvc3和剃须刀引擎,所以有很多我不知道。任何帮助,将不胜感激。

-----更新:新增控制器代码----

[HttpGet] 
    public ActionResult Index() 
    { 
     var inv = new InventoryEntities(); 
     var model = new IndexModel(inv); 
     model.SortOptions = new List<SortOption>(); 
     model.SortOptions.Add(new SortOption { ColumnName = "Model", Direction = SortDirection.Ascending }); 
     model.SortOptions.Add(new SortOption { ColumnName = "Make", Direction = SortDirection.Ascending }); 
     //Load data 
     model.LoadEquipmentList(); 

     return View(model); 
    } 


    [HttpPost] 
    [OutputCache(Duration = 1)] 
    public ActionResult Index(List<SortOption> sortOptions, SortOption sort) 
    { 
     var inv = new InventoryEntities(); 
     var model = new IndexModel(inv); 
     ModelState.Remove("SortOptions"); 
     model.SortOptions = new List<SortOption>(); 
     model.SortOptions.Add(new SortOption { ColumnName = "Type", Direction = SortDirection.Descending }); 
     model.SortOptions.Add(new SortOption { ColumnName = "SubType", Direction = SortDirection.Descending }); 
     model.EquipmentList = new List<EquipmentListItem>(); 
     model.EquipmentList.Add(new EquipmentListItem { ID = 3, AssignedTo = "Mike", Location = "Home", Make = "Ford", Model = "Pinto", Selected = false, SubType = "Car", Type = "Vehicle" }); 

     return View(model); 
    } 
+0

你能发布控制器操作代码吗? – sarvesh 2011-04-09 00:30:06

+0

现在发布控制器代码。 – m9k5j 2011-04-11 18:47:23

回答

0

请记住,Html帮助程序(如TextBoxFor)在绑定值和模型之后首先使用模型状态。让我们考虑以一个非常简单的例子来说明这是什么意思:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     return View(new MyViewModel { Name = "foo" }); 
    } 

    [HttpPost] 
    public ActionResult Index(MyViewModel model) 
    { 
     model.Name = "bar"; 
     return View(model); 
    } 
} 

和视图:

@model MyViewModel 
@using (Html.BeginForm()) 
{ 
    @Html.TextBoxFor(x => x.Name) 
    <input type="submit" value="OK" /> 
} 

现在,当您提交表单,你会想到的是,在文本框变为"bar"值因为这是您在POST操作中所做的,但值不会改变。这是因为模型状态下的密钥Name已经包含用户输入内容。所以,如果你想要这个工作,你需要从模型中取出状态原值:

[HttpPost] 
public ActionResult Index(MyViewModel model) 
{ 
    // remove the original value if you intend to modify it here 
    ModelState.Remove("Name"); 
    model.Name = "bar"; 
    return View(model); 
} 

同样的事情在您的情况同样会发生。因此,您可能需要在POST操作中从模型状态中删除要修改的值。

+0

我试着用ModelState.Remove,没有运气。我得到相同的结果。我将使用两种控制器方法的代码更新我的帖子。 – m9k5j 2011-04-11 18:38:12

+0

好的,这基本上是问题所在。我仍然不完全理解模型状态是如何工作的,但是如果我添加“ModelState.Clear();”在控制器方法的开始,它解决了这个问题。感谢您指点我正确的方向。 – m9k5j 2011-04-11 21:36:50

0

有两件事情我蹦出来 - 没有看到多一点很难说,但...这两种可能如此重写。额外的@符号不是必需的。

@using(Html.BeginForm()) { 
    Html.Encode("\n") 
    for (int i = 0; i < Model.SortOptions.Count; i++) { 
     Html.TextBoxFor(m => m.SortOptions[i].ColumnName); 
     Html.Encode("\n"); 
     Html.TextBoxFor(m => m.SortOptions[i].Direction); 
     Html.Encode("\n"); 
    } 
    <input type="submit" value="Submit" /> 
} 


@using (Html.BeginForm()) { 
    Html.Encode("\n"); 
    for (int i = 0; i < Model.SortOptions.Count; i++) { 
     var columnNameName = string.Format("SortOptions[{0}].ColumnName", i); 
     var columnNameID = string.Format("SortOptions_{0}__ColumnName", i); 
     var directionName = string.Format("SortOptions[{0}].Direction", i); 
     var directionID = string.Format("SortOptions_{0}__Direction", i); 

     <input type="hidden" name="@columnNameName" id="@columnNameID" value="@Model.SortOptions[i].ColumnName" /> 
     <input type="hidden" name="@directionName" id="@directionID" value="@Model.SortOptions[i].Direction" /> 

    } 
    <input type="submit" value="Submit" /> 
} 

否则你的东西看起来是正确的,我看不出我的头顶上有什么错。

+0

感谢您使用@提示。我已经为两个项目使用了MVC2,但这是第一个使用MVC3和剃须刀的项目。 – m9k5j 2011-04-11 18:49:58