WebApi - 在过滤器中访问和验证模型
WebApi - Access and validate models in Filters
我创建了一个过滤器,用于接收模型作为参数的操作。这个想法是在请求到达操作本身之前 return 一个 400。
这是过滤器:
public class ValidateModelAttribute : ActionFilterAttribute
{
private static readonly ILog Log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public override void OnActionExecuting(HttpActionContext actionContext)
{
Log.Debug("");
var _return = new BaseReturn<object>();
_return.Success = false;
try
{
if (actionContext.ModelState.IsValid && actionContext.ActionArguments[actionContext.ActionArguments.Keys.First()] != null)
return;
if (actionContext.ModelState.Values.Count == 0)
_return.Message = "Model not sent";
if (actionContext.ModelState.Values.Count > 0 && actionContext.ModelState.Values.Any(c => c.Errors.Count > 0))
_return.Message = actionContext.ModelState.Values.First(c => c.Errors.Count > 0).Errors[0].ErrorMessage;
}
catch (Exception ex)
{
_return.Message = ex.Message;
}
if (_return.Message == null)
_return.Message = "Model is not valid";
actionContext.Response = actionContext.Request.CreateResponse<BaseReturn<object>>(HttpStatusCode.BadRequest, _return);
}
}
这是我的行动:
[HttpPost]
[Route("api/Devices/{id}/SendOrder")]
[ValidateModel]
public BaseReturn<bool> SendNotificationToDevice(string id, OrderNotification model)
{
}
这里的问题是 ModelState 仅尝试验证 {id} 参数。如果我从方法声明中删除 {id},它 确实 验证我的模型。
有没有办法让 ModelState 验证这两个参数?
嗯...似乎 ModelState 确实 验证了模型,即使在方法声明中使用了 {id}。唯一的问题是我无法找到一种方法来发现(在 OnActionExecuting 方法中)是否发送了 OrderNotification 模型。
当我发送空 JSON 时,ModelState.Values.Count 为 1,并且由于 {id} 出现在 URL 中,ModelState.IsValid 为真。
parameter-binding-in-aspnet-web-api
To force Web API to read a complex type from the URI, add the
[FromUri]
attribute to the parameter
您是否尝试过将 [FromUri]
属性添加到您的参数?
[HttpPost]
[Route("api/Devices/{id}/SendOrder")]
[ValidateModel]
public BaseReturn<bool> SendNotificationToDevice(string id, [FromUri]OrderNotification model)
{
}
默认情况下,在 ASP.NET Web API 中,null
对象参数值不会被视为无效。如果您想将这些视为无效,您可以更新您的过滤器以首先处理参数以确保它们具有一个值集:
foreach (var parameter in actionContext.ActionDescriptor.GetParameters())
{
object parameterValue;
if (!parameter.IsOptional
&& parameter.ParameterType.IsClass
&& actionContext.ActionArguments.TryGetValue(parameter.ParameterName,
out parameterValue))
{
if (parameterValue == null)
{
ModelState.AddModelError(parameter.ParameterName, "");
}
}
}
我创建了一个过滤器,用于接收模型作为参数的操作。这个想法是在请求到达操作本身之前 return 一个 400。
这是过滤器:
public class ValidateModelAttribute : ActionFilterAttribute
{
private static readonly ILog Log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public override void OnActionExecuting(HttpActionContext actionContext)
{
Log.Debug("");
var _return = new BaseReturn<object>();
_return.Success = false;
try
{
if (actionContext.ModelState.IsValid && actionContext.ActionArguments[actionContext.ActionArguments.Keys.First()] != null)
return;
if (actionContext.ModelState.Values.Count == 0)
_return.Message = "Model not sent";
if (actionContext.ModelState.Values.Count > 0 && actionContext.ModelState.Values.Any(c => c.Errors.Count > 0))
_return.Message = actionContext.ModelState.Values.First(c => c.Errors.Count > 0).Errors[0].ErrorMessage;
}
catch (Exception ex)
{
_return.Message = ex.Message;
}
if (_return.Message == null)
_return.Message = "Model is not valid";
actionContext.Response = actionContext.Request.CreateResponse<BaseReturn<object>>(HttpStatusCode.BadRequest, _return);
}
}
这是我的行动:
[HttpPost]
[Route("api/Devices/{id}/SendOrder")]
[ValidateModel]
public BaseReturn<bool> SendNotificationToDevice(string id, OrderNotification model)
{
}
这里的问题是 ModelState 仅尝试验证 {id} 参数。如果我从方法声明中删除 {id},它 确实 验证我的模型。
有没有办法让 ModelState 验证这两个参数?
嗯...似乎 ModelState 确实 验证了模型,即使在方法声明中使用了 {id}。唯一的问题是我无法找到一种方法来发现(在 OnActionExecuting 方法中)是否发送了 OrderNotification 模型。
当我发送空 JSON 时,ModelState.Values.Count 为 1,并且由于 {id} 出现在 URL 中,ModelState.IsValid 为真。
parameter-binding-in-aspnet-web-api
To force Web API to read a complex type from the URI, add the
[FromUri]
attribute to the parameter
您是否尝试过将 [FromUri]
属性添加到您的参数?
[HttpPost]
[Route("api/Devices/{id}/SendOrder")]
[ValidateModel]
public BaseReturn<bool> SendNotificationToDevice(string id, [FromUri]OrderNotification model)
{
}
默认情况下,在 ASP.NET Web API 中,null
对象参数值不会被视为无效。如果您想将这些视为无效,您可以更新您的过滤器以首先处理参数以确保它们具有一个值集:
foreach (var parameter in actionContext.ActionDescriptor.GetParameters())
{
object parameterValue;
if (!parameter.IsOptional
&& parameter.ParameterType.IsClass
&& actionContext.ActionArguments.TryGetValue(parameter.ParameterName,
out parameterValue))
{
if (parameterValue == null)
{
ModelState.AddModelError(parameter.ParameterName, "");
}
}
}