Asp.net mvc POST数据中不包括MVC 3远程验证表单按钮
我有一个ASP.NET MVC3应用程序,在我的一个模型类上进行远程验证。我发现,如果我在提交表单之前打开该模型的编辑视图,并且未调用远程验证例程(由于未编辑带有远程验证的字段),则单击发布表单的按钮不会包含在发送到操作方法的请求数据中 如果在发布表单之前调用了远程验证例程,则单击提交表单的按钮将包含在发布中 我需要知道在服务器上调用操作时单击了哪个按钮,以便确定用户是单击了更新还是取消 如果我从模型中删除远程验证,表单每次都会正确提交 为什么在表单提交之前未调用远程验证时,用于提交表单的按钮会被排除在表单发布之外 谢谢 迈克尔 以下是一些示例代码:Asp.net mvc POST数据中不包括MVC 3远程验证表单按钮,asp.net-mvc,asp.net-mvc-3,Asp.net Mvc,Asp.net Mvc 3,我有一个ASP.NET MVC3应用程序,在我的一个模型类上进行远程验证。我发现,如果我在提交表单之前打开该模型的编辑视图,并且未调用远程验证例程(由于未编辑带有远程验证的字段),则单击发布表单的按钮不会包含在发送到操作方法的请求数据中 如果在发布表单之前调用了远程验证例程,则单击提交表单的按钮将包含在发布中 我需要知道在服务器上调用操作时单击了哪个按钮,以便确定用户是单击了更新还是取消 如果我从模型中删除远程验证,表单每次都会正确提交 为什么在表单提交之前未调用远程验证时,用于提交表单的按钮会
@model Channel
<script src="@Url.Content("~/Scripts/jquery-1.6.1.min.js")" type="text/javascript"></script>
<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>
@using (Html.BeginForm()) {
<fieldset>
<legend>Edit Channel</legend>
@Html.HiddenFor(model => model.ChannelGUID)
<div class="editor-label">Name</div>
<div class="editor-field">
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">Description</div>
<div class="editor-field">
@Html.EditorFor(model => model.Description)
@Html.ValidationMessageFor(model => model.Description)
</div>
<div class="editor-label">Channel Code</div>
<div class="editor-field">
@Html.EditorFor(model => model.Code)
@Html.ValidationMessageFor(model => model.Code)
</div>
<p>
<button type="submit" name="updateCommand" value="Update">Update</button>
<button type="submit" class="cancel">Cancel</button>
</p>
</fieldset>
}
以下是模型属性代码上的remote属性
[Remote("IsChannelCodeUnique", "Channel", AdditionalFields = "ChannelGUID", ErrorMessage = "code must be unique")]
我求助于将取消按钮更改为链接(使用操作链接),并使用jqueryui对表单上的链接和提交按钮进行样式设置,使其看起来相同。这避免了我在发布数据中没有包含单击按钮时遇到的问题。现在,当调用操作时,我不需要确定单击的按钮以查看用户是否按了取消。我们创建了一个自定义的ActionMethodSelectorAttribute,因此无需编写if-else或switch语句来确定单击了哪个按钮。以下是自定义类:
public class AcceptParameterAttribute : ActionMethodSelectorAttribute
{
public string Name { get; set; }
public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
{
var req = controllerContext.RequestContext.HttpContext.Request;
return req.Form[this.Name] != null;
}
}
此属性根据单击的按钮的名称选择要执行的方法。下面是用法:
[HttpPost]
[ActionName(ActionNameEditUser)]
[AcceptParameter(Name = "save")]
public ActionResult Save()
{
// put your code here
}
[HttpPost]
[ActionName(ActionNameEditUser)]
[AcceptParameter(Name = "cancel")]
public ActionResult Cancel()
{
// put your code here
}
所有剩下来命名按钮的工作都相应地完成了:
<button name="save">Save</button>
<button name="cancel">Cancel</button>
保存
取消
我遇到了同样的问题。我将远程验证添加到一个表单中,该表单有两个提交输入,并且单击的提交按钮的值不再总是发布
虽然其他答案提供了一些解决方法,但我对其进行了更深入的研究,并将回答您提出的实际问题:“当表单提交之前未调用远程验证时,为什么用于提交表单的按钮会被排除在表单发布之外?”
我知道这是一个好消息。因此,我尝试在禁用javascript的情况下发布。验证无效,但我提交的值已发布。我假设jquery.validate.js跳入并发送一个编程提交。事实确实如此。这就是使用jquery.validate.js 1.9.0解压时发生的情况:
event.preventDefault()代码>,但这仅在调试模式下调用。无论如何,在单击提交并执行远程验证后,将调用stopRequest方法
$(this.currentForm).submit()代码>,这是一个编程提交,不会发布提交的值。这就是为什么我无法确定单击了哪个提交按钮
validator.settings.submitHandler
或validator.submitButton
,因此从未调用此代码
如果在本例中也添加了这个隐藏字段,那就太好了,因为MVC不知道也不关心发布值的输入类型,控制器上的post操作只能使用该值
添加
我针对该问题的解决方法是向提交的单击函数添加一个处理程序:
$('input[type="submit"]').click(function () {
var hidden = $("<input type='hidden'/>").attr("name", this.name).val(this.value).appendTo($(this).closest("form"));
});
$('input[type=“submit”]”)。单击(函数(){
var hidden=$(“”).attr(“name”,this.name).val(this.value).appendTo($(this.closest(“form”));
});
隐藏字段已创建,因此我不必依赖具有正确名称的隐藏字段。
您可以为提交的文件指定相同的名称并测试其值,也可以为提交的文件指定不同的名称并测试是否存在post参数。
当然,您还需要使用尚未使用的表单字段名 您可以在视图中共享按钮的标记吗?更新您可以发布解决方案吗?我对MVC3中的远程验证和多个按钮有问题:()虽然这是一个很好的解决方案,但在使用问题中的远程验证方式时,它将不起作用,因为不会生成提交输入的post数据。谢谢。我认为隐藏字段应该在后续单击时删除并重新创建(或更新),尤其是在单击其他按钮时。例如,如果第一次单击“提交”按钮未通过验证,则随后单击“提交”按钮将添加另一个隐藏字段。
$('input[type="submit"]').click(function () {
var hidden = $("<input type='hidden'/>").attr("name", this.name).val(this.value).appendTo($(this).closest("form"));
});