This is a migrated thread and some comments may be shown as answers.

Embedded Image Resources not rendering in Silverlight ReportViewer

6 Answers 226 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Adrian
Top achievements
Rank 1
Adrian asked on 23 Jan 2012, 10:23 AM
We have some logos at the top of our report. These have been added to the report through the Properties dialog using the Value property and browsing to the PNG image file. The image is then added to the resources file.

Previewing the report in Visual Studio the icons display.
Viewing the report in the WinForms ReportViewer the icons display.
Viewing the report in the Silverlight ReportViewer the icons do not display.
Exporting the report to PDF from the Silverlight ReportViewer the icons display.

Why would this be?

6 Answers, 1 is accepted

Sort by
0
Steve
Telerik team
answered on 23 Jan 2012, 10:54 AM
Hi Adrian,

The Images, Charts, Barcodes and Shapes are not being displayed in the Silverlight report viewer KB article elaborates on your inquiry.

Regards,
Steve
the Telerik team

Q3’11 of Telerik Reporting is available for download. Register for the What's New in Data Tools webinar to see what's new and get a chance to WIN A FREE LICENSE!

0
Adrian
Top achievements
Rank 1
answered on 24 Jan 2012, 12:29 AM
Thanks for the response. Indeed creating a test service with an App.Config and a test Silverlight app referencing the same report, the images render.

Our service is instantiated by another process though and we have a class that configures and opens the service - were we have attempted to mimic the App.config. The only difference to the test app is that our service runs as localhost:80/MyReportingService.svc instead of localhost:80/

The code follows, can you see what we have incorrect?

{code}
public class ReportingServiceInstance
    {
        static System.ServiceModel.ServiceHost host;

        public static void Start(string servername, int port)
        {
             Type serviceType = typeof(MyTelerikReportingWCFService.ReportingService);

            if (port == 0) port = 80;
            if (string.IsNullOrEmpty(servername)) servername = "localhost";

            string endpointbase = "http://{0}:{1}/MyReportingService.svc";
            var baseUri = new Uri(string.Format(endpointbase, servername, port));

            host = new ServiceHost(serviceType, baseUri);

            //behavior
            ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
            behavior.HttpGetEnabled = true;
            host.Description.Behaviors.Add(behavior);

            //ServiceDebugBehavior behavior2 = new ServiceDebugBehavior();
            //behavior2.IncludeExceptionDetailInFaults = true;
            //host.Description.Behaviors.Add(behavior2);

            //bindings
            System.ServiceModel.BasicHttpBinding bindingHttp = new BasicHttpBinding();
            bindingHttp.MaxReceivedMessageSize = int.MaxValue;
            bindingHttp.MaxBufferSize = int.MaxValue;
            bindingHttp.ReaderQuotas.MaxBytesPerRead = int.MaxValue;
            bindingHttp.ReaderQuotas.MaxArrayLength = int.MaxValue;
            bindingHttp.ReaderQuotas.MaxStringContentLength = ushort.MaxValue;
            bindingHttp.ReaderQuotas.MaxNameTableCharCount = ushort.MaxValue;
            bindingHttp.ReaderQuotas.MaxDepth = ushort.MaxValue;
            bindingHttp.TransferMode = TransferMode.Streamed;

            System.ServiceModel.WebHttpBinding bindingWeb = new WebHttpBinding();

            System.ServiceModel.WebHttpBinding bindingWeb2 = new WebHttpBinding();

            System.ServiceModel.Channels.Binding bindingMex = MetadataExchangeBindings.CreateMexHttpBinding();

            //add endpoints
            host.AddServiceEndpoint(typeof(IReportService), bindingHttp, "ReportService");

            host.AddServiceEndpoint(typeof(IResourceService), bindingWeb, "ReportService/resources");
            host.AddServiceEndpoint(typeof(IClientAccessPolicy), bindingWeb2, "");
            host.AddServiceEndpoint(typeof(IMetadataExchange), bindingMex, "reportservicemex");

            // Open
            host.Open();
      }
}
{code}
0
Adrian
Top achievements
Rank 1
answered on 25 Jan 2012, 10:05 AM
Hi. Sorry to ask, but can anyone help with this? Appreciated.
0
Adrian
Top achievements
Rank 1
answered on 04 Feb 2012, 08:42 AM
Some more information, using IE developer toolbar to watch Network activity and we noted that silverlight is calling the following URL: http://localhost:54321/reportservice/resources/getrenderstream?instanceID=7d004415-0d33-4c68-bef1-d441fdcecf4a&name=8f138b63aea0481e9526930ce214a5a4

