【问题标题】:How to return ModelState with Forbidden status web api如何使用禁止状态 web api 返回 ModelState
【发布时间】:2018-02-12 10:31:49
【问题描述】:

我们可以通过以下方式从 web api 返回 ModelStateBadRequest

return BadRequest(ModelState);

它提供以下输出:

{
    "Message": "The request is invalid.",
    "ModelState": {
        "property": [
            "error"
        ]
    }
}

如何以Forbidden 状态返回相同的输出?

我尝试了以下方法:

return Content(HttpStatusCode.Forbidden, ModelState);

但它会返回:

{
    "property": {
        "_errors": [
            {
                "<Exception>k__BackingField": null,
                "<ErrorMessage>k__BackingField": "error"
            }
        ],
        "<Value>k__BackingField": null
    }
}

Json 序列化ModelSate 也不会返回相同的东西。如何将BadRequest() 方法用于ModelState 的序列化方法与其他状态码一起使用?

【问题讨论】:

    标签: c# asp.net-web-api serialization modelstate modelstatedictionary


    【解决方案1】:

    您可以通过使用InvalidModelStateResultExecuteAsync 方法(ApiControllerBadRequest() 方法的返回类型)来实现所需的输出,该方法实际上序列化了ModelState

    所以想法是创建一个扩展InvalidModelStateResult 的新类并覆盖ExecuteAsync 方法来更改状态码。

    public class ModelStateResult : InvalidModelStateResult
    {
        private readonly HttpStatusCode _status;
    
        public ModelStateResult(ModelStateDictionary modelState, ApiController controller, HttpStatusCode status) : base(modelState, controller)
        {
            _status = status;
        }
    
        public override Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
        {
            var response = base.ExecuteAsync(cancellationToken).Result;
            response.StatusCode = _status;
            return Task.FromResult(response);
        }
    }
    

    像这样使用它:

    return new ModelStateResult(ModelState, this, HttpStatusCode.Forbidden);    //this refers to ApiController here
    

    我认为这只是一种解决方法,希望有人发布更好的方法来实现它。

    编辑:

    不使用InvalidModelStateResult

    public class ModelStateResult : IHttpActionResult
    {
        public HttpStatusCode Status { get; }
        public ModelStateDictionary ModelState { get; }
        public HttpRequestMessage Request { get; }
    
        public ModelStateResult(HttpStatusCode status, ModelStateDictionary modelState, HttpRequestMessage request)
        {
            Status = status;
            ModelState = modelState;
            Request = request;
        }
    
        public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
        {
            var response = Request.CreateErrorResponse(Status, ModelState);
            return Task.FromResult(response);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      • 1970-01-01
      • 2013-12-04
      • 1970-01-01
      相关资源
      最近更新 更多