RadzenSSRSViewer: Authentication failed because the connection could not be reused

(I do understand that this may not be a supported situation but I thought I would ask)

If I create a fully working application, that connects to a password protected .rdl report in a SSRS server, using the Radzen Blazor application builder it works!

If I take the following code from that project:

image

...and put it in my project (that has all the same .net version, project settings, startup.cs, and program.cs, and nuget packages):

image

and use this tag on a .razor page:

<RadzenSSRSViewer ReportName="reports/FYIS_Transcipt" 
                  ReportServer="https://{{MY SERVER}}/ReportServer" 
                  style="height: 400px" 
                  UseProxy="true">
</RadzenSSRSViewer>

I get the following error:

image

System.Net.Http.HttpRequestException: Authentication failed because the connection could not be reused.
   at System.Net.Http.HttpConnection.DrainResponseAsync(HttpResponseMessage response)
   at System.Net.Http.AuthenticationHelper.SendWithNtAuthAsync(HttpRequestMessage request, Uri authUri, ICredentials credentials, Boolean isProxyAuth, HttpConnection connection, HttpConnectionPool connectionPool, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithNtConnectionAuthAsync(HttpConnection connection, HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.AuthenticationHelper.SendWithAuthAsync(HttpRequestMessage request, Uri authUri, ICredentials credentials, Boolean preAuthenticate, Boolean isProxyAuth, Boolean doRequestAuth, HttpConnectionPool pool, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.DecompressionHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
   at RadzenClientSsrs.Controllers.ReportController.ForwardRequest(HttpClient httpClient, HttpRequest currentReqest, String url) in C:\Users\Michael\Documents\Visual Studio 2019\Projects\RadzenSSRSTest\Controllers\ReportController.cs:line 129
   at RadzenClientSsrs.Controllers.ReportController.Get(String url) in C:\Users\Michael\Documents\Visual Studio 2019\Projects\RadzenSSRSTest\Controllers\ReportController.cs:line 25
   at lambda_method(Closure , Object )
   at Microsoft.Extensions.Internal.ObjectMethodExecutorAwaitable.Awaiter.GetResult()
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   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__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

I can provide my project if you want to look at it.

Again, I do understand if this is not a supported situation. However, I would be willing to Blog on this! :slight_smile:

Thank You

We have no idea what is causing that exception (also searching online doesn't bring up anything useful). However if you are positive that everything works in a Radzen Blazor application you can compare the Startup.cs with yours. Maybe some of the configurations there mitigate that error.

Understood, thanks.

This one is so weird, because the Radzen application builder creates a "normal .net Core project" so I am able to "open it up" and compare it "side-by-side" to a new project.

But, one works and the other doesn't :frowning:

If anyone else runs into this, a friend was able to find the answer.

In the ForwardRequest method in the ReportController.cs file, add this line before the return statement at the end of the method:

AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false);

2 Likes

It didn't work out for me.

    async Task<HttpResponseMessage> ForwardRequest(HttpClient httpClient, HttpRequest currentReqest, string url)
    {
        var proxyRequestMessage = new HttpRequestMessage(new HttpMethod(currentReqest.Method), url);

        foreach (var header in currentReqest.Headers)
        {
            if (header.Key != "Host")
            {
                proxyRequestMessage.Headers.TryAddWithoutValidation(header.Key, new string[] { header.Value });
            }
        }

        this.OnReportRequest(ref proxyRequestMessage);

        if (currentReqest.Method == "POST")
        {
            using (var stream = new MemoryStream())
            {
                await currentReqest.Body.CopyToAsync(stream);
                stream.Position = 0;

                string body = new StreamReader(stream).ReadToEnd();
                proxyRequestMessage.Content = new StringContent(body);

                if (body.IndexOf("AjaxScriptManager") != -1)
                {
                    proxyRequestMessage.Content.Headers.Remove("Content-Type");
                    proxyRequestMessage.Content.Headers.Add("Content-Type", new string[] { currentReqest.ContentType });
                }
            }
        }

        AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false);

        return await httpClient.SendAsync(proxyRequestMessage);
    }

@licitec
Does it work when you use the Radzen application creator?

This is important because in my situation I had a report that worked perfectly with the Radzen application creator - it just did not work when I called it in a normal Visual Studio project.

Yes. It occurs when the feature is used in a normal Visual Studio project, outside of Radzen

Is there a solution?

@licitec I think you first need to show that your reports works when using the Radzen application. Only then can you show the code it creates and see what the issue is.

OK. I will run some more tests. Thank you.

I'm having the same problem with a angular aplication, the weirdest thing is that it only happens on some pcs , not all, on others it works well. Needless to saying that I am also using a proxy or the radzen viewer in angular. What version of .net core are all you using?

I am using .Net Core 3.1 (with Blazor)

Also .Net Core 3.1 (but Angular)

Hi,

Your solution worked perfectly with .net core 3.1 but not with .net 5. Fo you by any chance have a solution for .net 5?

As noted in official Microsoft documentation:

In .NET 5 we recommend using RequestHeaderEncodingSelector.

UPDATE: My mistake - this is related to AllowLatin1Headers

In my initial testing, when using .NET 5 this works against SSRS 2016 (Version 13.0.1601.5), but it does not work against SSRS 2017 (Version 14.0.600.1572) or SSRS 2019 (Version 15.0.1102.861).

For SSRS 2017 (Version 14.0.600.1572) or SSRS 2019 (Version 15.0.1102.861), see this forum thread:

Passing Authentication to SSRS Report Viewer (.Net 5) - Radzen IDE (Blazor server-side) - Radzen

As suggested here:

modifying the generated code to use WinHttpHandler rather than HttpClientHandler worked for me.
I also had to turn off using the default credentials, add a new Network Credential to the handler.

            var httpClientHandler = new WinHttpHandler()
			{
                AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate,
                AutomaticRedirection = true,
                ServerCredentials = new NetworkCredential("myUser", "myPassword, "myDomain")
            };
1 Like