System.InvalidOperationException。在提交请求后,此操作不能执行。

问题描述 投票:1回答:2

这个问题可能已经被问过很多次了,但他们都没有 解决办法 真的很有帮助。

我正在使用OneSignal向所有连接的客户端发送推送通知。我在一个服务中实现了代码,并使其成为一个Singleton。

我想要的是 我的用例是,我想向一个用户发送一个通知,并立即向另一个用户发送一个不同的通知。

问题是 它只在第一次请求时有效,之后,我一直收到这个错误。

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
            }
        }

    }
c# asp.net asp.net-mvc asp.net-core onesignal
2个回答
1
投票

据我所知,Singleton是指应用程序的每个后续请求都使用同一个实例。

这意味着所有的两个请求都使用相同的 HttpWebRequest.

由于你的SendNotificationAsync是async方法。如果你在同一时间调用这个方法两次。它将使用相同的 HttpWebRequest(request) 来发送请求。

这个错误告诉你,第一个 HttpWebRequest(request) 提交,但没有完整执行,我们无法提交 HttpWebRequest(request) 再次。

在我看来,你应该将服务注册为 Transient,因为我们每个人都不能重复使用。HttpWebRequest(request) .


1
投票

我最终使用了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

            }
        }
© www.soinside.com 2019 - 2024. All rights reserved.