Создание отчета FastReport несколько источников данных, группировки
Делаю отчет в FastReport по аналогии со статьей в Академии.
https://academy.terrasoft.ru/documents/technic-sdk/7-16/primer-nastroyki-otcheta
Но мне для отчета нужны несколько источников данных и во многих несколько уровней группировки данных.
Источники данных.
{
"ProviderName": "MortgageConclusionDataProvider",
"Schemas": {
"MortgageConclusionData": {
"GroupName": {"DataValueType": 1},
"Account": {"DataValueType": 1},
"PreparationDate": {"DataValueType": 7},
"ConclusionType": {"DataValueType": 1}
},
"LevelSecurityData": {
"MortgageConclusion": {"DataValueType": 0},
"SublimitTypes": {"DataValueType": 0},
"NameSublimitTypes": {"DataValueType": 1},
"Groupe": {"DataValueType": 1},
"TargetUse": {"DataValueType": 1},
"AmountLimit": {"DataValueType": 5}
},
"LocalizableStrings": {
"ReportTitle": {"DataValueType": 1},
...
}
}
}
В сервисе прописываю логику:
public Task GetData(UserConnection userConnection, IReadOnlyDictionary parameters) {
var filter = ExtractFilterFromParameters(userConnection, _entitySchemaUId, parameters);
var result = new ReportDataDictionary {
// Заполнить колонки в отчете.
["MortgageConclusionData"] = GetMortgageConclusionData(userConnection, _entitySchemaUId, filter),
["LevelSecurityData"] = GetLevelSecurityData(userConnection, _entityLevelSecuritySchemaUId),
["LocalizableStrings"] = GetLocalizableStrings(userConnection)
};
return Task.FromResult(result);
}И при формировании отчета ошибка
Error while sending request
response status: 500 (Internal Server Error)
request url: ...FastReportService/CreateReport
method: POST
request data: {"reportTemplateId":"a1c1f160-a7c2-56a0-edcb-1101dde5a74e","reportCaption":"Заключение","reportSchemaName":"MortgageConclusion","report...
Через Profiler запросы сформировались, данные есть.
Хотелось бы хоть один рабочий пример увидеть, где несколько источников и есть иерархия...
Спасибо!
Нравится
Судя по сообщению из логов, второе исключение происходит в схеме FastReportService, в функции:
[Obsolete("7.15.3")]
[OperationContract]
[WebGet(UriTemplate = "GetReportFile/{key}")]
public Stream GetReportFile(string key) {
var data = PopFromSessionData(key);
string contentDisposition = "attachment; filename*=UTF-8''" + data.Key;
var reportStream = new MemoryStream(data.Value);
WebResponseProcessor.AssignFileResponseContent(HttpContextAccessor.GetInstance(), "application/pdf; charset=UTF-8", reportStream.Length, contentDisposition);
return reportStream;
}
private KeyValuePair<string, byte[]> PopFromSessionData(string sessionKey) {
var data = (KeyValuePair<string, byte[]>)UserConnection.SessionData[sessionKey];
UserConnection.SessionData.Remove(sessionKey);
return data;
}То есть падает не внутри Вашего кода отчёта, а при попытке скачать с сервера файл отчёта, вместо него пусто. Отчёт перед этим уже должен был создаться в CreateReport, а в ней происходит первое исключение. Но в этой функции любые ошибки обрабатывает общий блок try:
[Obsolete("7.15.3")]
[OperationContract]
[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
public string CreateReport(Guid reportTemplateId, string reportCaption, string reportSchemaName, string reportFilters) {
try {
var reportParameters = new Dictionary<string, object> {
["EsqFilters"] = new Dictionary<string, Filters> {
[reportSchemaName] = JsonConvert.DeserializeObject<Filters>(reportFilters)
}
};
var reportBytes = InternalCreateReport(reportTemplateId, reportParameters);
return PushToSessionData(new KeyValuePair<string, byte[]>($"{HttpUtility.UrlPathEncode(reportCaption)}.pdf", reportBytes));
} catch (Exception exception) {
throw new WebFaultException<FastReportGenerationException>(
new FastReportGenerationException(exception),
HttpStatusCode.InternalServerError);
}
}Получается, чтобы увидеть, где именно упало при генерации отчёта, нужно для теста убрать этот try, чтобы видеть дальнейший стек вызовов и настоящую ошибку.
А у Вас response status: 500 только на конкретном отчёте, который разрабатываете, на остальных нормально?
По поводу примеров, кроме описанного в академии, в системе есть ещё стандартные «Знаменательные события контакта» и «Полнота наполнения данными». В первом — несколько источников и схема ContactAnniversariesReportDataProvider, в ней интересующая Вас функция:
public Task<ReportDataDictionary> GetData(UserConnection userConnection,
IReadOnlyDictionary<string, object> parameters) {
var contactFilter = ExtractFilterFromParameters(userConnection, _contactEntitySchemaUId, parameters);
var result = new ReportDataDictionary {
["Contact"] = GetContactData(userConnection, _contactEntitySchemaUId, contactFilter),
["ContactAnniversary"] = GetContactAnniversaryData(userConnection, _contactAnniversaryEntitySchemaUId,
contactFilter),
["LocalizableStrings"] = GetLocalizableStrings(userConnection)
};
return Task.FromResult(result);
}Но обратите внимание, выше в коде есть сами функции GetContactData и GetContactAnniversaryData, получающие из базы коллекцию данных с указанным фильтром.
Елена, ошибка 500 происходит на сервере, то есть в логах должна быть более подробная информация, где именно в коде она возникает.
Зверев Александр,
2020-08-05 18:06:11,849 [192] ERROR Terrasoft.Web.Common.ServiceModel.ErrorHandler ProvideFault - Internal Server Error
System.ServiceModel.Web.WebFaultException`1[Terrasoft.Configuration.Reporting.FastReport.FastReportGenerationException]: Internal Server Error (Дополнительные сведения об ошибке — Terrasoft.Configuration.Reporting.FastReport.FastReportGenerationException: Error during report generation).
2020-08-05 18:06:11,864 [192] ERROR Terrasoft.WebApp.FileWebEventProvider RaiseInternal - Date: 05.08.2020 18:06:11
Date (UTC): 05.08.2020 15:06:11
Exception Message: Internal Server Error
Exception Type: System.ServiceModel.Web.WebFaultException`1[Terrasoft.Configuration.Reporting.FastReport.FastReportGenerationException]
Exception Source: Terrasoft.Configuration
Exception Stack Trace:
в Terrasoft.Configuration.Reporting.FastReport.FastReportService.CreateReport(Guid reportTemplateId, String reportCaption, String reportSchemaName, String reportFilters)
в SyncInvokeCreateReport(Object , Object[] , Object[] )
в System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
в System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
в System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
в System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc)
в System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
SessionID: xxiqbf2pqlqi4uvge2vbjffb
Request URL: /0/rest/FastReportService/CreateReport
Request Path: /0/rest/FastReportService/CreateReport
Request UrlReferrer: http://192.168.222.228:82/0/Nui/ViewModule.aspx
Request Type: POST
User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36
User Host Address: 192.168.10.131
User: Supervisor
Is Authenticated: True
Authentication Type: Forms
Is Secure Connection: False
Application Version: 7.16.0.4449
Application Virtual Path: /0
Application Trust Level: Full
Is Local: False
Process ID: 3988
Process Name: w3wp.exe
OS Version: Microsoft Windows NT 10.0.14393.0
Net Framework Version: 4.0.30319.42000
DBExecutor Type: MSSqlExecutor
<-->
2020-08-05 18:06:11,880 [192] ERROR Terrasoft.Web.Common.ServiceModel.ErrorHandler HandleError - Internal Server Error
System.ServiceModel.Web.WebFaultException`1[Terrasoft.Configuration.Reporting.FastReport.FastReportGenerationException]: Internal Server Error (Дополнительные сведения об ошибке — Terrasoft.Configuration.Reporting.FastReport.FastReportGenerationException: Error during report generation).
2020-08-05 18:06:11,974 [192] ERROR Terrasoft.Web.Common.ServiceModel.ErrorHandler ProvideFault - Ссылка на объект не указывает на экземпляр объекта.
System.NullReferenceException: Ссылка на объект не указывает на экземпляр объекта.
в Terrasoft.Configuration.Reporting.FastReport.FastReportService.PopFromSessionData(String sessionKey)
в Terrasoft.Configuration.Reporting.FastReport.FastReportService.GetReportFile(String key)
в SyncInvokeGetReportFile(Object , Object[] , Object[] )
в System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
в System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
в System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
в System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc)
в System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
2020-08-05 18:06:11,974 [192] ERROR Terrasoft.WebApp.FileWebEventProvider RaiseInternal - Date: 05.08.2020 18:06:11
Date (UTC): 05.08.2020 15:06:11
Exception Message: Ссылка на объект не указывает на экземпляр объекта.
Exception Type: System.ServiceModel.FaultException`1[System.NullReferenceException]
Exception Source:
Exception Stack Trace:
SessionID: xxiqbf2pqlqi4uvge2vbjffb
Request URL: /0/rest/FastReportService/GetReportFile/undefined
Request Path: /0/rest/FastReportService/GetReportFile/undefined
Request Type: GET
User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36
User Host Address: 192.168.10.131
User: Supervisor
Is Authenticated: True
Authentication Type: Forms
Is Secure Connection: False
Application Version: 7.16.0.4449
Application Virtual Path: /0
Application Trust Level: Full
Is Local: False
Process ID: 3988
Process Name: w3wp.exe
OS Version: Microsoft Windows NT 10.0.14393.0
Net Framework Version: 4.0.30319.42000
DBExecutor Type: MSSqlExecutor
<-->
2020-08-05 18:06:11,989 [192] ERROR Terrasoft.Web.Common.ServiceModel.ErrorHandler HandleError - Ссылка на объект не указывает на экземпляр объекта.
System.NullReferenceException: Ссылка на объект не указывает на экземпляр объекта.
в Terrasoft.Configuration.Reporting.FastReport.FastReportService.PopFromSessionData(String sessionKey)
в Terrasoft.Configuration.Reporting.FastReport.FastReportService.GetReportFile(String key)
в SyncInvokeGetReportFile(Object , Object[] , Object[] )
в System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
в System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
в System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
в System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc)
в System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
Судя по сообщению из логов, второе исключение происходит в схеме FastReportService, в функции:
[Obsolete("7.15.3")]
[OperationContract]
[WebGet(UriTemplate = "GetReportFile/{key}")]
public Stream GetReportFile(string key) {
var data = PopFromSessionData(key);
string contentDisposition = "attachment; filename*=UTF-8''" + data.Key;
var reportStream = new MemoryStream(data.Value);
WebResponseProcessor.AssignFileResponseContent(HttpContextAccessor.GetInstance(), "application/pdf; charset=UTF-8", reportStream.Length, contentDisposition);
return reportStream;
}
private KeyValuePair<string, byte[]> PopFromSessionData(string sessionKey) {
var data = (KeyValuePair<string, byte[]>)UserConnection.SessionData[sessionKey];
UserConnection.SessionData.Remove(sessionKey);
return data;
}То есть падает не внутри Вашего кода отчёта, а при попытке скачать с сервера файл отчёта, вместо него пусто. Отчёт перед этим уже должен был создаться в CreateReport, а в ней происходит первое исключение. Но в этой функции любые ошибки обрабатывает общий блок try:
[Obsolete("7.15.3")]
[OperationContract]
[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
public string CreateReport(Guid reportTemplateId, string reportCaption, string reportSchemaName, string reportFilters) {
try {
var reportParameters = new Dictionary<string, object> {
["EsqFilters"] = new Dictionary<string, Filters> {
[reportSchemaName] = JsonConvert.DeserializeObject<Filters>(reportFilters)
}
};
var reportBytes = InternalCreateReport(reportTemplateId, reportParameters);
return PushToSessionData(new KeyValuePair<string, byte[]>($"{HttpUtility.UrlPathEncode(reportCaption)}.pdf", reportBytes));
} catch (Exception exception) {
throw new WebFaultException<FastReportGenerationException>(
new FastReportGenerationException(exception),
HttpStatusCode.InternalServerError);
}
}Получается, чтобы увидеть, где именно упало при генерации отчёта, нужно для теста убрать этот try, чтобы видеть дальнейший стек вызовов и настоящую ошибку.
А у Вас response status: 500 только на конкретном отчёте, который разрабатываете, на остальных нормально?
По поводу примеров, кроме описанного в академии, в системе есть ещё стандартные «Знаменательные события контакта» и «Полнота наполнения данными». В первом — несколько источников и схема ContactAnniversariesReportDataProvider, в ней интересующая Вас функция:
public Task<ReportDataDictionary> GetData(UserConnection userConnection,
IReadOnlyDictionary<string, object> parameters) {
var contactFilter = ExtractFilterFromParameters(userConnection, _contactEntitySchemaUId, parameters);
var result = new ReportDataDictionary {
["Contact"] = GetContactData(userConnection, _contactEntitySchemaUId, contactFilter),
["ContactAnniversary"] = GetContactAnniversaryData(userConnection, _contactAnniversaryEntitySchemaUId,
contactFilter),
["LocalizableStrings"] = GetLocalizableStrings(userConnection)
};
return Task.FromResult(result);
}Но обратите внимание, выше в коде есть сами функции GetContactData и GetContactAnniversaryData, получающие из базы коллекцию данных с указанным фильтром.
Зверев Александр,
Спасибо за помощь,
«Знаменательные события контакта» нашла, сделала полностью по аналогии. Та же ошибка.
Ошибка исчезает, как только убираю второй источник данных(
Может быть дело в версии, отчет на 16.1 - наша 16.0...
Если дело в версии, зарегистрируйте тестовый сайт и проверьте такое же там.