想要创建自定义数据注释验证.有关如何创建它们的有用指南/示例吗?
首先:
具有最小和最大长度的StringLength.我知道.NET 4可以做到这一点,但是想在.NET 3.5中做同样的事情,如果可能的话,只能定义最小长度(至少x个字符),最大长度(最多x个字符),或者两者都是(在x和y之间).
其次:
使用模数运算验证 - 如果数字是有效长度,我希望使用模数11算法进行验证(我已经在JavaScript中实现了它,所以我想它只是一个简单的移植?)
更新:
解决了第二个问题,只是复制JavaScript实现并进行一些调整,所以不需要解决方案.
我正在为后端构建一个带WebApi的AngularJS SPA应用程序.我在服务器上使用属性进行模型验证,如果验证失败,这就是我从ModelState返回的内容.
{"Message":"The request is invalid.","ModelState":{"model.LastName":["Last Name must be at least 2 characters long."]}}
Run Code Online (Sandbox Code Playgroud)
然后我如何使用AngularJS将其呈现给客户端?
//Save User Info
$scope.processDriverForm = function(isValid) {
if (isValid) {
//set button disabled, icon, text
$scope.locked = true;
$scope.icon = 'fa fa-spinner fa-spin';
$scope.buttonText = 'Saving...';
$scope.submitted = true;
$scope.formData.birthDate = $scope.formData.birthMonth + '/' + $scope.formData.birthDay + '/' + $scope.formData.birthYear;
$http({
method: 'POST',
url: 'api/Account/Register',
data: $.param($scope.formData),
headers: { 'Content-Type': 'application/x-www-form-urlencoded' } // set the headers so angular passing info as form data (not request …Run Code Online (Sandbox Code Playgroud) 在MVC中,我可以创建一个可以采用依赖关系的模型验证器.我通常使用FluentValidation.例如,这允许我检查帐户注册是否未使用电子邮件地址(注意:这是一个简化的示例!):
public class RegisterModelValidator : AbstractValidator<RegisterModel> {
private readonly MyContext _context;
public RegisterModelValidator(MyContext context) {
_context = context;
}
public override ValidationResult Validate(ValidationContext<RegisterModel> context) {
var result = base.Validate(context);
if (context.Accounts.Any(acc => acc.Email == context.InstanceToValidate.Email)){
result.Errors.Add(new ValidationFailure("Email", "Email has been used"));
}
return result;
}
}
Run Code Online (Sandbox Code Playgroud)
使用FluentValidation的Web API不存在此类集成.已经有夫妇的尝试,在这一点,但也没有解决的依赖注入方面,只有静态验证工作.
这很困难的原因是由于MVC和Web API之间的ModelValidatorProvider和ModelValidator的实现不同.在MVC中,这些是按请求实例化的(因此注入上下文很容易).在Web API中,它们是静态的,ModelValidatorProvider为每种类型维护ModelValidators的缓存,以避免对每个请求进行不必要的反射查找.
我一直试图自己添加必要的集成,但一直试图获得依赖范围.相反,我想我会退后一步,询问是否还有其他问题的解决方案 - 如果有人提出了执行模型验证的解决方案,可以注入依赖关系.
我不想在Controller中执行验证(我使用ValidationActionFilter来保持这一点),这意味着我无法从控制器的构造函数注入中获得任何帮助.
我一直在 环顾 四周,我认为我的解决方案很好,但不知何故ModelState.IsValid财产总是如此true.
请考虑以下代码段:
[Route("address")]
[HttpPut]
[ResponseType(typeof(UserViewModel))]
public IHttpActionResult UpdateAddress([FromBody] UpdateAdressValidationModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
// irrelevant code omitted
}
[TestMethod]
public void UpdateAddress_WithoutStreet_ReturnsHttpCode400()
{
var userController = new UserController(new UserRepository(_context));
var addressInfo = new UpdateAdressValidationModel
{
City = "Ghent",
};
var response = userController.UpdateAddress(addressInfo) as BadRequestResult;
Assert.IsNotNull(response);
}
public class UpdateAdressValidationModel
{
[Required]
public string Street { get; set; }
[Required]
public int? Number { get; set; }
[Required]
public …Run Code Online (Sandbox Code Playgroud) 我创建了一个ASP.net Web API控制器:
public class UsersController : ApiController
{
//...
public void Put([FromBody]User_API user, long UpdateTicks)
{
user.UpdateTicks = UpdateTicks;
//...
}
}
Run Code Online (Sandbox Code Playgroud)
如果客户端未提供正确的参数,则"user"参数将为null.我可以创建一个全局过滤器来检查这样的每个参数,如果发生任何错误,将返回400消息.
使用MVC4,我可以创建并注册一个全局动作过滤器,该过滤器将在执行动作之前检查模型状态,并ModelState在可能造成任何损害之前返回序列化的序列。
public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
{
if (!actionContext.ModelState.IsValid)
{
actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState);
}
}
Run Code Online (Sandbox Code Playgroud)
但是,使用MVC5时,我很难找到Request,因此CreateErrorResponse
public override void OnActionExecuting(ActionExecutingContext nActionExecutingContext)
{
if (!nActionExecutingContext.Controller.ViewData.ModelState.IsValid)
{
nActionExecutingContext.Result = // Where is Request.CreateErrorResponse ?
}
}
Run Code Online (Sandbox Code Playgroud)
我意识到我可以创建一个自定义响应类来分配给它,Result但是我宁愿使用内置的(如果CreateErrorResponse仍然可用)。
知道在哪里可以找到相对于ActionExecutingContextMVC5 / Web API 2中的它吗?
我正在使用ASP.NET Core 2.0,我有一个请求对象注释如下:
public class MyRequest
{
[Required]
public Guid Id { get; set; }
[Required]
public DateTime EndDateTimeUtc { get; set; }
[Required]
public DateTime StartDateTimeUtc { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
在我的控制器中:
public async Task<IActionResult> HandleRequest([FromBody] MyRequest request)
{ /* ... */ }
Run Code Online (Sandbox Code Playgroud)
我注意到一个问题与模型绑定:当我发送包含该头的请求Content-Type设置为application/json和一个空的身体,我想到,request在我的控制器是null和ModelState.IsValid是false.
但是当我有这样的身体时:
{
"hello": "a-string-value!"
}
Run Code Online (Sandbox Code Playgroud)
我request不是null,它有一切的默认值,而且ModelState.IsValid是true
这当然发生在我缺少所有Required属性的时候,并且唯一存在的名称与那里的属性不匹配(即使是这个单个参数的类型string,也与我的模型上的任何类型都不匹配).
所以在某种程度上,Required如果我的请求中没有任何内容,那些属性似乎正在起作用,但如果我的请求不为空,它们就不会做任何事情!
当我准备这个问题时,我注意到还有一个JsonRequired …
如标题所示,如果“模型”不完整,我将尝试返回所有错误的自定义集合。
尽管积极地进行“ SO'ing / Google搜索”,但我还没有找到解决我的问题的解决方案。
我可以使用“ ModelState”,但是由于“自定义”,我想手动执行此操作。
代码如下:
API级别
// POST api/<controller>
[HttpPost]
[Route("")]
public async Task<IHttpActionResult> Post([FromBody]Order order)
{
var modelResponse = new ModelResponse<Order>(order);
if (order == null)
return BadRequest("Unusable resource, object instance required.");
//Check if all required properties contain values, if not, return response
//with the details
if (!modelResponse.IsModelValid())
return this.PropertiesRequired(modelResponse.ModelErrors());
try
{
await _orderService.AddAsync(order);
}
catch (System.Exception ex)
{
return InternalServerError();
}
finally
{
_orderService.Dispose();
}
return Ok("Order Successfully Processed.");
}
Run Code Online (Sandbox Code Playgroud)
需要的属性操作结果
public List<string> Messages { get; …Run Code Online (Sandbox Code Playgroud) 我正在验证 ASP.NET MVC 中的模型,并抛出一个包含这些错误列表的自定义异常。这是首选的最佳实践,还是我应该返回一个强类型的错误列表,而不是使用 throw new CustomException(List errors)。无论在 BaseController 中的 OnException 中处理 ajax 请求还是回发,我都会捕获这些错误。
我正在使用ASP.Net MVC创建一个RESTful API
有一个GET路由有问题.我创建了一个参数模型来处理所有接收参数.
public class MyParameters : BaseParameters
{
public string ProductCode { get; set; }
...
}
Run Code Online (Sandbox Code Playgroud)
并以这种方式使用这个类:
public HttpResponseMessage Get([FromUri] MyParameters filter)
Run Code Online (Sandbox Code Playgroud)
问题是我没有传递任何参数 - 过滤器对象没有被初始化.它始终为空.
但我还是需要初始化这个对象,因为有一些默认参数,比如flags,我在构造函数中初始化.
public MyParameters()
{
AuthFlag = 'Y';
}
Run Code Online (Sandbox Code Playgroud)
我知道这是默认行为,但我不想做这样的事情:
if (filter == null)
filter = new MyParameters();
Run Code Online (Sandbox Code Playgroud)
也许是否有任何配置可用于创建参数对象?
谢谢你的任何建议.