我有一个模态窗口,在按钮单击时弹出,包含一个带有几个字段和提交按钮的局部视图。在提交时,我将部分视图中的数据添加到数据库中,并重定向到生成弹出窗口的原始视图。所有这一切都很好。但是,现在我想在控制器操作中进行错误检查(对于唯一性)并从模态视图中显示错误。
以下是我如何使用其中的局部视图设置模态窗口
@Html.Kendo().Window().Name("CopyTaskWindow").Title("Copy Task").Modal(true).Width(400).Draggable().Iframe(false).Visible(false)
function onCopyClick(id) {
var wnd = $("#CopyTaskWindow").data("kendoWindow");
wnd.refresh({
url: '@(Url.Action("CopyTaskRender", "Task"))',
data: { id: id },
iframe: true
});
wnd.center().open();
}
这是部分视图
model pManager.Models.CopyTaskModel
@using (Html.BeginForm("CopyTask", "Task", FormMethod.Post, new { id = "copyTaskForm" }))
{
@Html.HiddenFor(model=>model.TaskID)
<div style="float: left; width: 48%;">
<div class="editor-label">
@Html.LabelFor(model => model.NewTaskName)
</div>
<div class="editor-field">
@(Html.EditorFor(model=>model.NewTaskName))
</div>
</div>
<div style="float: left; width: 48%;">
<div class="editor-label">
@Html.LabelFor(model => model.ProjectId)
</div>
<div class="editor-field">
@(Html.Kendo().DropDownListFor(model => model.ProjectId)
.DataTextField("Name")
.DataValueField("ID")
.DataSource(ds => ds
.Read("GetProjectsList", "Project").ServerFiltering(true)
)
)
</div>
</div>
<div align="center" class="btns-container">
<a class="k-button k-button-icontext k-grid-update btn-update" href="#" onclick="$('#copyTaskForm').submit()" >
<span class="k-icon k-update"></span>
Copy Task
</a>
<a class="k-button k-button-icontext k-grid-cancel btn-cancel" href="#">
<span class="k-icon k-cancel"></span>
Cancel
</a>
</div>
}
这里是渲染函数和实际处理来自提交的局部视图的数据的函数
public ActionResult CopyTaskRender(int? id)
{
var context = new pcloudEntities();
var tmp = context.Tasks.Where(i => i.id == id).Select(task => new CopyTaskModel()
{
NewTaskName = task.Name,
TaskID = task.id,
ProjectId = task.ProjectId
}).FirstOrDefault();
return PartialView("CopyTask", tmp);
}
public ActionResult CopyTask(CopyTaskModel model)
{
var context = new pcloudEntities();
var task = context.Tasks.FirstOrDefault(i => i.id == model.TaskID);
if (isUnique(model.NewTaskName, model.ProjectId))
{
context.Detach(task);
task.ProjectId = model.ProjectId;
task.Name = model.NewTaskName;
context.Tasks.AddObject(task);
context.SaveChanges();
return RedirectToAction("TasksList", "Task", new { projectID = model.ProjectId });
}
else
{
ModelState.AddModelError("", "Name is not unique");
return PartialView("CopyTask", model);
}
}
正如您所看到的,我试图通过执行ModelState.AddModelError来返回错误。但是,模态窗口仍然会关闭,并在局部视图外部呈现模态窗口。
有人可以建议我如何实现从模态视图弹出的错误吗?
谢谢
答案 0 :(得分:3)
你不能这样做。您需要使用远程验证。这是你如何做到的。
您可以像这样(更新):
定义您的剑道窗口@Html.Kendo().Window().Name("CopyTaskWindow")
.Title("Copy Task")
.Modal(true).Width(400)
.Draggable().Iframe(false)
.Visible(false)
.Events(events => events.Refresh("onRefresh")) // add a new event here...
function onRefresh(e) {
// this is to make sure client validation works in the window...
$.validator.unobtrusive.parse($("#CopyTaskWindow"));
// UPDATE: This will cause the validation to occur only on submit.
// But, as I explained in the comments, it won't work for remote validation...
$.validator.setDefaults({
onkeyup: false,
onfocusout: false,
onsubmit: true
});
var form = $("#CopyTaskWindow").find('#copyTaskForm');
form.submit(function () {
if (form.validate().valid()) {
var wnd = $("#CopyTaskWindow").data("kendoWindow");
wnd.close();
}
});
}
然后,在你的模型中,你在属性上使用RemoteAttribute
,需要对此进行唯一性验证(我假设NewTaskName必须是唯一的,即使从你的代码中还不清楚是什么你想这样做):
public class CopyTaskModel
{
[Remote("IsUnique", "YourControllerName", ErrorMessage = "The Task Name already exists.")]
public string NewTaskName { get; set; }
public int TaskID { get; set; }
public int ProjectId { get; set; }
}
然后,将验证错误消息添加到部分视图:
@model pManager.Models.CopyTaskModel
@using (Html.BeginForm("CopyTask", "Task", FormMethod.Post, new { id = "copyTaskForm" }))
{
@Html.HiddenFor(model=>model.TaskID)
<div style="float: left; width: 48%;">
<div class="editor-label">
@Html.LabelFor(model => model.NewTaskName)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.NewTaskName)
@Html.ValidationMessageFor(model => model.NewTaskName)
</div>
</div>
// The rest of your Partial View...
}
而且,在您的控制器中,您将拥有:
[HttpPost]
public ActionResult CopyTask(CopyTaskModel model)
{
var context = new pcloudEntities();
var task = context.Tasks.FirstOrDefault(i => i.id == model.TaskID);
context.Detach(task);
task.ProjectId = model.ProjectId;
task.Name = model.NewTaskName;
context.Tasks.AddObject(task);
context.SaveChanges();
return RedirectToAction("TasksList", "Task", new { projectID = model.ProjectId });
}
并且,新的远程验证操作:
public ActionResult IsUnique(NewTaskCopy model)
{
var isUnique = IsUnique(model.NewTaskName, model.ProjectId);
return Json(isUnique, JsonRequestBehavior.AllowGet);
}