我正在使用新的 ASP.Net 4.5 Web Api 编写 Api。我的 Api 响应与fourSquare 的 Api Response Messages
非常相似。
我的 api 应该总是响应这样的消息:
{
Meta:
{
Code: "401"
ErrorDetails: "Not Authorized!"
}
Response: "The Api Response Object or Text'
}
意思是我应该总是返回 Http 状态码:200 OK
任何错误指示都将位于“Meta”标签中。因此,我为所有 Json 请求实现了一个 MediaFormatter。看起来像这样:
public class MyApiResponseFormatter : JsonMediaTypeFormatter
{
public MyApiResponseFormatter()
{
SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
}
public override bool CanReadType(Type type)
{
return true;
}
public override bool CanWriteType(Type type)
{
return true;
}
public override Task WriteToStreamAsync(Type type, object value, System.IO.Stream writeStream, System.Net.Http.HttpContent content, System.Net.TransportContext transportContext)
{
HttpContext.Current.Response.StatusCode = (int)HttpStatusCode.OK;
return Task.Factory.StartNew(() =>
{
ApiResponse apiResponse = CreateApiResponse(type, value);
using (StreamWriter requestWriter = new StreamWriter(writeStream))
{
requestWriter.Write(JsonConvert.SerializeObject(apiResponse, new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
}));
}
});
}
private ApiResponse CreateApiResponse(Type type, object value)
{
#region Handle Errors
Type exceptionType = null;
ErrorDetails errorDetails = null;
HttpStatusCode statusCode = HttpStatusCode.OK;
if (type == typeof(HttpError))
{
exceptionType = Type.GetType(((System.Web.Http.HttpError)value)["ExceptionType"].ToString());
errorDetails = new ErrorDetails()
{
Message = ((System.Web.Http.HttpError)value)["ExceptionMessage"].ToString(),
StackStace = ((System.Web.Http.HttpError)value)["StackTrace"].ToString()
};
// get the status code
if (exceptionType == typeof(UnauthorizedAccessException))
{
statusCode = HttpStatusCode.Unauthorized;
}
else
{
statusCode = HttpStatusCode.BadRequest;
};
}
#endregion
ApiResponse apiResponse = new ApiResponse()
{
Meta = new MetaData()
{
Code = (int)statusCode,
ErrorType = exceptionType,
ErrorDetails = errorDetails
},
Notifications = null,
Response = type == typeof(HttpError) ? null : value
};
return apiResponse;
}
public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, System.Net.Http.HttpContent content, IFormatterLogger formatterLogger)
{
return base.ReadFromStreamAsync(type, readStream, content, formatterLogger);
}
}
一切似乎都很好,除了如果引发异常,响应上的状态代码不是 200(它是 500 - 内部服务器错误)
所以我添加了这行代码,看起来像一个 hack:
HttpContext.Current.Response.StatusCode = (int)HttpStatusCode.OK;
在这个解决方案中感觉有些不对劲。任何有经验的关于如何实现这样的 Api 的 web api 见解将不胜感激。谢谢。