[英]Return a list of errors with BadRequest (WebApi)
正如标题所示,我想要做的就是在“模型”不完整的情况下返回自定义的错误集合。
虽然积极地“SO'ing /谷歌搜索”,但我还没有找到解决方案来帮助解决我的问题。
我可以使用“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.");
}
属性必需的操作结果
public List<string> Messages { get; private set; }
public HttpRequestMessage Request { get; private set; }
public PropertiesRequiredActionResult(List<string> message,
HttpRequestMessage request)
{
this.Messages = message;
this.Request = request;
}
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
return Task.FromResult(Execute());
}
public HttpResponseMessage Execute()
{
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.BadRequest);
response.Content = new ObjectContent()
//new List<StringContent>(Messages); //Stuck here
response.RequestMessage = Request;
return response;
}
根据自定义属性查找不完整的属性
private T _obj;
public ModelResponse(T obj)
{
_obj = obj;
}
private Dictionary<string, object> GetPropertyAttributes(PropertyInfo property)
{
Dictionary<string, object> attribs = new Dictionary<string, object>();
// look for attributes that takes one constructor argument
foreach (CustomAttributeData attribData in property.GetCustomAttributesData())
{
if (attribData.ConstructorArguments.Count == 1)
{
string typeName = attribData.Constructor.DeclaringType.Name;
if (typeName.EndsWith("Attribute")) typeName = typeName.Substring(0, typeName.Length - 9);
attribs[typeName] = attribData.ConstructorArguments[0].Value;
}
}
return attribs;
}
private IEnumerable<PropertyInfo> GetProperties()
{
var props = typeof(T).GetProperties().Where(
prop => Attribute.IsDefined(prop, typeof(APIAttribute)));
return props;
}
public bool IsModelValid()
{
var props = GetProperties();
return props.Any(p => p != null);
}
public List<string> ModelErrors()
{
List<string> errors = new List<string>();
foreach (var p in GetProperties())
{
object propertyValue = _obj.GetType()
.GetProperty(p.Name).GetValue(_obj, null);
if (propertyValue == null)
{
errors.Add(p.Name + " - " + GetPropertyAttributes(p).FirstOrDefault());
}
}
return errors;
}
属性样本
/// <summary>
/// The date and time when the order was created.
/// </summary>
[API(Required = "Order Created At Required")]
public DateTime Order_Created_At { get; set; }
因此,忽略后两个片段,更多的是提供完整的流程概述。 我完全理解有一些“开箱即用”的技术,但我喜欢自己设计。
到目前为止,是否可以使用“BadRequest”返回错误列表?
非常感激。
您可能正在寻找使用此方法:
BadRequestObjectResult BadRequest(ModelStateDictionary modelState)
它的用法是这样的,例子来自SO中的另一个问题 :
if (!ModelState.IsValid)
return BadRequest(ModelState);
根据模型错误,您会得到以下结果:
{
Message: "The request is invalid."
ModelState: {
model.PropertyA: [
"The PropertyA field is required."
],
model.PropertyB: [
"The PropertyB field is required."
]
}
}
希望能帮助到你
在IHttpActionResult
的自定义实现中,使用请求创建响应并传递模型和状态代码。
public List<string> Messages { get; private set; }
public HttpRequestMessage Request { get; private set; }
public HttpResponseMessage Execute() {
var response = Request.CreateResponse(HttpStatusCode.BadRequest, Messages);
return response;
}
我知道从这篇文章发布之日起就已经很晚了,以防其他人有同样的需求。
我是这样做的:
public object GetModelStateErrors(ModelStateDictionary modelState)
{
var errors = new List<string>();
foreach (var state in modelState)
{
foreach (var error in state.Value.Errors)
{
errors.Add(error.ErrorMessage);
}
}
var response = new { errors = errors };
return response;
}
正如您所见, GetModelStateErrors
是一个函数,它返回一个字符串数组,其中包含您已收到的错误集合,并接收ModelState
对象以从中获取这些错误。
我这样实现了:
return Request.CreateResponse(HttpStatusCode.BadRequest, GetModelStateErrors(ModelState))
我使用Insomnia的反应是:
{
"errors": [
"The Correo field is required.",
"The Telefono field is required."
]
}
希望有所帮助
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.