WebAPI validation

本文关键字:validation WebAPI | 更新日期: 2023-09-27 17:55:16

我通常有类似的ApiController方法

[HttpPost]
public HttpResponseMessage DoSomething(int someId)
{
  var someObj = Session.Get<SomeObj>(someId);
  if (someObj == null)
  {
    return Request.CreateResponse(HttpStatusCode.NotFound);
  }
  Do something...
}

我想摆脱if条件。我可以让NullPointerException被抛出,但我希望能够指定返回哪个HTTP状态代码。我想将if条件移到某个验证类中,并在OnActionExecuting中执行验证。

我以前在WebAPI中使用过FluentValidation,如果有这样的语法会很好:

RuleFor(x => x.SomeId).Must(x => someObjectExists()).WithMessage("SomeObject wasn't found").WithHTTPStatusCode(HttpStatusCode.NotFound);

其中WithHTTPStatusCode将是解决我的问题的方法。

你有什么建议吗?

WebAPI validation

酷名字!

我想向你推荐这种方法。创建一个您定义的新类,称为ServiceNotFoundException或类似的类,并让它从HttpResponseException继承,传入一个404作为构造函数,如下所示:

 public class ServiceNotFoundException : HttpResponseException
    {
        public ServiceNotFoundException() : base(HttpStatusCode.NotFound)
        {
        }
    }

现在在您的Session.Get中,如果在其中找不到实体,则应该抛出异常(因此将此逻辑保留在控制器之外(。

这样,如果多个控制器使用您的服务,它在所有情况下都会抛出异常。因为您从HttpResponseException继承并抛出NotFound,所以它将返回一个404。如果你需要特定的文本/消息来配合它,那么试着使用构造函数,你会看到base((有一个HttpResponseMessage,你可以在其中交替抛出(也许可以在响应中设置特定的消息文本(。

如果你更喜欢在控制器中执行此逻辑,那么无论如何都可以在那里抛出异常,但你应该尽量不要重复!

如果有任何问题,请告诉我!

我喜欢更安静地处理这个问题,因为它让任何访问WebAPI端点的人都不知道他们是否缺少所需的变量。

        [AcceptVerbs("GET", "POST")]
        public ServiceResult Login(JObject args)
        {
            var retVal = new ServiceResult {Success = false};
            JToken tokenValue;
            var email = string.Empty;
            var password = string.Empty;
            if (args.TryGetValue("email", out tokenValue))
            {
                email = args.Value<string>("email");
            }
            if (args.TryGetValue("password", out tokenValue))
            {
                password = args.Value<string>("password");
            }
            var user = Services.Users.GetByEmail(email, true);
            if (null != user || null != user.Id)
            {
                return Services.Authentication.AuthenticateSignIn(user, password, true);
            }
            retVal.Data = tokenValue;
            return retVal;
        }

如果变量丢失,默认情况下,它应该在到达端点之前出错,除非您将App_Start/WebApiConfig.cs设置为

config.Formatters.JsonFormatter.SerializerSettings.MissingMemberHandling = MissingMemberHandling.Ignore;

如果您不喜欢If条件,您可以在获取变量后始终使用Assert。祝你好运

为什么不使用标准模型验证?你在使用实体框架吗?您可以使用pocos上的数据注释来实现这一点,或者根据需要创建一个模型,在您的情况下,一个具有单个属性的类就可以了。

public async Task<IHttpActionResult> PutOrder(int id, Order order)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }...

订单模型应该是这样的。。。

    public partial class Order
    {
[Required]
 public int id { get; set; }
}