我想知道是否可以在特定的控制器操作中禁用"Required"验证属性。我之所以这样想,是因为在我的一个编辑表单中,我不需要用户为他们之前已经指定的字段输入值。但是,当他们输入一个值时,我会实现一些特殊逻辑,例如对一个值进行哈希等操作来更新模型。
有没有任何建议可以解决这个问题?
编辑:
而且是的,客户端验证也是一个问题,因为它不允许他们提交表单而不输入值。
我想知道是否可以在特定的控制器操作中禁用"Required"验证属性。我之所以这样想,是因为在我的一个编辑表单中,我不需要用户为他们之前已经指定的字段输入值。但是,当他们输入一个值时,我会实现一些特殊逻辑,例如对一个值进行哈希等操作来更新模型。
有没有任何建议可以解决这个问题?
编辑:
而且是的,客户端验证也是一个问题,因为它不允许他们提交表单而不输入值。
这个问题可以通过使用视图模型轻松解决。视图模型是专门针对特定视图需求的类。所以例如在你的情况下,你可以有以下视图模型:
public UpdateViewView
{
[Required]
public string Id { get; set; }
... some other properties
}
public class InsertViewModel
{
public string Id { get; set; }
... some other properties
}
这将在它们对应的控制器操作中使用:
[HttpPost]
public ActionResult Update(UpdateViewView model)
{
...
}
[HttpPost]
public ActionResult Insert(InsertViewModel model)
{
...
}
Update(FormCollection collection)
,至少我从来没有这样做。我总是定义和使用一个特定的视图模型:Update(UpdateViewView model)
。 - Darin DimitrovInsert
。谢谢你指出了这一点。 - Darin Dimitrov如果你只想在客户端禁用单个字段的验证,那么可以按照以下方式覆盖验证属性:
@Html.TextBoxFor(model => model.SomeValue,
new Dictionary<string, object> { { "data-val", false }})
@Html.TexBoxFor(model => model.SomeValue, new { data_val = false })
,我的翻译如下:@Html.TexBoxFor(model => model.SomeValue, new { data_val = false })
- 依我的看法,这段代码更易读。 - eth0$(".search select").attr('data-val', false);
- Leniel Maccaferri我知道这个问题很久以前就有答案并且被接受的答案确实可以解决问题。但是有一件事情困扰着我:需要复制两个模型来禁用验证。
这是我的建议:
public class InsertModel
{
[Display(...)]
public virtual string ID { get; set; }
...Other properties
}
public class UpdateModel : InsertModel
{
[Required]
public override string ID
{
get { return base.ID; }
set { base.ID = value; }
}
}
这样,你就不必费心在客户端/服务器端验证上,框架会按照应有的方式表现。此外,如果你在基类上定义了一个 [Display]
属性,那么在 UpdateModel
中就不用重新定义它。
而且,你仍然可以像以前一样使用这些类:
[HttpPost]
public ActionResult Update(UpdateModel model)
{
...
}
[HttpPost]
public ActionResult Insert(InsertModel model)
{
...
}
ModelState.Remove<ViewModel>(x => x.SomeProperty);
@Ian's 对于MVC5的评论
以下仍然是可能的
ModelState.Remove("PropertyNameInModel");
ModelState
上没有与该签名匹配的方法。 - Ian Kemp客户端 根据我的研究,以下提供了多个选项来禁用表单验证。其中一个应该可以解决您的问题。
选项1:
我更喜欢这个选项,它对我来说完美地发挥了作用。
(function ($) {
$.fn.turnOffValidation = function (form) {
var settings = form.validate().settings;
for (var ruleIndex in settings.rules) {
delete settings.rules[ruleIndex];
}
};
})(jQuery);
并像这样调用它
$('#btn').click(function () {
$(this).turnOffValidation(jQuery('#myForm'));
});
选项2
$('your selector here').data('val', false);
$("form").removeData("validator");
$("form").removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse("form");
选项 3
var settings = $.data($('#myForm').get(0), 'validator').settings;
settings.ignore = ".input";
选项4
$("form").get(0).submit();
jQuery('#createForm').unbind('submit').submit();
选项 5
$('input selector').each(function () {
$(this).rules('remove');
});
服务器端
创建一个属性,并将您的操作方法标记为该属性。按照您的特定需求进行自定义。
[AttributeUsage(AttributeTargets.All)]
public class IgnoreValidationAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var modelState = filterContext.Controller.ViewData.ModelState;
foreach (var modelValue in modelState.Values)
{
modelValue.Errors.Clear();
}
}
}
这里描述了一种更好的方法启用/禁用MVC服务器端动态验证
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if( NumberField < 0 )
{
yield return new ValidationResult(
"Don't input a negative number",
new[] { "NumberField" } );
}
if( NumberField > 100 )
{
yield return new ValidationResult(
"Don't input a number > 100",
new[] { "NumberField" } );
}
yield break;
}
这是评论区中别人的答案...但它应该是真正的答案:
$("#SomeValue").removeAttr("data-val-required")
在具有[Required]
属性的字段上使用MVC 6进行测试。
我在创建一个编辑视图用于更新模型中的某个字段时遇到了问题。
我想要的最简单的解决方法是使用以下方式将这两个字段放在一起:
<%: Html.HiddenFor(model => model.ID) %>
<%: Html.HiddenFor(model => model.Name)%>
<%: Html.HiddenFor(model => model.Content)%>
<%: Html.TextAreaFor(model => model.Comments)%>
评论是我仅在编辑视图中更新的字段,它没有必需属性。
ASP.NET MVC 3实体
我正在寻找一种解决方案,可以在Web API中同时使用相同的模型进行插入和更新。在我的情况下,这总是一个主体内容。如果是更新方法,则必须跳过[Requiered]
属性。
在我的解决方案中,您需要在方法上方放置[IgnoreRequiredValidations]
属性。具体如下:
public class WebServiceController : ApiController
{
[HttpPost]
public IHttpActionResult Insert(SameModel model)
{
...
}
[HttpPut]
[IgnoreRequiredValidations]
public IHttpActionResult Update(SameModel model)
{
...
}
...
还需要做什么?
必须创建自己的BodyModelValidator并在启动时添加。
这在HttpConfiguration中,并且看起来像这样:config.Services.Replace(typeof(IBodyModelValidator), new IgnoreRequiredOrDefaultBodyModelValidator());
using Owin;
using your_namespace.Web.Http.Validation;
[assembly: OwinStartup(typeof(your_namespace.Startup))]
namespace your_namespace
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
Configuration(app, new HttpConfiguration());
}
public void Configuration(IAppBuilder app, HttpConfiguration config)
{
config.Services.Replace(typeof(IBodyModelValidator), new IgnoreRequiredOrDefaultBodyModelValidator());
}
...
我自己的BodyModelValidator是从DefaultBodyModelValidator派生而来的。我发现我必须重写'ShallowValidate'方法。在这个重写中,我过滤了所需的模型验证器。现在有了IgnoreRequiredOrDefaultBodyModelValidator类和IgnoreRequiredValidations属性类:
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web.Http.Controllers;
using System.Web.Http.Metadata;
using System.Web.Http.Validation;
namespace your_namespace.Web.Http.Validation
{
public class IgnoreRequiredOrDefaultBodyModelValidator : DefaultBodyModelValidator
{
private static ConcurrentDictionary<HttpActionBinding, bool> _ignoreRequiredValidationByActionBindingCache;
static IgnoreRequiredOrDefaultBodyModelValidator()
{
_ignoreRequiredValidationByActionBindingCache = new ConcurrentDictionary<HttpActionBinding, bool>();
}
protected override bool ShallowValidate(ModelMetadata metadata, BodyModelValidatorContext validationContext, object container, IEnumerable<ModelValidator> validators)
{
var actionContext = validationContext.ActionContext;
if (RequiredValidationsIsIgnored(actionContext.ActionDescriptor.ActionBinding))
validators = validators.Where(v => !v.IsRequired);
return base.ShallowValidate(metadata, validationContext, container, validators);
}
#region RequiredValidationsIsIgnored
private bool RequiredValidationsIsIgnored(HttpActionBinding actionBinding)
{
bool ignore;
if (!_ignoreRequiredValidationByActionBindingCache.TryGetValue(actionBinding, out ignore))
_ignoreRequiredValidationByActionBindingCache.TryAdd(actionBinding, ignore = RequiredValidationsIsIgnored(actionBinding.ActionDescriptor as ReflectedHttpActionDescriptor));
return ignore;
}
private bool RequiredValidationsIsIgnored(ReflectedHttpActionDescriptor actionDescriptor)
{
if (actionDescriptor == null)
return false;
return actionDescriptor.MethodInfo.GetCustomAttribute<IgnoreRequiredValidationsAttribute>(false) != null;
}
#endregion
}
[AttributeUsage(AttributeTargets.Method, Inherited = true)]
public class IgnoreRequiredValidationsAttribute : Attribute
{
}
}
来源:
string debug = new StackTrace().ToString()
查找处理模型验证的人员。