【发布时间】:2012-07-06 18:37:23
【问题描述】:
我的控制器中有以下操作:
[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的解决方案版
在我看来,我有几个动作调用,我必须使用动作和控制器创建一个键。
自定义模型元数据
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 的多个局部视图的情况。在这种情况下,包括一个检查密钥的控件。因为它在key中包含了控制器的名字和action,所以这个key几乎是唯一的,只能在描述的情况下重复
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);
}
}
【问题讨论】:
-
一个仅供参考:使用模型获取 GET 是错误的。您应该使用 id 传递 GET,然后在您的方法中检索模型,如下所示
MyModel model = MyModel.Initialize(id) -
@amb 好的,但我需要测试控制器,并制作模型的
MOCK -
@amb:在 this 实例中使用带有 GET 的模型是错误的想法,但在其他领域完全没问题。您的 GET 可能需要一些需要验证的参数。
-
@rossisdead 我同意,但是从“可能有”到“让我们插入另一个参数”,最后“很多参数”是很短的距离......更不用说 GET 有一个非常限制长度。在 RESTful 服务领域考虑 GET 并遵循指南很有用。
标签: c# .net asp.net-mvc validation attributes