【问题标题】:System.InvalidOperationException: Timeouts are not supported on this stream. at System.IO.Stream.get_ReadTimeout()System.InvalidOperationException:此流不支持超时。在 System.IO.Stream.get_ReadTimeout()
【发布时间】:2021-03-31 19:17:45
【问题描述】:

我有一个运行良好的 asp.net web api 核心控制器,它执行所有行并且永远不会到达 catch 块。

它还会添加和更新 CosmosDB 上的记录。 我逐行调试它,然后我删除了所有在 ComosDB 上也验证过的断点,一切都是正确的。

但是,当我从 Postmann 调用端点时,我收到此错误:

如您所见,调用堆栈没有我的任何代码:

System.InvalidOperationException: Timeouts are not supported on this stream.
   at System.IO.Stream.get_ReadTimeout()
   at System.Text.Json.JsonPropertyInfo`1.GetMemberAndWriteJson(Object obj, WriteStack& state, Utf8JsonWriter writer)
   at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryWrite(Utf8JsonWriter writer, T value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.JsonPropertyInfo`1.GetMemberAndWriteJson(Object obj, WriteStack& state, Utf8JsonWriter writer)
   at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryWrite(Utf8JsonWriter writer, T value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.JsonPropertyInfo`1.GetMemberAndWriteJson(Object obj, WriteStack& state, Utf8JsonWriter writer)
   at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryWrite(Utf8JsonWriter writer, T value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.JsonConverter`1.WriteCore(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.Serialization.JsonConverter`1.WriteCoreAsObject(Utf8JsonWriter writer, Object value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.JsonSerializer.WriteCore[TValue](JsonConverter jsonConverter, Utf8JsonWriter writer, TValue& value, JsonSerializerOptions options, WriteStack& state)
   at System.Text.Json.JsonSerializer.WriteAsyncCore[TValue](Stream utf8Json, TValue value, Type inputType, JsonSerializerOptions options, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
   at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeResultAsync>g__Logged|21_0(ResourceInvoker invoker, IActionResult result)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResultFilterAsync>g__Awaited|29_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

我的控制器:

 /// <summary>
        /// Adds global design tenant
        /// </summary>
        /// <param name="globaldesigntenant">Global Design Tenant</param>
        /// <returns>OK if no errors</returns>
        [HttpPost]
        public  async Task<ActionResult> AddGlobalDesignTenant([FromForm]GlobalDesignTenant globaldesigntenant)
        {
            this.telemetry.TrackEvent("AddGlobalDesignTenant");
            try
            {
                /*if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState);
                }*/

                byte[] data = Convert.FromBase64String(globaldesigntenant.CertPfxFile);

                // Converts the base 64 encoded cert to an X509Certicate instannce
                var cert = new X509Certificate2(
                    data,
                    globaldesigntenant.CertificatePassword,
                    X509KeyStorageFlags.Exportable |
                    X509KeyStorageFlags.MachineKeySet |
                    X509KeyStorageFlags.PersistKeySet);

            
                var authManager = new AuthenticationManager(globaldesigntenant.AzureApplicationId, 
                                            cert,
                                            globaldesigntenant.TenantId);

                using (var context = authManager.GetContext(globaldesigntenant.TestSiteCollectionUrl))
                {
                    context.Load(context.Web, p => p.Title);
                    context.ExecuteQuery();
                };

                //No exceptions here, it means the certificate and password are valid.

                string certName = "GlobalDesignTenantPFXFileBase64-"+globaldesigntenant.TenantId;
                string secretName = "GlobalDesignTenantCertPassword-"+globaldesigntenant.TenantId;

                /// Adding the certificate password to the key vault
                await _secretClient.SetSecretAsync(secretName, globaldesigntenant.CertificatePassword);

                 //Adding the certificate to keyvault (base 64 encoded)
                await _secretClient.SetSecretAsync(certName, globaldesigntenant.CertPfxFile);

                var added = await _globalDesignTenantCosmosStore.AddAsync(globaldesigntenant);

                // These secrets are saved in KeyVault, not in CosmosDB.
                added.Entity.CertificatePassword = string.Empty;
                added.Entity.CertPfxFile = string.Empty;

                var result = await _globalDesignTenantCosmosStore.UpdateAsync(added);

                return Ok(result);
            }
            catch (Exception ex)
            {
                string guid = Guid.NewGuid().ToString();
                var dt = new Dictionary<string, string>
                {
                    { "Error Lulo: ", guid }
                };

                telemetry.TrackException(ex, dt);
                return BadRequest("Error Lulo: " + guid);
            }             
        }

【问题讨论】:

    标签: c# asp.net-core asp.net-web-api asp.net-web-api2 asp.net-core-webapi


    【解决方案1】:

    它看起来像是在默认中间件中完成的输出序列化过程中抛出的。不确定这是否是 System.Text.Json 序列化程序中的错误,因为它不应该尝试获取响应流的超时,或者是否某些其他中间件导致流的超时不可读。您可以尝试使用 newtonsoft json formatter 中间件来测试理论吗?

    为此,添加包:Microsoft.AspNetCore.Mvc.NewtonsoftJson 并在 ConfigureServices 中:

    // replace
    services.AddControllers();
    // with
    services.AddControllers().AddNewtonsoftJson();
    

    如果这没有帮助,也许添加一些自定义中间件可能会有所帮助。在这个中间件中,您可以将 http 上下文的输出流替换为您可以控制的流,然后再将其放回原处。

    【讨论】:

      【解决方案2】:

      这可能与您的邮递员请求标头有关,但我并不指望它。如果是服务器的序列化错误,您可以将结果转换为 JSON 对象

      return Ok(JObject.fromObject(result)); //with newtonsoft
      

      看看这是否能确保序列化或给出更详细的错误。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-11
        • 2014-06-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多