System.InvalidOperationException: 请求提交后无法执行此操作
System.InvalidOperationException: This operation cannot be performed after the request has been submitted
这个问题可能已被问过多次,但他们 solution 中的 none 真的很有帮助。
我正在使用 OneSignal 向所有连接的客户端发送推送通知。我在一个服务中实现了代码并使它成为一个单例。
我想要的
我的用例是我想向用户发送通知,并立即向另一个用户发送不同的通知。
问题
它仅适用于第一个请求,之后,我不断收到此错误:
System.InvalidOperationException: This operation cannot be performed after the request has been submitted.
at System.Net.HttpWebRequest.InternalGetRequestStream()
at System.Net.HttpWebRequest.GetRequestStream()
at BingoAPI.Services.NotificationService.SendNotificationAsync(Byte[] buffer) in D:\Bingo\BingoAPI\Services\NotificationService.cs:line 74
实现如下:
public NotificationService(IOptions<OneSignalNotificationSettigs> oneSignalSettings, IOptions<NotificationTemplates> notificationTemplates)
{
this.oneSignalSettings = oneSignalSettings;
this.notificationTemplates = notificationTemplates;
// request configuration
request = WebRequest.Create(oneSignalSettings.Value.EndPoint) as HttpWebRequest;
request.Headers.Add("authorization", oneSignalSettings.Value.Authorization);
request.KeepAlive = true;
request.Method = "POST";
request.ContentType = "application/json; charset=utf-8";
}
private async Task SendNotificationAsync(byte[] buffer)
{
string responseContent = null;
try
{
// here is the error
var writer = await request.GetRequestStreamAsync();
await writer.WriteAsync(buffer, 0, buffer.Length);
writer.Close();
var response = await request.GetResponseAsync() as HttpWebResponse;
var reader = new StreamReader(response.GetResponseStream());
responseContent = await reader.ReadToEndAsync();
}
catch (WebException ex)
{
// LOGGING
}
}
}
据我所知,单例是指应用程序的每个后续请求都使用相同的实例。
这意味着所有两个请求都使用相同的HttpWebRequest
。
因为您的 SendNotificationAsync 是异步方法。如果你同时调用这个方法两次。它将使用相同的 HttpWebRequest(request)
来发送请求。
报错告诉你第一个HttpWebRequest(request)
已经提交但没有执行完成,我们无法再次提交HttpWebRequest(request)
。
在我看来,您应该将服务注册为 Transient
,因为我们不能重复使用 HttpWebRequest(request)
。
我最终使用了 HttpClientFactory 而不是 HttpWebRequest,尽管我可以使它成为瞬态的。但从长远来看,这对我来说似乎不是一个解决方案 运行 因为每个请求都必须重新初始化很多额外的东西。而且代码更少。
public NotificationService(IOptions<OneSignalNotificationSettigs> oneSignalSettings, IOptions<NotificationTemplates> notificationTemplates,
IHttpClientFactory clientFactory)
{
this.oneSignalSettings = oneSignalSettings;
this.notificationTemplates = notificationTemplates;
// request configuration
httpClient = clientFactory.CreateClient();
httpClient.DefaultRequestHeaders.Add("authorization", oneSignalSettings.Value.Authorization);
request = new HttpRequestMessage(HttpMethod.Post, oneSignalSettings.Value.EndPoint);
}
private async Task SerializeNotificationAsync(Object obj)
{
var param = JsonConvert.SerializeObject(obj);
var data = new StringContent(param, Encoding.UTF8, "application/json");
await SendNotificationAsync(data);
}
private async Task SendNotificationAsync(StringContent buffer)
{
var response = await httpClient.PostAsync(request.RequestUri, buffer);
if (!response.IsSuccessStatusCode)
{
// logg error
}
}
这个问题可能已被问过多次,但他们 solution 中的 none 真的很有帮助。
我正在使用 OneSignal 向所有连接的客户端发送推送通知。我在一个服务中实现了代码并使它成为一个单例。
我想要的
我的用例是我想向用户发送通知,并立即向另一个用户发送不同的通知。
问题
它仅适用于第一个请求,之后,我不断收到此错误:
System.InvalidOperationException: This operation cannot be performed after the request has been submitted.
at System.Net.HttpWebRequest.InternalGetRequestStream()
at System.Net.HttpWebRequest.GetRequestStream()
at BingoAPI.Services.NotificationService.SendNotificationAsync(Byte[] buffer) in D:\Bingo\BingoAPI\Services\NotificationService.cs:line 74
实现如下:
public NotificationService(IOptions<OneSignalNotificationSettigs> oneSignalSettings, IOptions<NotificationTemplates> notificationTemplates)
{
this.oneSignalSettings = oneSignalSettings;
this.notificationTemplates = notificationTemplates;
// request configuration
request = WebRequest.Create(oneSignalSettings.Value.EndPoint) as HttpWebRequest;
request.Headers.Add("authorization", oneSignalSettings.Value.Authorization);
request.KeepAlive = true;
request.Method = "POST";
request.ContentType = "application/json; charset=utf-8";
}
private async Task SendNotificationAsync(byte[] buffer)
{
string responseContent = null;
try
{
// here is the error
var writer = await request.GetRequestStreamAsync();
await writer.WriteAsync(buffer, 0, buffer.Length);
writer.Close();
var response = await request.GetResponseAsync() as HttpWebResponse;
var reader = new StreamReader(response.GetResponseStream());
responseContent = await reader.ReadToEndAsync();
}
catch (WebException ex)
{
// LOGGING
}
}
}
据我所知,单例是指应用程序的每个后续请求都使用相同的实例。
这意味着所有两个请求都使用相同的HttpWebRequest
。
因为您的 SendNotificationAsync 是异步方法。如果你同时调用这个方法两次。它将使用相同的 HttpWebRequest(request)
来发送请求。
报错告诉你第一个HttpWebRequest(request)
已经提交但没有执行完成,我们无法再次提交HttpWebRequest(request)
。
在我看来,您应该将服务注册为 Transient
,因为我们不能重复使用 HttpWebRequest(request)
。
我最终使用了 HttpClientFactory 而不是 HttpWebRequest,尽管我可以使它成为瞬态的。但从长远来看,这对我来说似乎不是一个解决方案 运行 因为每个请求都必须重新初始化很多额外的东西。而且代码更少。
public NotificationService(IOptions<OneSignalNotificationSettigs> oneSignalSettings, IOptions<NotificationTemplates> notificationTemplates,
IHttpClientFactory clientFactory)
{
this.oneSignalSettings = oneSignalSettings;
this.notificationTemplates = notificationTemplates;
// request configuration
httpClient = clientFactory.CreateClient();
httpClient.DefaultRequestHeaders.Add("authorization", oneSignalSettings.Value.Authorization);
request = new HttpRequestMessage(HttpMethod.Post, oneSignalSettings.Value.EndPoint);
}
private async Task SerializeNotificationAsync(Object obj)
{
var param = JsonConvert.SerializeObject(obj);
var data = new StringContent(param, Encoding.UTF8, "application/json");
await SendNotificationAsync(data);
}
private async Task SendNotificationAsync(StringContent buffer)
{
var response = await httpClient.PostAsync(request.RequestUri, buffer);
if (!response.IsSuccessStatusCode)
{
// logg error
}
}