Jas*_*son 0 c# razor asp.net-mvc-3
我在我的模型中发布一个带有列表的ajax调用时遇到了麻烦.
我的模型是:
public class MyListItem
{
public int Id { get; set; }
public string Value { get; set; }
}
public class MyModel
{
public int Integer { get; set; }
public string Str { get; set; }
public List<MyListItem> MyList { get; set; }
public MyModel()
{
Str = "Initial";
Integer = 1;
}
}
Run Code Online (Sandbox Code Playgroud)
在我看来,我正在尝试将MyList的列表项显示为:
<div>
@{
if (Model.MyList != null)
{
int i = 0;
foreach (var item in Model.MyList)
{
<label>@item.Value</label>
@Html.Hidden("MyList[" + i + "].Id", item.Id);
@Html.TextArea("MyList[" + i + "].Value", item.Value, 1, 10, new { Value = item.Value });
<div />
i++;
}
}
}
</div>
Run Code Online (Sandbox Code Playgroud)
这个视图是局部视图,它从"主"视图中调用,如下所示:
<form id="mine2">
@{Html.RenderPartial("Test2", Model);}
</form>
Run Code Online (Sandbox Code Playgroud)
我的ajax帖子是:
function OnAddToListAjax() {
var actionUrl = '@Url.Action("AddToList", "Test1")';
var alist = @Html.Raw(Json.Encode(Model));
try
{
$.ajax(
{
url: actionUrl,
type: "POST",
dataType: "HTML",
contentType: 'application/json',
processData: false,
//data: JSON.stringify({myModel: existing, list: alist}),
data: JSON.stringify({myModel: alist}),
traditional: true,
success: function(result) {
//alert(result);
$('#mine2').html(result);
},
error: function (req, status, error) {
HandleError(req);
}
});
}
catch (err)
{
alert(err);
}
}
Run Code Online (Sandbox Code Playgroud)
我的控制器是:
[HttpPost]
public ActionResult AddToList(MyModel myModel)//, MyList list)
{
try
{
//var list = new MyList();
if (myModel.MyList == null)
myModel.MyList = new MyList();
myModel.Str += " Changed";
//throw new Exception("This is broken!");
myModel.MyList.Add(new MyListItem { Id = myModel.MyList.Count, Value = string.Format("Item {0}", myModel.MyList.Count) });
//myModel.MyList = list;
return PartialView("Test2", myModel);
}
catch (Exception ex)
{
myModel.ErrorModel = new ErrorModel() { ErrorDetails = "Error adding to list", ErrorString = ex.Message };
return PartialView("Test2", myModel);
}
}
Run Code Online (Sandbox Code Playgroud)
当使用我的模型的直接属性时,这个概念对我来说非常有效.例如,如果我尝试设置/获取Str的属性.但是,对于MyList项,它们似乎永远不会在Json命令中正确序列化.它保留了原始模型的一部分值.即第一次调用它时,MyList为null所以我创建它并将其作为Action Result的一部分返回.这会显示值ok.但是,如果我手动编辑该值并重新发布它,则发布的值与最初检索的值相同.
我相信它可能与我给TextArea的名称有关,而且无法正确解析.使用Firebug,其中一个文本区域的来源是:
<textarea id="MyList_0__Value" rows="1" name="MyList[0].Value" cols="10" value="Item 0">Item 0</textarea>
Run Code Online (Sandbox Code Playgroud)
所以我试图确定为什么模型的编码没有更新(编辑)的值.
TIA
我建议你使用编辑器模板.所以你可以用你的部分视图替换你在局部视图中编写的foreach循环:
@model MyModel
<div>
@if (Model.MyList != null)
{
@Html.EditorFor(x => x.MyList)
}
</div>
Run Code Online (Sandbox Code Playgroud)
然后为它定义一个编辑器模板,该模板将为列表(~/Views/Test1/EditorTemplates/MyListItem.cshtml
或~/Views/Shared/EditorTemplates/MyListItem.cshtml
)的每个元素呈现:
@model MyListItem
@Html.LabelFor(x => x.Value, Model.Value)
@Html.HiddenFor(x => x.Id);
@Html.TextAreaFor(x => x.Value, 1, 10);
Run Code Online (Sandbox Code Playgroud)
编辑器模板将负责正确命名输入字段,以便默认模型绑定器正确地反序列化它们.
现在在主视图中,您还可以使用编辑器模板而不是部分:
@model MyModel
@using (Html.BeginForm("AddToList", "Test1", FormMethod.Post, new { id = "myForm" }))
{
@Html.EditorForModel()
}
Run Code Online (Sandbox Code Playgroud)
然后我之前显示的编辑器模板将按惯例放入~/Views/Test1/EditorTemplates/MyModel.cshtml
或~/Views/Shared/EditorTemplates/MyModel.cshtml
.
好的,到目前为止一切顺利.最后一步是发送一个AJAX请求.这可以在单独的javascript文件中完成:
var myForm = $('#myForm');
$.ajax({
url: myForm.attr('action'),
type: myForm.attr('method'),
data: myForm.serialize(),
success: function(result) {
$('#mine2').html(result);
},
error: function (req, status, error) {
HandleError(req);
}
});
Run Code Online (Sandbox Code Playgroud)
干净简单.
现在我们已经清理了视图和javascript,我们必须清理控制器操作,这是原始问题的来源.因此,在您的控制器操作中,您尝试修改POSTed值.这个问题是HTML帮助程序在绑定时使用ModelState值,之后它们使用模型.这是设计的.因此,您在模型中放置的值将被助手完全忽略,您会看到旧值,这些值是发布到控制器操作的值.您必须先将它们从模型状态中删除.
归档时间: |
|
查看次数: |
3946 次 |
最近记录: |