希望能以一种相对统一的方式来处理Web API的Response
- StatusCode() 是ControllerBase的,所以就为之写了扩展方法
- 设计为XXXService的所有方法,全都返回一个继承自Response的类型的实例
[HttpGet]
public ActionResult<XXXResponse> Method1()
{
try
{
var response = m_service.DoSomething();
return this.UnifyResponseFormat(response);
}
catch (Exception e)
{
return this.FormatResponseForFailure((int)HttpStatusCode.InternalServerError, e.Message);
}
}
[HttpPost]
public IActionResult Method2([FromBody]XXXRequest request)
{
try
{
var validationResponse = m_service.ValidateRequest(request);
if(this.IsBadRequest(validationResponse))
{
return this.FormatResponseForFailure(validationResponse);
}
var response = m_service.DoSomething(request);
return this.UnifyResponseFormat(response);
}
catch(Exception e)
{
return this.FormatResponseForFailure((int)HttpStatusCode.InternalServerError, e.Message);
}
}
public class XXXResponse : Response
{
[JsonProperty(PropertyName = "A")]
public A a { get; set; }
}
public class Response
{
[JsonIgnore]
[JsonProperty(PropertyName = "status")]
public HttpStatusCode Status { get; set; } = HttpStatusCode.OK;
[JsonIgnore]
[JsonProperty(PropertyName = "reason")]
public string Reason { get; set; } = String.Empty;
}
public static class ResponseHelper
{
public static ObjectResult UnifyResponseFormat(this ControllerBase controllerBase, Response response)
{
int statusCode = (int)response.Status;
switch (response.Status)
{
case HttpStatusCode.OK:
return controllerBase.FormatResponseForSuccess(response);
case HttpStatusCode.InternalServerError:
return controllerBase.FormatResponseForFailure(response);
}
return controllerBase.FormatResponseForFailure((int)HttpStatusCode.BadRequest, "failed for certain reason. And also the response status code might not be properly handled by server");
}
public static ObjectResult FormatResponseForFailure(this ControllerBase controllerBase, Response response)
{
int statusCode = (int)response.Status;
return controllerBase.StatusCode((int)response.Status, response.Reason);
}
public static ObjectResult FormatResponseForFailure(this ControllerBase controllerBase, int statusCode, string reason)
{
return controllerBase.StatusCode(statusCode, reason);
}
public static ObjectResult FormatResponseForSuccess(this ControllerBase controllerBase, Response response)
{
int statusCode = (int)response.Status;
return controllerBase.StatusCode(statusCode, response);
}
public static bool IsBadRequest(this ControllerBase controllerBase, Response response)
{
return response.Status == HttpStatusCode.BadRequest;
}
}