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将是解决我的问题的方法。
你有什么建议吗?
酷名字!
我想向你推荐这种方法。创建一个您定义的新类,称为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; }
}