我的控制器中有以下操作:
[HttpGet]
public ActionResult Office(GestionOffice model)
{
ModelState.Clear();
model.Initialize();
return View(model);
}
我不需要GET采取行动,进行验证。这将有助于我通过GET进行调用。
这将是我理想的情况:
[HttpGet]
[NotValidateModel]
public ActionResult Office(GestionOffice model)
{
model.Initialize();
return View(model);
}
谢谢。
修改
NotValidateModel
澄清说不存在,会将案件归咎于避免验证。
移动模型的原因是MOCK
模型
编辑II
我有POST的动作,我需要通过GET接收我的动作,没有验证的模型,成功完成控制器中动作的测试
[HttpGet]
[NotValidateModel]
public ActionResult Office(GestionOffice model)
{
model.Initialize();
return View(model);
}
[HttpPost]
[ActionName("Office")]
[NotValidateModel]
public ActionResult OfficePost(GestionOffice model)
{
if(ModelState.IsValid)
{
model.Save();
return RedirectToAction("List");
}
model.Initialize();
return View(model);
}
关于@Mark解决方案的版本
在我看来,我有几个动作调用,我不得不用动作和控制器创建一个键。
自定义ModelMetaData
public class CustomModelMetaData : ModelMetadata
{
public CustomModelMetaData(ModelMetadataProvider provider, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)
: base(provider, containerType, modelAccessor, modelType, propertyName)
{
}
public override IEnumerable<ModelValidator> GetValidators(ControllerContext context)
{
var itemKey = this.CreateKey(context.RouteData);
if (context.HttpContext.Items[itemKey] != null && bool.Parse(context.HttpContext.Items[itemKey].ToString()) == true)
{
return Enumerable.Empty<ModelValidator>();
}
return base.GetValidators(context);
}
private string CreateKey(RouteData routeData)
{
var action = (routeData.Values["action"] ?? null).ToString().ToLower();
var controller = (routeData.Values["controller"] ?? null).ToString().ToLower();
return string.Format("NoValidation_{0}_{1}", controller, action);
}
}
过滤
public class NoValidationAttribute : FilterAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext)
{
var itemKey = this.CreateKey(filterContext.ActionDescriptor);
filterContext.HttpContext.Items.Add(itemKey, true);
}
private string CreateKey(ActionDescriptor actionDescriptor)
{
var action = actionDescriptor.ActionName.ToLower();
var controller = actionDescriptor.ControllerDescriptor.ControllerName.ToLower();
return string.Format("NoValidation_{0}_{1}", controller, action);
}
}
修改过滤器
可能存在在主视图中使用foreach调用具有属性NoValidation
的多个部分视图的情况。在这种情况下,包括检查密钥的控件。因为它包含控制器的名称和键中的动作,这个键几乎是唯一的,它只能在描述的情况下重复
public class NoValidationAttribute : FilterAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext)
{
var itemKey = this.CreateKey(filterContext.ActionDescriptor);
if (!filterContext.HttpContext.Items.Contains(itemKey))
{
filterContext.HttpContext.Items.Add(itemKey, true);
}
}
private string CreateKey(ActionDescriptor actionDescriptor)
{
var action = actionDescriptor.ActionName.ToLower();
var controller = actionDescriptor.ControllerDescriptor.ControllerName.ToLower();
return string.Format("NoValidation_{0}_{1}", controller, action);
}
}
答案 0 :(得分:2)
[请参阅@ANDRES在问题中提到的编辑更新
你想要做的事情有点难以实现,我不确定你为什么要这样做。我试图通过自定义ModelMetaData
和过滤器(未完全测试)来完成。
我们无法从模型绑定器或元数据提供程序中读取操作所装饰的属性,因此我们需要一个过滤器。过滤器在HttpContext.Items
中放置了一些值,我们可以从自定义元数据提供程序中检索它( http://stackoverflow.com/questions/6198155/asp-net-mvc-modelbinder-getting-action-方法)。
过滤强>
public class NoValidationAttribute : FilterAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext)
{
// please see the edits in question to see the key generation
filterContext.HttpContext.Items.Add("NoValidation", true);
}
}
自定义ModelMetaData
public class CustomModelMetaData : ModelMetadata
{
public CustomModelMetaData(ModelMetadataProvider provider, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName) :
base(provider, containerType, modelAccessor, modelType, propertyName)
{
}
public override System.Collections.Generic.IEnumerable<ModelValidator> GetValidators(ControllerContext context)
{
if (context.HttpContext.Items["NoValidation"] != null && bool.Parse(context.HttpContext.Items["NoValidation"].ToString()) == true)
return Enumerable.Empty<ModelValidator>();
return base.GetValidators(context);
}
}
自定义ModelMetaDataProvider
public class CustomModelMetaDataProvider : DataAnnotationsModelMetadataProvider
{
protected override ModelMetadata CreateMetadata(System.Collections.Generic.IEnumerable<Attribute> attributes,
Type containerType, Func<object> modelAccessor,
Type modelType,
string propertyName)
{
return new CustomModelMetaData(this, containerType, modelAccessor, modelType,
propertyName);
}
}
<强>的Global.asax.cs 强>
ModelMetadataProviders.Current = new CustomModelMetaDataProvider();
<强>用法强>
[HttpGet]
[NoValidation]
public ActionResult Office(GestionOffice model)
{
...
}
================================= 更新 ====== ===============================
不是通过继承CustomModelMetaData
来创建ModelMetadata
,而是认为继承DataAnnotationsModelMetadata
会很好。
public class CustomModelMetaData : DataAnnotationsModelMetadata
{
public CustomModelMetaData(DataAnnotationsModelMetadataProvider provider, Type containerType,
Func<object> modelAccessor, Type modelType, string propertyName,
DisplayColumnAttribute displayColumnAttribute) :
base(provider, containerType, modelAccessor, modelType, propertyName, displayColumnAttribute)
{
}
public override IEnumerable<ModelValidator> GetValidators(ControllerContext context)
{
var itemKey = this.CreateKey(context.RouteData);
if (context.HttpContext.Items[itemKey] != null &&
bool.Parse(context.HttpContext.Items[itemKey].ToString()) == true)
{
return Enumerable.Empty<ModelValidator>();
}
return base.GetValidators(context);
}
private string CreateKey(RouteData routeData)
{
var action = (routeData.Values["action"] ?? null).ToString().ToLower();
var controller = (routeData.Values["controller"] ?? null).ToString().ToLower();
return string.Format("NoValidation_{0}_{1}", controller, action);
}
}
在CustomModelMetaDataProvider
中,您必须设置一些属性。
public class CustomModelMetaDataProvider : DataAnnotationsModelMetadataProvider
{
protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes,
Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)
{
var displayColumnAttribute = new List<Attribute>(attributes).OfType<DisplayColumnAttribute>().FirstOrDefault();
var baseMetaData = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
// is there any other good strategy to copy the properties?
return new CustomModelMetaData(this, containerType, modelAccessor, modelType, propertyName, displayColumnAttribute)
{
TemplateHint = baseMetaData.TemplateHint,
HideSurroundingHtml = baseMetaData.HideSurroundingHtml,
DataTypeName = baseMetaData.DataTypeName,
IsReadOnly = baseMetaData.IsReadOnly,
NullDisplayText = baseMetaData.NullDisplayText,
DisplayFormatString = baseMetaData.DisplayFormatString,
ConvertEmptyStringToNull = baseMetaData.ConvertEmptyStringToNull,
EditFormatString = baseMetaData.EditFormatString,
ShowForDisplay = baseMetaData.ShowForDisplay,
ShowForEdit = baseMetaData.ShowForEdit,
Description = baseMetaData.Description,
ShortDisplayName = baseMetaData.ShortDisplayName,
Watermark = baseMetaData.Watermark,
Order = baseMetaData.Order,
DisplayName = baseMetaData.DisplayName,
IsRequired = baseMetaData.IsRequired
};
}
}
答案 1 :(得分:1)
是的,您使用[ValidateInput(false)]
属性,如下所示:
[ValidateInput(false)]
[HttpGet]
public ActionResult Office(GestionOffice model)
{
model.Initialize();
return View(model);
}
答案 2 :(得分:0)
如果您想在生产代码中使用而不进行验证,则需要禁用客户端验证,因为在服务器端它将被禁用。
将web.config修改为fallows:
<appSettings>
<add key="ClientValidationEnabled" value="false" />
</appSettings>
答案 3 :(得分:0)
验证在POST中进行,因此您必须删除Model.IsValid
并添加[ValidateInput(false)]
[HttpPost]
[ValidateInput(false)]
[ActionName("Office")]
public ActionResult OfficePost(GestionOffice model)
{
model.Save();
return RedirectToAction("List");
}
现在帖子会成功,但如果你插入数据库,你必须小心。