c# - 不断出现错误:无法访问 Asp.net Core 中间件上的已关闭流
问题描述
在阅读了 StackOverflow 中的几篇文章后,我已经避免using
并且没有关闭,Stream
但仍然不断收到错误消息:
无法访问已关闭的 Stream。
这是我为解密传入的有效负载并用解密的字符串asp.net core
覆盖而编写的中间件。HttpContext.Request.Body
public class DecryptMiddleware
{
private readonly RequestDelegate _next;
private X509Certificate2 cert;
public DecryptMiddleware(RequestDelegate next)
{
cert = new X509Certificate2(@"C:\Program Files\OpenSSL-Win64\bin\SandBox\07122020\my-cert.pfx", "xxxxxxxx");
_next = next;
}
public async Task InvokeAsync(HttpContext httpContext)
{
//body => stream
var encryptedRequestData = httpContext.Request.Body;
var encryptedAttributeData = string.Empty;
var decryptedResponseData = String.Empty;
if (httpContext.Request.Method == "POST")
{
//DeSerialize
var encryptedData = string.Empty;
StreamReader stream = null;
try
{
stream = new StreamReader(encryptedRequestData);
var body = await stream.ReadToEndAsync();
var request = JsonConvert.DeserializeObject<SecureTestClass>(body);
encryptedData = request.JData;
}
finally
{
if (stream != null) //I tried avoiding this code but still keep getting the error
{
stream.Close();
stream.Dispose();
}
}
//Decrypt
var rsa = (RSACng)cert.PrivateKey;
decryptedResponseData = Encoding.UTF8.GetString(
rsa.Decrypt(Convert.FromBase64String(encryptedData)
, RSAEncryptionPadding.Pkcs1)
);
httpContext.Request.Body = GenerateStreamFromString(decryptedResponseData);
}
await _next(httpContext);
await httpContext.Request.Body.DisposeAsync();
}
public static Stream GenerateStreamFromString(string s)
{
StreamWriter sw = null;
StreamReader sr = null;
MemoryStream ms = null;
try
{
ms = new MemoryStream();
sw = new StreamWriter(ms);
sr = new StreamReader(ms);
sw.WriteLine(s);
ms.Position = 0;
}
finally
{
if (sw != null) sw.Dispose();
if (sr != null) sr.Dispose();
}
return ms;
}
}
我得到的错误是:
{
"Message": "Cannot access a closed Stream.",
"Exception": "System.ObjectDisposedException: Cannot access a closed Stream.\r\n at System.IO.MemoryStream.Read(Byte[] buffer, Int32 offset, Int32 count)\r\n at System.IO.MemoryStream.ReadAsync(Memory`1 buffer, CancellationToken cancellationToken)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Text.Json.JsonSerializer.ReadAsync[TValue](Stream utf8Json, Type returnType, JsonSerializerOptions options, CancellationToken cancellationToken)\r\n at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonInputFormatter.ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)\r\n at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonInputFormatter.ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)\r\n at Microsoft.AspNetCore.Mvc.ModelBinding.Binders.BodyModelBinder.BindModelAsync(ModelBindingContext bindingContext)\r\n at Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder.BindModelAsync(ActionContext actionContext, IModelBinder modelBinder, IValueProvider valueProvider, ParameterDescriptor parameter, ModelMetadata metadata, Object value)\r\n at Microsoft.AspNetCore.Mvc.Controllers.ControllerBinderDelegateProvider.<>c__DisplayClass0_0.<<CreateBinderDelegate>g__Bind|0>d.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)\r\n at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)\r\n at BankServiceListener.Middleware.DecryptMiddleware.InvokeAsync(HttpContext httpContext) in C:\\Projects\\GIT\\JKSB\\BankServiceListener\\BankServiceListener\\Middleware\\DecryptionMiddleware.cs:line 69\r\n at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)\r\n at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)\r\n at BankServiceListener.Middleware.DeveloperExceptionMiddleware.InvokeAsync(HttpContext httpContext) in C:\\Projects\\GIT\\JKSB\\BankServiceListener\\BankServiceListener\\Middleware\\DeveloperExceptionMiddleware.cs:line 27",
"StackTrace": " at System.IO.MemoryStream.Read(Byte[] buffer, Int32 offset, Int32 count)\r\n at System.IO.MemoryStream.ReadAsync(Memory`1 buffer, CancellationToken cancellationToken)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Text.Json.JsonSerializer.ReadAsync[TValue](Stream utf8Json, Type returnType, JsonSerializerOptions options, CancellationToken cancellationToken)\r\n at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonInputFormatter.ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)\r\n at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonInputFormatter.ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)\r\n at Microsoft.AspNetCore.Mvc.ModelBinding.Binders.BodyModelBinder.BindModelAsync(ModelBindingContext bindingContext)\r\n at Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder.BindModelAsync(ActionContext actionContext, IModelBinder modelBinder, IValueProvider valueProvider, ParameterDescriptor parameter, ModelMetadata metadata, Object value)\r\n at Microsoft.AspNetCore.Mvc.Controllers.ControllerBinderDelegateProvider.<>c__DisplayClass0_0.<<CreateBinderDelegate>g__Bind|0>d.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)\r\n at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)\r\n at BankServiceListener.Middleware.DecryptMiddleware.InvokeAsync(HttpContext httpContext) in C:\\Projects\\GIT\\JKSB\\BankServiceListener\\BankServiceListener\\Middleware\\DecryptionMiddleware.cs:line 69\r\n at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)\r\n at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)\r\n at BankServiceListener.Middleware.DeveloperExceptionMiddleware.InvokeAsync(HttpContext httpContext) in C:\\Projects\\GIT\\JKSB\\BankServiceListener\\BankServiceListener\\Middleware\\DeveloperExceptionMiddleware.cs:line 27",
"Source": "System.Private.CoreLib"
}
我在这里做错了吗?想不通。
解决方案
似乎您正在处理 StreamWriter sw,而后者又将处理传递给它的内存流
尝试使用这个
public static Stream GenerateStreamFromString(string s)
{
var ms = new MemoryStream(Encoding.Default.GetBytes(s));
return ms;
}
推荐阅读
- android - 数据发生变化时如何测试 MutableLiveData<>.observe?
- jquery - Tomcat - 使用正确的 JSESSIONID 进行 AJAX 调用
- sql - 当其他表中的日期比今天更早时更新列
- c# - 使用图形 API 从 Asp.net C# 访问 facebook 好友列表
- php - 将 MS Office 与 PHP 和 SQLServer 文件表集成
- spring-boot-actuator - 如何配置 spring boot admin 以传递额外的 headers
- haskell - 如果达到内存限制,则中止评估 Haskell 表达式
- spring - 晚上好,我无法解决这个问题请给一些想法
- android - Android Room:以 SQLite 格式保存和导出数据库
- kotlin - 如何在kotlin中实现序列的并行映射