我在ASP.NET Web API项目中启用了CORS,一切都按预期工作。我想在提供无效原点时覆盖默认错误消息。现在我收到了一条默认错误消息:
{"Message":"The origin 'http://xyz' is not allowed."}
我想返回这样的内容:
{"Code": 1000, "Message":"The origin 'http://xyz' is not allowed."}
我通过自定义政策启用CORS:
config.SetCorsPolicyProviderFactory(new MyCorsPolicyProviderFactory());
config.EnableCors();
定义错误消息在哪里?任何帮助,将不胜感激。谢谢。
答案 0 :(得分:0)
我能够通过做类似以下的事情来实现这一目标:
CorsResult
以存储错误代码。public class MyCorsResult : CorsResult {
public ErrorCode ErrorCode { get; set; }
public new bool IsValid {
get {
return base.IsValid && ErrorCode == default(int);
}
}
}
CorsEngine
并覆盖TryValidateOrigin
以正确设置错误代码。public class MyCorsEngine : CorsEngine {
public bool TryValidateOrigin(CorsRequestContext requestContext, CorsPolicy policy, MyCorsResult result) {
if (requestContext == null) {
throw new ArgumentNullException("requestContext");
}
if (policy == null) {
throw new ArgumentNullException("policy");
}
if (result == null) {
throw new ArgumentNullException("result");
}
if (requestContext.Origin != null) {
if (policy.AllowAnyOrigin) {
if (policy.SupportsCredentials) {
result.AllowedOrigin = requestContext.Origin;
}
else {
result.AllowedOrigin = CorsConstants.AnyOrigin;
}
}
else if (policy.Origins.Contains(requestContext.Origin)) {
result.AllowedOrigin = requestContext.Origin;
}
else {
result.ErrorCode = 1000;
result.ErrorMessages.Add(string.Format("The origin '{0}' is not allowed", requestContext.Origin));
}
}
else {
result.ErrorCode = 1001;
result.ErrorMessages.Add("The origin header is missing");
}
return result.IsValid;
}
// Needed to implement the below since we're using `MyCorsResult` instead of `CorsResult` now
public MyCorsResult EvaluatePolicy(CorsRequestContext requestContext, CorsPolicy policy) {
if (requestContext == null) {
throw new ArgumentNullException("requestContext");
}
if (policy == null) {
throw new ArgumentNullException("policy");
}
MyCorsResult result = new MyCorsResult();
if (this.TryValidateOrigin(requestContext, policy, result)) {
result.SupportsCredentials = policy.SupportsCredentials;
if (requestContext.IsPreflight) {
if (this.TryValidateMethod(requestContext, policy, result)) {
if (!this.TryValidateHeaders(requestContext, policy, result)) {
return result;
}
result.PreflightMaxAge = policy.PreflightMaxAge;
}
return result;
}
AddHeaderValues(result.AllowedExposedHeaders, policy.ExposedHeaders);
}
return result;
}
private static void AddHeaderValues(IList<string> target, IEnumerable<string> headerValues) {
foreach (string str in headerValues) {
target.Add(str);
}
}
}
CorsMessageHandler
以在错误响应中包含错误代码。public class MyCorsMessageHandler : CorsMessageHandler {
private HttpConfiguration _httpConfiguration;
public MyCorsMessageHandler(HttpConfiguration httpConfiguration) : base (httpConfiguration) {
_httpConfiguration = httpConfiguration;
}
public async override Task<HttpResponseMessage> HandleCorsPreflightRequestAsync(HttpRequestMessage request, CorsRequestContext corsRequestContext, CancellationToken cancellationToken) {
HttpResponseMessage message2;
if (request == null)
{
throw new ArgumentNullException("request");
}
if (corsRequestContext == null)
{
throw new ArgumentNullException("corsRequestContext");
}
try
{
new HttpMethod(corsRequestContext.AccessControlRequestMethod);
}
catch (ArgumentException)
{
return request.CreateErrorResponse(HttpStatusCode.BadRequest, "Access control request method cannot be null or empty");
}
catch (FormatException)
{
return request.CreateErrorResponse(HttpStatusCode.BadRequest, string.Format(CultureInfo.CurrentCulture, "Invalid access control request method: '{0}'", new object[] { corsRequestContext.AccessControlRequestMethod }));
}
CorsPolicy corsPolicy = await this.GetCorsPolicyAsync(request, cancellationToken);
if (corsPolicy != null)
{
MyCorsResult result;
HttpResponseMessage response = null;
if (this.TryEvaluateCorsPolicy(corsRequestContext, corsPolicy, out result))
{
response = request.CreateResponse(HttpStatusCode.OK);
response.WriteCorsHeaders(result);
}
else
{
if (result != null) {
if (result.ErrorCode > 0) {
var content = new {
code = result.ErrorCode,
message = result.ErrorMessages.FirstOrDefault()
};
response = new HttpResponseMessage(HttpStatusCode.BadRequest);
response.Content = new ObjectContent<dynamic>(content, new JsonMediaTypeFormatter(), "application/json");
}
else {
response = request.CreateErrorResponse(HttpStatusCode.BadRequest, string.Join(" | ", result.ErrorMessages));
}
}
else {
response = request.CreateResponse(HttpStatusCode.BadRequest);
}
}
message2 = response;
}
else
{
message2 = await base.SendAsync(request, cancellationToken);
}
return message2;
}
private async Task<CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request, CancellationToken cancellationToken) {
CorsPolicy corsPolicy = null;
ICorsPolicyProvider corsPolicyProvider = this._httpConfiguration.GetCorsPolicyProviderFactory().GetCorsPolicyProvider(request);
if (corsPolicyProvider == null) {
return corsPolicy;
}
return await corsPolicyProvider.GetCorsPolicyAsync(request, cancellationToken);
}
private bool TryEvaluateCorsPolicy(CorsRequestContext requestContext, CorsPolicy corsPolicy, out MyCorsResult corsResult) {
var engine = this._httpConfiguration.GetCorsEngine() as MyCorsEngine;
corsResult = engine.EvaluatePolicy(requestContext, corsPolicy);
return ((corsResult != null) && corsResult.IsValid);
}
}
config.SetCorsEngine(new MyCorsEngine());
config.MessageHandlers.Add(new MyCorsMessageHandler(config));
希望能帮助别人!