新しい 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'
}
意味は、常に200 OKの HTTP ステータス コードを返す必要があるということです
。エラー表示は、「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 - 内部サーバー エラー) という事実を除いて、すべて問題ないように思われるので
、ハックのように見える次のコード行を追加しました。
HttpContext.Current.Response.StatusCode = (int)HttpStatusCode.OK;
このソリューションでは、何かが正しくありません。このような API の実装方法に関する経験豊富な Web API の洞察を歓迎します。ありがとう。