Hi,
Is it possible now to save and load IGR reports into/from database reports in v12.1 ?
regards
You can load a report from a database or any other source by loading it as a stream and providing it to the viewer.
Considering your request, you can use a Report Uri Resolver to map URI to reports and define how they are loaded (e.g. retrieve them from a DB). Here is a guide and sample to learn how to use it.
Also, if you are using client-side rendering you can do something like this to set the viewer once you have loaded the stream (e.g. retrieved from the DB).:
//Load a local report
Stream myReportStream = Application.GetResourceStream(new Uri("SilverlightApplication1;component/Report1.igr", UriKind.Relative)).Stream;
xamReportViewer1.RenderSettings = new ClientRenderSettings { DefinitionStream = myReportStream };
Hope it helps.
Regards,
Miguel
Hi, I'm affraight I can't cope with that without some help :)
I've created following code, is it correct ? I had to put the static interface which I use to get data from database:
public static IDBApi iDBApi;
public void Resolve(Uri reportUri, Action<UriResolverData> result)
{
//TODO: Add report load logic based on the reportUri parameter.
string report = iDBApi.DataBase.GetTable("select ReportBody from Reports where ReportID = 2").Rows[0][0].ToString();
var mStream =
new MemoryStream(ASCIIEncoding.Default.GetBytes(report));
result.Invoke(new UriResolverData(mStream, null));
}
Hello,
I do apologize for not responding sooner. The code you have seems to be correct; the problem might be in the report’s igr source code. What's the error message you are getting?
Please make sure the report is being retrieved correctly from the database, if you are saving the *.igr as a string/varchar/text in the database, please compare it with the report’s source file (*.igr) to make sure they match (you can open the *.igr (xml) from the Designer by right clicking on it>Open With…).
Once you have loaded the *.igr source (xml) you can encode it and load it as you are doing it.
Here is a sample I wrote to test your scenario. I created the following SQL DB to save my reports using "id" to identify reports and saving the *.igr "as is" into "Design".
// Recognize Desired Path
if (reportUri.ToString().StartsWith(mydesiredPrefix))
// Retrieve Report igr from DB
SqlConnection connection = new SqlConnection(@"Data Source=.\sqlexpress;Initial Catalog=ReportLibraryDB;Integrated Security=True");
connection.Open();
SqlCommand command = new SqlCommand("select * from dbo.Report WHERE dbo.Report.id='Customers';");
command.Connection = connection;
SqlDataReader reader = command.ExecuteReader();
reader.Read();
// Load igr
var reportSource = reader["Design"].ToString();
connection.Close();
// Convert string to stream
byte[] byteArray = Encoding.ASCII.GetBytes(reportSource);
using (var reportStream = new MemoryStream(byteArray))
var resultUri = new UriResolverData(reportStream, null);
result.Invoke(resultUri);
else
{ // Ignore Uri Resolution
result.Invoke(null);
Hope this helps, please let me know how it goes...
Thanks. No problem with that delay. But I've got another dumb question :) Where and how should I call that method ?
The Resolve method is invoked automatically when declaring a ReportUriResolver as explained Here.
As a reference:
[ReportUriResolverExport]
public class DatabaseUriResolver : IReportUriResolver
const string ResolverPrefix = "http://MyDomain/MyDatabase/";
if (reportUri.ToString().StartsWith(ResolverPrefix))
I suggested this mechanism (i.e. ReportUriResolver) since it gives you full control on how to define and map uris as well as how reports are loaded.
For instance, you can define a certain prefix to know which reports should be retrieved from the DB and/or parse the uri to create the corresponding query that will load the report from the DB.
e.g.
$(function() {
$("#viewer").igReportViewer({
renderSettings: {
definitionUri: "http://MyDomain/MyDatabase/MyReportsTable/MyReportId ",
serviceEndpointUri: serviceEndpoint},
});
Following the steps indicated in How to Customize Uri Resolution should get you going to implement this. You can also check out this link to see a running sample, Please let me know if you need further instructions.
Miguel.
I've still got problems with that. That's my implementation of that class:
public class ReportUriResolver1 : IReportUriResolver
public static IDBase iDbase;
var reportBody = iDbase.DataBase.GetTable("select ReportBody from Reports where ReportID = 3").Rows[0][0].ToString();
byte[] byteArray = Encoding.ASCII.GetBytes(reportBody);
An here's the definition uri for the report viewer. In my opinion Uri string (blablabla) doesn't matter here beacuse in ReportUriResolver1 I always load report with reportid = 3.
ultraReportViewer1.RenderSettings.DefinitionUri = new System.Uri(@"blablabla", System.UriKind.RelativeOrAbsolute);
Every time I try to show the report I receive: " Could not find report definition blablabla."
Ok, in order to debug that, please make sure that Resolve method is being invoked when trying to render a report by toogling a break point in it. That method should be invoked everytime a report is rendered ,so assuming that the *.igr is being loaded correctly from the database, the only reason I can think of why it is not finding the report is because its not even running the resolver.
If it's not, please make sure you have added the assembly containing the ReportUriResolver as a runtime assembly in the config file.
e.g. web.config
<configuration><configSections><section name="infragistics.reports" type="Infragistics.Reports.ReportsConfigurationSection, InfragisticsWPF4.Reports.Client.v12.1"/></configSections>
<infragistics.reports><reportServercleanupIntervalInMinutes="10" timeoutInMinutes="10" includeExceptionDetail="true"/><!-- Add more assemblies to look up for Report Uri Resolvers --><runtimeAssemblies><add assembly="MyAssemblyWithUriResolvers1"/><add assembly="MyAssemblyWithUriResolvers2"/></runtimeAssemblies></infragistics.reports></configuration>
Hope this solves the problem.
Many thanks. I'll check that
I could reproduce the problem. The problems happen when executing the application using .NET4. There is a bug in the framework when invoking System.Configuration.ConfigurationManager from the network share, it throws a security exception, and therefore the RuntimeAssemblies are not being taken into account. Here is the explanation of the bug. After installing the provided hotfix the problem is resolved. This problem does not occurs in framework 4.5.
Can you avoid running the application from the network share?
Best,
Leo
Any info ?
Solution ready.
Can you please provide a simple solution that reproduces the problem? For the Uri Provider you can just create a dummy one that displays the messagee and just invokes result.Invoke(null);