用于WebApi 2的FluentValidation中的访问路由数据 [英] Access route data in FluentValidation for WebApi 2
问题描述
我有一个基本的C#Web Api 2控制器,该控制器具有用于创建实体的POST方法
I have a basic C# Web Api 2 controller that has a POST method to create an entity
public HttpResponseMessage Post(UserModel userModel){ ... }
还有一种更新所述模型的PUT方法
And also a PUT method to update said model
public HttpResponseMessage Put(int id, UserModel userModel) { ... }
这是UserModel
And here is the UserModel
public class UserModel
{
public virtual Name { get; set; }
public virtual Username { get; set; }
}
对于我的验证者,我想验证名称是否未在Post上使用-很容易.对于PUT,我需要验证其他用户是否使用了该名称,但是这个特定用户当然会使用相同的用户名.
For my validator, I want to validate that the name is not taken on Post - easy enough. For PUT, I need to validate that the name is not taken, by another user, but of course this particular user would have the same username.
public class UserModelValidator : AbstractValidator<UserModel>
{
public UserModelValidator()
{
RuleFor(user => user.Username)
.Must(NotDuplicateName).WithMessage("The username is taken");
}
private bool NotDuplicateName(string username)
{
var isValid = false;
//Access repository and check to see if username is not in use
//If it is in use by this user, then it is ok - but user ID is
//in the route parameter and not in the model. How do I access?
return isValid;
}
}
我正在使用AutoFac,所以也许有一种方法可以将HttpRequest注入到验证器中,并以此方式获取路由数据.
I am using AutoFac, so maybe there is a way to inject the HttpRequest into the validator and get the route data that way.
或者我可以创建一个模型绑定器来查找路线数据并将其添加到模型中?
Or possibly I could create a model binder that looks for the route data and adds it to the model?
还是有一种简单的方法?
Or is there an easy way?
推荐答案
最简单的方法当然是将Id
添加到UserModel
.但是,您必须在Post
和Put
操作上添加一些额外的检查.客户端提供时,第一个应忽略Id
.第二个可以检查路径中的Id
是否与模型中的Id
相同.如果不是,则返回BadRequest
.
The easiest way of course is to add the Id
to the UserModel
. You'd have to add some extra checking on the Post
and Put
operations though. The first should ignore the Id
when a client provides it. The second could check whether the Id
in the path is the same as the Id
in the model. If not, then return a BadRequest
.
更改的模型:
public class UserModel
{
public virtual Id { get; set; }
public virtual Name { get; set; }
public virtual Username { get; set; }
}
更改的方法:
public HttpResponseMessage Post(UserModel userModel)
{
// ignore provided userModel.Id
}
public HttpResponseMessage Put(int id, UserModel userModel)
{
if(id != userModel.Id)
{
// return bad request response
}
}
更新
在路线和模型中均具有ID确实确实允许您所评论的两者之间存在差异.尊敬的API使用者可能不会发布带有未对齐ID的请求.但是恶意消费者(又名黑客)很可能会这么做.因此,当ID不匹配时,您应该返回BadRequest
.
Having an Id in the route as well as in the model does indeed allow for a discrepancy between the two as you commented. A respectful API consumer will probably not post a request with misaligned Ids. But a malicious consumer (aka hacker) most probably will. Therefore you should return BadRequest
when the Ids don't match.
您当然不想像您提到的那样用ID更新UserModel
,否则您最终可能会被用户1(URL中的一个)覆盖,而用户1(URL中的一个)被用户2的详细信息(UserModel
中的一个)覆盖).
You certainly do not want to update the UserModel
with the Id as you mentioned otherwise you might end up with user 1 (the one in the url) overwritten by the details of user 2 (the one in the UserModel
).
这篇关于用于WebApi 2的FluentValidation中的访问路由数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!