MVC 3.0 编辑可变长度列表并使用 PRG 模式
我创建了一个具有可变长度列表的视图,如下所述: http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/。
我尝试将 PRG 模式与操作过滤器一起使用,如第 13 点所述:http://weblogs.asp.net/rashid/archive/2009/04/01/asp-net-mvc-best-practices-part-1.aspx。
我有一个编辑操作:
[HttpGet, ImportModelStateFromTempData]
public ActionResult Edit(int id)
{
}
和后操作:
[HttpPost, ExportModelStateToTempData]
public ActionResult Edit(int id, FormCollection formCollection)
{
if (!TryUpdateModel<CategoryEntity>(category, formCollection))
{
return RedirectToAction("Edit", new { id = id });
}
// succes, no problem processing this...
return RedirectToAction("Edit", new { id = id });
}
一切正常,包括验证和错误消息。
我遇到的唯一问题是重定向后不会保留新添加的项目和删除的项目(客户端删除/添加)。我正在尝试找到一种方法在使用新项目重定向后更新我的模型。我更改了 ImportModelStateFromTempData 属性以使用 OnActionExecuting 覆盖而不是 OnActionExecuted 覆盖,以使 ModelState 在操作中可用,但我没有看到从传入的 ModelState 更新模型的干净方法。
更改了 ImportModelStateFromTempData:
public class ImportModelStateFromTempData : ModelStateTempDataTransfer
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
ModelStateDictionary modelState = filterContext.Controller.TempData[Key] as ModelStateDictionary;
if (modelState != null)
{
filterContext.Controller.ViewData.ModelState.Merge(modelState);
}
base.OnActionExecuting(filterContext);
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
//ModelStateDictionary modelState = filterContext.Controller.TempData[Key] as ModelStateDictionary;
//if (modelState != null)
//{
// //Only Import if we are viewing
// if (filterContext.Result is ViewResult)
// {
// filterContext.Controller.ViewData.ModelState.Merge(modelState);
// }
// else
// {
// //Otherwise remove it.
// filterContext.Controller.TempData.Remove(Key);
// }
//}
base.OnActionExecuted(filterContext);
}
}
非常感谢对此的任何输入,谢谢。
Harmen
更新:我想我可能会添加更多的(伪)代码以使其更清晰:
public class CategoryEntity
{
public int Id;
public string Name;
public IEnumerable<CategoryLocEntity> Localized;
}
public class CategoryLocEntity
{
public int CategoryId;
public int LanguageId;
public string LanguageName;
public string Name;
}
我的编辑视图:
@model CategoryEntity
@{
ViewBag.Title = Views.Category.Edit;
}
<h2>@Views.Category.Edit</h2>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script type="text/javascript"><!--
$(document).ready(function () {
$('#addItem').click(function () {
var languageId = $('#languageId').val();
var index = $('#editor-rows').children().size() - 1;
$.ajax({
url: this.href + '?languageId=' + languageId + '&index=' + index,
cache: false,
error: function (xhr, status, error) {
alert(error);
},
success: function (html) {
$('#editor-rows').append(html);
}
});
return false;
});
$("a.removeItem").live("click", function () {
$(this).parents("div.editor-row:first").remove();
return false;
});
});
--></script>
@using (Html.BeginForm())
{
@Html.ValidationSummary(false)
<fieldset>
<legend>@Views.Shared.Category</legend>
@Html.HiddenFor(model => model.Id)
<div id="editor-rows">
<div class="editor-row">
<div class="editor-label">
@Html.LabelFor(model => model.Name, Views.Shared.NameEnglish)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
</div>
</div>
@for (int i = 0; i < Model.Localized.Count; i++)
{
@Html.EditorFor(m => m.Localized[i], "_CategoryLoc", null, null)
}
</div>
<div class="editor-label"></div>
<div class="editor-field">
@Html.DropDownList("languageId", (IEnumerable<SelectListItem>)ViewBag.LanguageSelectList)
@Html.ActionLink(Views.Category.AddNewLanguage, "AddNewLanguage", null, new { id = "addItem" })
</div>
<p class="clear">
<input type="submit" value="@Views.Shared.Save" />
</p>
</fieldset>
}
<div>
@Html.ActionLink(Views.Shared.BackToList, "Index")
</div>
CategoryLocEntity 的编辑器模板:
@model CategoryLocEntity
<div class="editor-row">
@Html.HiddenFor(model => model.Id)
@Html.HiddenFor(model => model.LanguageId)
<div class="editor-label">
@Html.LabelFor(model => model.LanguageName, Model.LanguageName)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Name)
<a href="#" class="removeItem">@Views.Shared.Remove</a>
@Html.ValidationMessageFor(model => model.Name)
</div>
</div>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我找到了一个解决方案(可能不是最优雅的解决方案,但它对我有用)。我创建了自己的 ModelStateValueProvider 来与 UpdateModel 一起使用。该代码基于DictionaryValueProvider。请参阅http://www.java2s.com/Open-Source/CSharp/2.6.4-mono-.net-core/System.Web/System/Web/Mvc/DictionaryValueProvider%601.cs.htm 。
我在编辑(获取)操作中使用它,例如:
期待您的评论...
I found a solution (probably not the most elegant one but it works for me). I created my own ModelStateValueProvider to be used with UpdateModel. The code is based on the DictionaryValueProvider. See http://www.java2s.com/Open-Source/CSharp/2.6.4-mono-.net-core/System.Web/System/Web/Mvc/DictionaryValueProvider%601.cs.htm.
I use it in de Edit (Get) action like:
Looking forward to your comments...