我目前正在尝试编写一个Web API应用程序,其中我要验证的参数之一是查询参数(也就是说,我希望以val accum1:Accumulable[a]
val accum2: Accumulable[b]
val accum3: Accumulable[c]
data.foreach{
u =>
accum1+=u
accum2 += u
accum3 += u
}
的形式传递它):
/route?offset=0&limit=100
特别是,我想确保"偏移"大于0,因为负数会导致数据库抛出异常。
我直接采用了附加[HttpGet]
public async Task<HttpResponseMessage> GetItems(
int offset = 0,
int limit = 100)
{
if (!ModelState.IsValid)
{
// Handle error
}
// Handle request
}
的逻辑方法:
ValidationAttribute
这根本不会导致任何错误。
经过对ASP.NET的大量痛苦调试后,在我看来,这可能根本不可能。特别是,因为[HttpGet]
public async Task<HttpResponseMessage> GetItems(
[Range(0, int.MaxValue)] int offset = 0,
int limit = 100)
{
if (!ModelState.IsValid)
{
// Handle error
}
// Handle request
}
参数是方法参数而不是字段,offset
是使用ModelMetadata
而不是GetMetadataForType
创建的,这意味着GetMetadataForProperty
将是PropertyName
。反过来,这意味着null
调用AssociatedValidatorProvider
,它使用一个空的属性列表,即使参数上有属性。
我甚至没有看到以这样的方式编写自定义GetValidatorsForType
的方法来获取该信息,因为这是一个函数参数的信息似乎早已丢失。一种方法可能是从ModelValidatorProvider
类派生并使用自定义ModelMetadata
,但基本上没有任何此代码的文档,因此它将是一个crapshoot它实际上工作正常,我必须复制所有ModelMetadataProvider
逻辑。
有人能证明我错了吗?有人可以告诉我如何获得验证来处理参数,类似于DataAnnotationsModelValidatorProvider
在MVC中的工作方式吗?或者是否有另一种绑定查询参数的方法可以使验证正常工作?
答案 0 :(得分:3)
您可以使用这两个属性创建 视图 请求模型类,并在属性上应用验证属性。
public class Req
{
[Range(1, Int32.MaxValue, ErrorMessage = "Enter number greater than 1 ")]
public int Offset { set; get; }
public int Limit { set; get; }
}
在您的方法中,将其用作参数
public HttpResponseMessage Post(Req model)
{
if (!ModelState.IsValid)
{
// to do :return something. May be the validation errors?
var errors = new List<string>();
foreach (var modelStateVal in ModelState.Values.Select(d => d.Errors))
{
errors.AddRange(modelStateVal.Select(error => error.ErrorMessage));
}
return Request.CreateResponse(HttpStatusCode.OK, new { Status = "Error",
Errors = errors });
}
// Model validation passed. Use model.Offset and Model.Limit as needed
return Request.CreateResponse(HttpStatusCode.OK);
}
当请求到来时,默认模型绑定器会将请求参数(limit
和offset
(假设它们是请求的一部分)映射到Req
类的对象并且您将能够调用ModelState.IsValid
方法。
答案 1 :(得分:1)
对于 .Net 5.0 和验证查询参数:
using System.ComponentModel.DataAnnotations;
namespace XXApi.Models
{
public class LoginModel
{
[Required]
public string username { get; set; }
public string password { get; set; }
}
}
namespace XXApi.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class LoginController : ControllerBase
{
[HttpGet]
public ActionResult login([FromQuery] LoginModel model)
{
//.Net automatically validates model from the URL string
//and gets here after validation succeeded
}
}
}
答案 2 :(得分:0)
if (Offset < 1)
ModelState.AddModelError(string.Empty, "Enter number greater than 1");
if (ModelState.IsValid)
{
}