So the silverlightviewer is not adding the MyReportingService.svc prefix to the resources URL.

Is this a telerik bug or do we need to configure something?

We are also using a Custom Binding to avoid render timeouts on long reports:

<telerikReporting:ReportViewer ReportServiceClientFactory="{Binding ReportServiceClientFactory}" 
                                       ReportServiceUri="{Binding ReportServiceUrl}" 
                                       Report="{Binding ReportName}" 
                                       Visibility="{Binding ReportVisibility}" />

The ReportServiceUrl binds to the same URL as defined above with MyReportingService.svc 

The ReportServiceClientFactory binds to an instance of:

public class ReportServiceClientFactory : IReportServiceClientFactory
    {
        Telerik.Reporting.Service.SilverlightClient.ReportServiceClient IReportServiceClientFactory.Create(System.Uri remoteAddress)
        {
            var binding = new BasicHttpBinding() // or BasicHttpBinding(BasicHttpSecurityMode.Transport) overload if SSL is used
            {
                MaxBufferSize = int.MaxValue,
                MaxReceivedMessageSize = int.MaxValue,
                ReceiveTimeout = new TimeSpan(0, 10, 0),
                SendTimeout = new TimeSpan(0, 10, 0),
                CloseTimeout = new TimeSpan(0, 10, 0)
            };


            var endpointAddress = new EndpointAddress(remoteAddress);


            return new Telerik.Reporting.Service.SilverlightClient.ReportServiceClient(binding, endpointAddress);
        }
    }
0
Steve
Telerik team
answered on 09 Feb 2012, 01:15 PM
Hi Adrian,

The provided code is executed on the Silverlight client and creating custom bindings scenario is already present in the Using Custom Bindings help article. Please note that although you implement IReportServiceClientFactory on the Silverlight client, the entries in the application configuration file are required in all cases, in order to host the WCF service and the settings in the configuration file should match those on the client. See:

If your svc file name is MyReportingService.svc, the URL you've posted should contain it i.e.:

http://localhost:54321/reportservice/resources/getrenderstream?....
should be:
http://localhost:54321/MyReportingService.svc/resources/getrenderstream?.....

so it looks like your ReportServiceUri binding is not taken into account.

Kind regards,
Steve
the Telerik team
Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
0
Adrian
Top achievements
Rank 1
answered on 14 Feb 2012, 02:28 AM
Thanks for the response. We solved this earlier, and here it is.

The issue was that the Silverlight ReportViewer call to get the resources looks to be driven from the server-side ReportingService : ReportServiceBase class and the protected override Uri BaseAddress property.

We had this set to localhost etc but in our install environment this could be any Uri - depending on the install location. So we have this implementation if it helps anyone else.

class ReportingService : ReportServiceBase
    {
        static readonly Uri baseUri = BaseUri;
 
        /**
         * BaseUri - method to get the dynamic Uri that the web-service is called by.
         * I.e. returning localhost... is not correct when this is installed at an IP address
         * or on a named server. The Silverlight ReportViewer uses the URL returned from here
         * to request report resources such as Images and Charts.
         **/
        private static Uri BaseUri
        {
            get
            {
                OperationContext operationContext = OperationContext.Current;
                HttpRequestMessageProperty httpRequest = operationContext.IncomingMessageProperties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
                if (httpRequest != null)
                {
                    // Get the OperationContext request Uri:
                    Uri viaUri = operationContext.IncomingMessageProperties.Via;
                    // Get the HTTP Host Header value:
                    string host = httpRequest.Headers[System.Net.HttpRequestHeader.Host];
                    // Remove Port
                    if (host.IndexOf(":") != -1)
                    {
                        host = host.Substring(0, host.IndexOf(":"));
                    }
                    // Build a new Uri replacing the host component of the Via Uri:
                    var uriBuilder = new UriBuilder(viaUri) { Host = host };
 
                    // This is the Uri which was requested:
                    string originalRequestUri = uriBuilder.Uri.AbsoluteUri;
 
                    return new Uri(originalRequestUri);
                }
 
                return new Uri("http://localhost:8080/MyReportingService.svc/reportservice");
            }
        }
 
        protected override Uri BaseAddress
        {
            get
            {
                // Can we gaurantee that each Silverlight ReportViewer is running from the same Uri?
                // I dont think this is true, i.e. one user using an IP address, another using the server name
                //return baseUri;
                return BaseUri;
            }
        }
    }

I would appreciate any feedback if there is a better solution?

Tags
General Discussions
Asked by
Adrian
Top achievements
Rank 1
Answers by
Steve
Telerik team
Adrian
Top achievements
Rank 1
Share this question
or