C# HTTP状态代码500、.net核心CORS和HttpClient错误
我在dotnetcore中遇到了一些关于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
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无法处理大量的连接?