我正在使用automatic model validation(请参阅“更好的输入处理”)来保持控制器清洁;所以:
[HttpPost]
[ProducesResponseType(typeof(Product), 201)]
public IActionResult Post([FromBody] Product product)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
product = _repository.AddProduct(product);
return CreatedAtAction(nameof(Get), new { id = product.Id }, product);
}
成为:
[HttpPost]
[ProducesResponseType(201)]
public ActionResult<Product> Post(Product product)
{
_repository.AddProduct(product);
return CreatedAtAction(nameof(Get), new { id = product.Id }, product);
}
但是,我确实有一些具有phonenumber属性的模型。我想在调用模型验证之前“标准化”这些。我的意思是我想从各种输入中对这些属性(类型为string
)进行标准化,例如:
因此,无论用户以哪种形式输入电话号码,在调用验证之前,我想确保其始终为E.164格式(“规范化”)。规范化的完成方式无关紧要(如果您坚持要使用libphonenumber)。作为第二个,也许不太复杂的例子,我可以想象一个字符串在调用验证之前总是大写/小写。
在调用验证之前 调用我的规范化过程的正确或最佳方法是什么?我需要编写一些中间件吗?
也相关:我的模型包含属性,因此规范化器知道要规范化哪些属性(以及如何规范化):
class ExampleModel {
public int Id { get; set; }
public string Name { get; set; }
[NormalizedNumber(NumberFormat.E164)]
public string Phonenumber { get; set; }
}
我猜中间件(?或解决方案将是什么)然后可以建立一个模型,找出是否有任何属性(递归地)具有该属性,并在需要时调用规范化器
答案 0 :(得分:0)
也许您可以使用Formatter使用类似的方法。我使用类似的方法将所有传入的日期转换为我的API中的UTC格式
public class JsonModelFormatter : JsonMediaTypeFormatter
{
public override System.Threading.Tasks.Task<Object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger, CancellationToken cancellationToken)
{
System.Threading.Tasks.Task<Object> baseTask = base.ReadFromStreamAsync(type, readStream, content, formatterLogger, cancellationToken);
if (baseTask.Result != null)
{
var properties = baseTask.Result.GetType().GetProperties();
foreach (var property in properties)
{
//Check Property attribute and decide if you need to format it
if (property.CustomAttributes.Where (x=> you condition here))
{
if (property.CanWrite && property.GetValue(baseTask.Result, null) != null)
{
var propValue = ((string)property.GetValue(baseTask.Result, null));
//Update propValue here
property.SetValue(baseTask.Result, newPropValue);
}
}
}
}
return baseTask;
}
public override bool CanReadType(Type type)
{
return true;
}
}