C# HTTP状态代码500、.net核心CORS和HttpClient错误

C# HTTP状态代码500、.net核心CORS和HttpClient错误,c#,ajax,asp.net-core,httpclient,C#,Ajax,Asp.net Core,Httpclient,我在dotnetcore中遇到了一些关于CORS/HttpClient的问题。首先,我的应用程序的结构如下: Webapp -> Microservice-Gateway -> multiple Microservices 如果我从我的Webapp执行Ajax调用 $.ajax({ url: "https://[actual gateway Url]/customer/" + customerId, type: "GET", time

我在dotnetcore中遇到了一些关于CORS/HttpClient的问题。首先,我的应用程序的结构如下:

Webapp -> Microservice-Gateway -> multiple Microservices
如果我从我的Webapp执行Ajax调用

$.ajax({
        url: "https://[actual gateway Url]/customer/" + customerId,
        type: "GET",
        timeout: 60000,
        crossDomain: true,
        dataType: "json",
        success: data => {
            //...
        }
    });
到网关服务器,我有时会收到以下错误消息:

请求的服务器上不存在“Access Control Allow Origin”标头 资源。因此,不允许使用源“” 通道响应的HTTP状态代码为500

但是,如果我调试,我的网关会在内部引发此错误:

System.Net.Http.HttpRequestException:发送时出错 请求。-->System.Net.Http.WinHttpException:操作 超时

我试图通过在网关和每个微服务中添加以下代码来解决第一个错误:

public void ConfigureServices(IServiceCollection services) {
        var corsBuilder = new CorsPolicyBuilder();
        corsBuilder.AllowAnyHeader();
        corsBuilder.AllowAnyMethod();
        corsBuilder.AllowAnyOrigin();
        corsBuilder.AllowCredentials();

        services.AddCors(options => {
            options.AddPolicy("SiteCorsPolicy", corsBuilder.Build());
        });
 //..
 }
 public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
        app.UseCors("SiteCorsPolicy");
 //..
 }
为了确定,我还加了一句

[EnableCors("SiteCorsPolicy")]
给每个控制器。 我试图解决的第二个问题是在网关中创建一个HttpClient作为Singleton并修改以下属性:

var client = new HttpClient();
client.Timeout = new TimeSpan(0, 10, 0);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
services.AddSingleton(client);
我的网关发送如下HTTP请求:

[HttpGet("{id}")]
public async Task<JsonResult> GetById(int id) {
    var response = await _client.GetAsync(new Uri(ServiceUrls.Customer + $"{id}"));

    if (!response.IsSuccessStatusCode)
        return new JsonResult(BadRequest($"{(int)response.StatusCode}: {response.ReasonPhrase}"));

    var customer = JsonConvert.DeserializeObject<CustomerViewModel>(await response.Content.ReadAsStringAsync());
    return new JsonResult(customer);
}
[HttpGet(“{id}”)]
公共异步任务GetById(int id){
var response=wait_client.GetAsync(新Uri(serviceURL.Customer+$“{id}”);
如果(!response.issucessStatusCode)
返回新的JsonResult(BadRequest($“{(int)response.StatusCode}:{response.ReasonPhrase}”);
var customer=JsonConvert.DeserializeObject(wait response.Content.ReadAsStringAsync());
返回新的JsonResult(客户);
}
正如我所说,有时有效,有时无效。也许你能给我一些想法我犯了什么错。提前谢谢


编辑:如果一次有多个来自Webapp的异步ajax调用,那么问题似乎会更频繁地出现。但这也可能只是一种感觉。

这可能与您的CORS设置无关。当发生错误时(例如使用
HttpClient
的HTTP调用),默认异常处理程序中间件将删除所有响应头并返回错误响应。这意味着您的策略添加的任何CORS头都将被删除,因此您将收到关于“请求的资源上不存在“Access Control Allow Origin”头的错误。”

为了克服这个问题,您应该自己处理控制器中的任何异常,并返回相应的错误结果,或者在之前编写中间件,或者用您自己的异常处理逻辑替换默认的异常中间件

关于这种行为还有一个公开的GitHub问题:。

好的,伙计们

谢谢你帮我找到了正确的方向。我想我找到了一个解决方法。我必须在网关中设置以下属性:

ServicePointManager.DefaultConnectionLimit = int.MaxValue;

我也遇到过这个问题,.NETCore2.0不会在非200或非300响应上返回http状态码。我通过创建middlewear来修复它,它可以参与创建发送回客户机的响应

您可以在此处查看所有步骤:

能否在Simon分享您在何处定义了“SiteCorsPolicy”策略?“options.AddPolicy(“SiteCorsPolicy”,corsBuilder.Build());”在第五个代码段中,问题是500错误,这与您的CORS配置无关。只是和大多数服务器一样,这台服务器只将Access Control Allow Origin和其他自定义配置的响应头添加到2xx成功消息中,而不是添加到5xx和4xx错误中。谢谢@sideshowbarker!这就把范围缩小到了HttpClient。我已经多次读到HttpClient是线程安全的,这是错的吗?我真的想不出它失败的另一个原因。这似乎是关于HttpClient线程安全的标准答案。谢谢,我明白了。但是,“System.Net.Http.WinHttpException:操作超时”毫无意义。我将超时时间增加到10分钟,我在大约30秒内得到了这些异常。也许原因是红隼不能同时处理30-50个请求。但我真的不相信。我忘了提到服务器是固定的。也许docker无法处理大量的连接?