我正在尝试从远程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
}
}