我有一个表单,允许用户填写字段以创建票证(支持票证)。这些字段映射到名为TicketModel的模型。现在,在表单中我有2个按钮,一个创建票证(提交表单)和另一个(创建并关闭票证),打开一个对话框,允许用户在关闭票证时输入更多信息。具体来说,他们正在输入开始和结束日期以及他们为解决问题所做的工作的描述。
创建按钮工作正常。但是当我单击对话框中的关闭票据时,我注意到当调用我的CreateTicket操作方法时,对话框中填写的字段的模型属性(StartDate,EndDate和Description)不在TicketModel参数中(它们是null)。
以下是我的相关代码示例。
CreateTicket部分视图
@using (Ajax.BeginForm("AjaxCreateTicket", "Home",
new { id = "CreateTicketForm", enctype = "multipart/form-data" },
new AjaxOptions
{
OnBegin = "OnBegin",
OnSuccess = "OnSuccess",
OnFailure = "OnFailure"
}))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(false, "Please correct the following errors:")
<fieldset>
<legend>TicketModel</legend>
<div class="editor-label">
@Html.LabelFor(model => model.UserCreated)
</div>
<div class="editor-field">
@Html.TextBoxFor(model => model.UserCreated)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.UserDisplayName)
</div>
<div class="editor-field">
@Html.TextBoxFor(model => model.UserDisplayName)
</div>
// Remaining form fields omitted for brevity
</fieldset>
<div id="closeDialog" class="ui-dialog ui-widget ui-widget-content ui-corner-all ui-draggable ui-resizable" style="display: none;">
@Html.Partial("_CloseNewTicketComment", Model)
</div>
}
这是放在关闭对话框中的partialView
@model HelpDesk.Web.Models.TicketModel
<script>
// wire up datetimepicker
$(function () {
$(".date-picker").datetimepicker({
timepicker: true,
formatDate: 'm/d/Y',
formatTime: 'h:i a',
format: 'm/d/y h:i a',
validateOnBlur: false,
scrollInput: false,
step: 15
});
});
</script>
@Html.ValidationSummary(false, "Please correct the following errors:")
<div class="label">
Comment:
</div>
<div style="clear:both;height:10px" />
<div class="editor-field" id="closeTextBox">
@Html.TextAreaFor(model => model.CommentModel.Description, new { @id = "CloseDescription" })
</div>
<div style="clear:both;height:10px" />
<div class="editor-label">
@Html.LabelFor(model => model.DateWorkStarted)
</div>
<div class="editor-field">
@Html.TextBoxFor(model => model.DateWorkStarted, new { @class = "date-picker", @style = "width: 160px;" })
</div>
<div style="clear:both; height:10px" />
<div class="editor-label">
@Html.LabelFor(model => model.DateClosed)
</div>
<div class="editor-field">
@Html.TextBoxFor(model => model.DateClosed, new { @class = "date-picker", @style = "width: 160px;" })
</div>
<div>
@Html.HiddenFor(model => model.UserCreated)
</div>
<div style="clear:both; height:10px" />
来自CreateTicket局部视图的我的Javascript
<script type="text/javascript">
var userLookupData = '';
var thisRedactorCreate = '';
// wire up datetimepicker
$(function () {
$(".date-picker").datetimepicker({
timepicker: true,
formatDate: 'm/d/Y',
formatTime: 'h:i a',
format: 'm/d/y h:i a',
validateOnBlur: false,
scrollInput: false,
step: 15
});
});
function OnBegin() {
progressDialogOpen();
}
function OnSuccess() {
//thisRedactorCreate.redactor("destroy");
progressDialogClose();
$('#CreateTicketForm').clearForm();
showSuccessDialog(0);
}
function OnFailure() {
progressDialogClose();
}
// This is the click event jquery that opens the dialog
$("#CreateCloseButton").click(function () {
// change IsCreateAndClose boolean because this ticket is going to be closed
// upon creation
$("#IsCreateAndClose").val("true")
if ($('form').valid())
{
$(".validation-summary-errors")
.removeClass("validation-summary-errors")
.addClass("validation-summary-valid");
$("#closeDialog").dialog({
width: 525,
height: 500,
modal: true,
resizable: true,
title: 'Close Ticket',
close: function () {
$(this).dialog('close');
},
buttons:{
"Close Ticket": function () {
if ($('form').valid())
{
$('form').submit();
$('#closeDialog').dialog("close");
}
},
"Cancel": function () {
$(this).dialog('close');
}
}
});
}
})
在ajax调用
上调用的ActionMethod [ValidateInput(false)]//this is necessary because we are posting HTML
[ValidateAntiForgeryToken]
public ActionResult AjaxCreateTicket(TicketModel ticketModel)
{
// If this action is not being called from the create and close dialog
// we need to remove the data annotations for the descriptiong property of the commmentModel.
if (!ticketModel.IsCreateAndClose)
{
ModelState.Remove("CommentModel.Description");
}
if (ModelState.IsValid)
{
bool ticketCreated = false;
try
{
Ticket ticket = new Ticket();
//form collection
ticket.Title = ticketModel.Title;
ticket.UserEmail = ticketModel.UserEmail;
ticket.Description = ticketModel.Description;
ticket.UserComputerName = ticketModel.UserComputerName;
// Irrelevant code omitted for brevity.
如果我在action方法中设置断点并将一个监视添加到TicketModel对象。我注意到commentModel中的DateWorkStarted,DateClosed和Description字段为null。在过去的几天里,我一直在四处寻找,试图弄清楚为什么这没有运气。有没有人对我做错了什么(或者根本不做)有任何想法?
答案 0 :(得分:0)
从我在代码表单中看到的是'提交'正确,尽管表单的定义被省略,并且不清楚它在哪里发布。也许它会发布到AjaxCreateTicket动作,尽管我没有看到用[HttpPost]装饰的这个动作?
如果是这样,看起来ModelBinder存在问题。 (不幸的是你的模型也没有显示)。这就是为什么我只能怀疑您的模型定义公共字段而不是公共属性。 MopelBinder仅使用属性并忽略字段,无需访问它们 - 公共,内部,受保护。私人不计算在内。
当然,我可能完全错了,因为代码中缺少重要的部分。如果你把你的模型发布到最低限度,那么对于正在发生的事情会更加清楚。
答案 1 :(得分:0)
在与同事一起工作几天之后,我们能够让它发挥作用。唯一的问题是我不记得我们为了让它发挥作用我们到底做了什么(在很晚的时候归咎于它),但它现在似乎正在起作用。
感谢所有关于此的输入。