MVC3 Postback没有修改数据

时间:2012-08-03 15:32:15

标签: asp.net-mvc-3 postback

所以我有以下代码:

@model Project.Models.ViewModels.SomeViewModel
@using (Html.BeginForm("SomeAction", "SomeController", new { id = Model.Id}))
        {
            for(int i = 0; i < Model.SomeCollection.Count(); i++)
            {
                @Html.HiddenFor(x => Model.SomeCollection.ElementAt(i).Id)
                <div class="grid_6">
                    @Html.TextAreaFor(x => Model.SomeCollection.ElementAt(i).Text, new { @style = "height:150px", @class = "grid_6 input" })
                </div>
            }
            <div class="grid_6 alpha omega">
                <input type="submit" value="Next" class="grid_6 alpha omega button drop_4 gravity_5" />
            </div>
        }

在控制器端,我有以下内容:

[HttpPost]
        public ActionResult SomeAction(int id, SomeViewModel model)
        {

            return PartialView("_SomeOtherView", new SomeOtherViewModel(id));
        }

我的视图模型设置如下:

public class SomeViewModel
{
        public SomeViewModel()
        {

        }
        public IEnumerable<ItemViewModel> SomeCollection { get; set; }

}

public class ItemViewModel{

      public ItemViewModel(){}

      public int Id {get;set;}

      public string Text{get;set;}

}

如果执行了SomeAction,则SomeCollection始终为空。为了显示用户的更新值,我该怎么做。文本属性和Id字段。

4 个答案:

答案 0 :(得分:2)

使用 EditorTemplate

Views / YourcontrollerName 下创建一个EditorTemplate文件夹,并创建一个名称为ItemViewModel.cshtml的视图

enter image description here

并在该文件中包含此代码

@model  Project.Models.ViewModels.ItemViewModel
<p>
 @Html.EditorFor(x => x.Text) 
 @Html.HiddenFor(x=>x.Id)
</p>

现在,从主视图中,将其称为

@model  Project.Models.ViewModels.SomeViewModel
@using (Html.BeginForm("SomeAction", "Home", new { id = Model.Id}))
{
    @Html.EditorFor(s=>s.SomeCollection)
    <div class="grid_6 alpha omega">
        <input type="submit" value="Next" class="grid_6 alpha omega button drop_4 gravity_5" />
    </div>
}

现在,您的HTTPPOST方法将填充值。

我不确定你想对这些值做什么(返回局部视图?)所以不要对此做任何评论。

答案 1 :(得分:0)

我不确定您是否已发布所有代码。

您的操作方法不执行任何操作,因为它使用新的模型对象返回部分视图(出于某种原因来自后调用,而不是ajax请求)。

您有效地将模型传递回动作然后丢弃它,并返回一个新的模型对象。这就是你的收藏总是空的原因,它永远不会在任何地方设置。

答案 2 :(得分:0)

我发现这篇文章在尝试做同样的事情时特别有用。

Model Binding To A List

我建议使用IList或数组,以便您可以使用[index]语法。 祝你好运!

答案 3 :(得分:0)

嗯,首先,你为什么同时将模型AND id(模型的属性)发送回控制器?这看起来有点多余吗?此外,您在视图中使用了javascript for循环。使用@foreach会更容易。

无论如何,你的问题是,当你告诉某个动作接受一个模型时,它会在post中查找带有与模型的每个属性的名称相匹配的键的值。所以,假设我们有以下模型:

public class Employee
{
   public string Name;
   public int ID;
   public string Position;
}

如果我这样传回来的话:

@using(Html.BeginForm("SomeAction", "SomeController"))
{
     <input type="text" name = "name" [...] />    //in your case HtmlHelper is doing this for you, but same thing
     <input type="number" name = "id" [...] />
     <input type="submit" name = "position" [...] />
}

要将此模型传递回控制器,我必须这样做:

接受模型

//MVC matches attribute names to form values
public ActionResult SomethingPosted(Employee emp)
{
    //
}

接受值集合

//MVC matches parameter names to form values
public ActionResult SomethingPosted(string name, int id, string postion)
{
    //
}

或者这个:

接受FormCollection

//same thing as first one, but without a strongly-typed model
public ActionResult SomethingPosted(FormCollection empValues)
{
    //
}

所以,这是一个更好的代码版本。

您的新观点

@model Project.Models.ViewModels.SomeViewModel
@{
    using (Html.BeginForm("SomeAction", "SomeController", new { id = Model.Id}))
        {
            foreach(var item in Model)
            {
                @Html.HiddenFor(item.Id)
                <div class="grid_6">
                    @Html.TextAreaFor(item.Text, new { @style = "height:150px", @class = "grid_6 input" })
                </div>
            }
            <div class="grid_6 alpha omega">
                <input type="submit" value="Next" class="grid_6 alpha omega button drop_4 gravity_5" />
            </div>
        }
}

您的新动作

[HttpPost]
public ActionResult SomeAction(int Id, string Text)
{
    //do stuff with id and text
    return PartialView("_SomeOtherView", new SomeOtherViewModel(id));
}

[HttpPost]
public ActionResult SomeAction(IEnumerable<ItemViewModel> SomeCollection)  //can't use someviewmodel, because it doesn't (directly) *have* members called "Id" and "Text"
{
    //do stuff with id and text
    return PartialView("_SomeOtherView", new SomeOtherViewModel(id));
}