Netcore将服务连接到SSRS-CommunicationException

时间:2019-04-19 19:17:30

标签: c# wcf reporting-services asp.net-core-2.0

我正在尝试从远程SSRS服务器获取报告,但出现错误:

CommunicationException: The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.

我正在使用去年Previous Answer提供的以下答案中的代码。

有人能指出我为什么出现此错误的正确方向吗?我无法从研究中找到与SSRS相关的内容。我试图引入错误以获得某种响应,并且它总是在上面指出错误。我可以手动到达实时报表服务器并运行报表。

它在此点失败:var taskLoadReport = await reportClient.LoadReportAsync(trustedUserHeader, reportPath, historyID);,它只挂了15到20分钟左右。

错误的原始输出是:

System.ServiceModel.CommunicationException: The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.
   at System.Runtime.AsyncResult.End[TAsyncResult](IAsyncResult result)
   at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.End(SendAsyncResult result)
   at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
   at System.ServiceModel.Channels.ServiceChannelProxy.TaskCreator.<>c__DisplayClass1_0.<CreateGenericTask>b__0(IAsyncResult asyncResult)
--- End of stack trace from previous location where exception was thrown ---
   at IntechMappingApplication.Controllers.MappingReportController.RenderReport(String reportName, IDictionary`2 parameters, String languageCode, String exportFormat) in C:\Users\D\Dropbox\Intech\IntechMappingApplication\IntechMappingApplication\Controllers\MappingReportController.cs:line 70
   at IntechMappingApplication.Controllers.MappingReportController.GetPdfReport() in C:\Users\D\Dropbox\Intech\IntechMappingApplication\IntechMappingApplication\Controllers\MappingReportController.cs:line 28
   at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
   at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.MigrationsEndPointMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

代码是:

public async Task<IActionResult> GetPdfReport()
        {
            string reportname = "MainReport";
            IDictionary<string, object> parameters = new Dictionary<string, object>();
            //parameters.Add("ProjectUid", "");
            //parameters.Add("", "");
            //parameters.Add("", "");
            string languageCode = "en-us";

            byte[] reportContent = await this.RenderReport(reportname, parameters, languageCode, "PDF");

            Stream stream = new MemoryStream(reportContent);

            return new FileStreamResult(stream, "application/pdf");
        }

        private async Task<byte[]> RenderReport(string reportName, IDictionary<string, object> parameters, string languageCode, string exportFormat)
        {
            //
            // SSRS report path. Note: Need to include parent folder directory and report name.
            // Such as value = "/[report folder]/[report name]".
            //
            string reportPath = string.Format("{0}{1}", "/MappingReport/", reportName);

            //
            // Binding setup, since ASP.NET Core apps don't use a web.config file
            //
            var binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportCredentialOnly);
            binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
            binding.MaxReceivedMessageSize = 10485760; //It is 10MB size limit on response to allow for larger PDFs

            //Create the execution service SOAP Client
            ReportExecutionServiceSoapClient reportClient = new ReportExecutionServiceSoapClient(binding, new EndpointAddress("http://111.111.111.111/ReportServer"));

            //Setup access credentials. Here use windows credentials.
            var clientCredentials = new NetworkCredential("xxxx","xxxx","xxxx");
            reportClient.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
            reportClient.ClientCredentials.Windows.ClientCredential = clientCredentials;

            //This handles the problem of "Missing session identifier"
            reportClient.Endpoint.EndpointBehaviors.Add(new ReportingServicesEndpointBehavior());

            string historyID = null;
            TrustedUserHeader trustedUserHeader = new TrustedUserHeader();
            ExecutionHeader execHeader = new ExecutionHeader();

            trustedUserHeader.UserName = clientCredentials.UserName;

            //
            // Load the report
            //
            var taskLoadReport = await reportClient.LoadReportAsync(trustedUserHeader, reportPath, historyID);
            // Fixed the exception of "session identifier is missing".
            execHeader.ExecutionID = taskLoadReport.executionInfo.ExecutionID;

            //
            //Set the parameteres asked for by the report
            //
            ParameterValue[] reportParameters = null;
            if (parameters != null && parameters.Count > 0)
            {
                reportParameters = taskLoadReport.executionInfo.Parameters.Where(x => parameters.ContainsKey(x.Name)).Select(x => new ParameterValue() { Name = x.Name, Value = parameters[x.Name].ToString() }).ToArray();
            }

            await reportClient.SetExecutionParametersAsync(execHeader, trustedUserHeader, reportParameters, languageCode);
            // run the report
            const string deviceInfo = @"<DeviceInfo><Toolbar>False</Toolbar></DeviceInfo>";

            var response = await reportClient.RenderAsync(new RenderRequest(execHeader, trustedUserHeader, exportFormat ?? "PDF", deviceInfo));

            //spit out the result
            return response.Result;
        }

        internal class ReportingServicesEndpointBehavior : IEndpointBehavior
        {
            public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { }

            public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
            {
                clientRuntime.ClientMessageInspectors.Add(new ReportingServicesExecutionInspector());
            }

            public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { }

            public void Validate(ServiceEndpoint endpoint) { }
        }

        class ReportingServicesExecutionInspector : IClientMessageInspector
        {
            private MessageHeaders headers;

            public void AfterReceiveReply(ref Message reply, object correlationState)
            {
                var index = reply.Headers.FindHeader("ExecutionHeader", "http://schemas.microsoft.com/sqlserver/2005/06/30/reporting/reportingservices");
                if (index >= 0 && headers == null)
                {
                    headers = new MessageHeaders(MessageVersion.Soap11);
                    headers.CopyHeaderFrom(reply, reply.Headers.FindHeader("ExecutionHeader", "http://schemas.microsoft.com/sqlserver/2005/06/30/reporting/reportingservices"));
                }
            }

            public object BeforeSendRequest(ref Message request, IClientChannel channel)
            {
                if (headers != null)
                    request.Headers.CopyHeadersFrom(headers);

                return Guid.NewGuid(); //https://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.iclientmessageinspector.beforesendrequest(v=vs.110).aspx#Anchor_0
            }
        }

0 个答案:

没有答案