ASP.NET Web API:处理来源不允许的消息

ASP.NET Web API: Handling origin not allowed message

我正在我的 ASP.NET Web API 项目中启用 CORS,并且一切都按预期工作。不过,我想在提供无效来源时覆盖默认错误消息。现在我收到一条默认错误消息:

{"Message":"The origin 'http://xyz' is not allowed."}

我想要return这样的东西:

{"Code": 1000, "Message":"The origin 'http://xyz' is not allowed."}

我正在通过自定义策略启用 CORS:

config.SetCorsPolicyProviderFactory(new MyCorsPolicyProviderFactory());
config.EnableCors();

错误信息是在哪里定义的?任何帮助,将不胜感激。谢谢。

我能够通过执行类似于以下的操作来完成此操作:

  1. 编写自定义 CorsResult 来存储错误代码。
public class MyCorsResult : CorsResult {
    public ErrorCode ErrorCode { get; set; }

    public new bool IsValid {
        get {
            return base.IsValid && ErrorCode == default(int);
        }
    }

}
  1. 编写自定义 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);
        }
    }
}
  1. 编写自定义 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);
    }

}
  1. 终于全部注册了。
config.SetCorsEngine(new MyCorsEngine());
config.MessageHandlers.Add(new MyCorsMessageHandler(config));

希望对某人有所帮助!