我有一个 ItemsController,它带有一个 Index 操作,可以在客户端返回和呈现项目,例如
return View(itemViewModels);
每个 itemViewModel 都有一些 Bootstrap 选项卡。在每个选项卡中呈现一个 partialView。
当用户编辑 partialView 并将数据发送到 Tab1Controller 时,我如何返回整个 itemViewModel 的 View ,显示其中的一个局部 View 的验证错误标签 1?
我已经使 View 工作请求/响应发送的 itemViewModel 但随后只返回单个项目的 html 而不是完整的项目 html。
并且当我将索引 View 返回到 ItemsViewModels 时,我无法返回我传递的 itemViewModels 以显示验证错误。
[HttpGet]
public ActionResult Index(ItemViewModel viewModel)
{
return View("ItemsViewModels", viewModel);
}
此代码不起作用,因为 View 与 View 模型类型不匹配。
但我需要显示 ItemsViewModels 的 Html 以及单个编辑的 itemViewModel 的无效(data-val 属性)html。
我不能发布和返回 ItemsViewModels,因为它有许多其他属性会使模型状态无效...
你有什么想法吗?
更新
我不允许使用 ajax,否则问题会很快解决...这是针对一个普通网站,客户希望回发没有 ajax/SPA 行为。
此刻我再次从服务中获取整个项目并呈现它,但随后每个 ItemViewModel 的 html 都有一个无效的,例如文本框。但我希望只有某个 ItemViewModel 是无效的。
[HttpPost]
public virtual async Task<ActionResult> SaveLanguage(ItemViewModel itemViewModel)
{
var viewModels = GetItemsViewModelsFromSErvice();
viewModels.Items.ElementAt(0).Settings = itemViewModel;
return View(MVC.Test.Items.Views.Index,viewModels );
}
最佳答案
如果您被迫进行完整的回发,但每个部分 View 只包含一个包含该 1 项元素的表单,那么您必须在返回之前在 Controller 中重建其他项。
你的 Controller 方法应该是这样的
public ActionResult Index()
{
var vm = GetAllItems(); //method to get all your items for first load
return View(vm);
}
[HttpPost]
public ActionResult Index(ItemViewModel viewModel)
{
//get the full list of items, and then replace just the altered one
var vm = GetAllItems(); // assume returns a list
var index = vm.FindIndex(x => x.ID == viewModel.ID);
vm[index] = viewModel;
//might have to rename items in the ModelState.Errors dictionary
//so they are associated with the correct item index.
//first get the list of errors. As viewModel is not a list for this method
//they will have keys like "PropertyName".
//For a listItem need renaming to something like "[#].PropertyName" (# = index)
var errs = from ms in ModelState
where ms.Value.Errors.Any()
let fieldKey = ms.Key
let errors = ms.Value.Errors
from error in errors
select new {fieldKey, error.ErrorMessage};
//clear the ModelState, and then re-add any model-errors with the renamed key
ModelState.Clear();
foreach(var item in errs)
{
ModelState.AddModelError(
String.Format("[{0}].{1}", index, item.fieldKey), item.ErrorMessage);
}
return View("ItemsViewModels", vm);
}
此外,您可能需要重命名表单元素,以便模型绑定(bind)器在回发后将它们视为列表项。不过,我不是 100% 确定这是必要的。
如果你可以使用 ajax,这会变得更整洁......
看起来您的索引模型是 List<ItemViewModel>
然后您的主视图 (Index.cshtml) 将类似于..
@model List<ItemViewModel>
...
@for(int i = 0; i < Model.Count; i++)
{
<div id="@String.Format("partialContainer{0}", Model[i].ID)">
@Html.Partial("Partial1", Model[i])
</div>
}
(注意容器 div 的 ID 是我们可以作为 ajax 更新目标引用的东西)
然后让您的部分 View 使用相关的部分模型
例如 Partial1.cshtml:
@model ItemViewModel
... etc
@using (Ajax.BeginForm("RefreshPartial", "Home", null, new AjaxOptions() {
UpdateTargetId = String.Format("partialContainer{0}", Model.ID), HttpMethod = "Post" }, null))
{
@Html.TextBoxFor(m => m.Property1);
@* form controls... *@
<input type="submit" value="Submit" />
}
关于asp.net-mvc - 返回一个 View 模型类型与传递的不同的 mvc 操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28479955/