I have currently updated my Telerik Reporting Services to the latest Version of Q3.
My Application uses Silverlight and Telerik Silverlight Report Viewer that gets the data from the "ReportService.svc" WCF Web Service.
When I have more than 1000 records (transactions) I always get a timeout after about 1 minute. My suggestion is that this is the default max time of a WCF web service call before a timeout exception is thrown.
I already adjusted the service behavior and timeout settings in the hosting web application that provides the ReportService.svc service.
What I am missing is the client endpoint configuration in my Silverlight application.
My Silverlight code for the report viewer is:
<telerikReports:ReportViewer |
x:Name="repViewer" Margin="5" Width="Auto" Height="750" |
ReportServerUri="../ReportService.svc" |
Report="Reports.TransactionReport, Reports, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=null"> |
</telerikReports:ReportViewer> |
Where can I set this client endpoint parameters to increase the timeout settings in Silverlight??
I really preciate any quick help on my issue. I think it can only be a configuration issue.
Thanks a lot
Heiko
15 Answers, 1 is accepted
"I already adjusted the service behavior and timeout settings in the hosting web application."
You should configure the client-side as well as the server side. Currently the service client (that is the ReportServiceClient) uses the default timeouts. Please check the timeout-related properties of Binding class for additional information and default values.
There is a need to use custom Bindings for the ReportServiceClient and with the Q3 SP1 we just released today we have extended the viewer's API so you can now create your own ReportServiceClient object instance and initialize it according to your needs.
The described improvement includes the new:
public interface IReportServiceClientFactory
{
ReportServiceClient Create(Uri remoteAddress);
}
and one property added to the ReportViewer class:
public IReportServiceClientFactory ReportServiceClientFactory { get; set; }
You need to implement the IReportServiceClientFactory interface and its only method should create and return a new instance of the ReportServiceClient class using any of its constructors. This way you attach your custom Binding to be used for connecting to the Report Service.
Once you have implemented IReportServiceClientFactory, you should provide an instance to the report viewer so it will use it the next time it creates a new instance of the ReportServiceClient - that is when the report or report service Uri have changed or the RefreshReportCommand is executed through the ReportViewerModel.
The ReportViewer usually passes absolute Uri to the IReportServiceClientFactory.Create() method.
For more information on how the ReportServiceUri is resolved to absolute please review EnsureAbsoluteUri.
Steve
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
Thanks a lot for your feedback. This seams to be a very easy and flexible way to adjust the client service config in Silverlight report viewer.
I created a class in Silverlight that is derived from IReportServiceClientFactory which implements the Create function for a ReportServiceClient instance.
Furthermore I assigned this instance to my ReportViewer instance.
The only issue is now that the Create - Function is not called. Is something else missing?
Can you provide a working sample code?
Thanks!
Heiko
You can find a working sample code in our documentation in the Using Custom Bindings help article. Please review it and let us know if further help is needed.
Best wishes,Steve
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
Thanks,
Mike
public partial class MyReportPage : UserControl, IReportServiceClientFactory |
{ |
public MyReportPage() |
{ |
InitializeComponent(); |
this.MainReportViewer.ReportServiceClientFactory = this; |
} |
ReportServiceClient IReportServiceClientFactory.Create(Uri remoteAddress) |
{ |
Binding binding = new BasicHttpBinding(); |
binding.ReceiveTimeout = new TimeSpan(0, 10, 0); |
binding.SendTimeout = new TimeSpan(0, 10, 0); |
binding.OpenTimeout = new TimeSpan(0, 10, 0); |
binding.CloseTimeout = new TimeSpan(0, 10, 0); |
EndpointAddress endpointAddress = new EndpointAddress(remoteAddress); |
return new ReportServiceClient(binding, endpointAddress); |
} |
} |
<services> |
<service name="Telerik.Reporting.Service.ReportService" behaviorConfiguration="ReportServiceBehavior"> |
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="BasicHttpBindingConfig" contract="Telerik.Reporting.Service.IReportService"> |
<identity> |
<dns value="localhost" /> |
</identity> |
</endpoint> |
<endpoint address="resources" binding="webHttpBinding" behaviorConfiguration="WebBehavior" contract="Telerik.Reporting.Service.IResourceService" /> |
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> |
</service> |
</services> |
<behaviors> |
<serviceBehaviors> |
<behavior name="ReportServiceBehavior"> |
<serviceMetadata httpGetEnabled="true"/> |
<serviceDebug includeExceptionDetailInFaults="false" /> |
</behavior> |
</serviceBehaviors> |
<endpointBehaviors> |
<behavior name="WebBehavior"> |
<webHttp /> |
</behavior> |
</endpointBehaviors> |
</behaviors> |
<bindings> |
<basicHttpBinding> |
<binding name="BasicHttpBindingConfig" |
maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" maxBufferPoolSize="2147483647" |
receiveTimeout="00:10:00" sendTimeout="00:10:00" openTimeout="00:10:00" closeTimeout="00:10:00"/> |
</basicHttpBinding> |
</bindings> |
this problem is still an issue!!
Main issue is that the implemented Create function (through the IReportServiceClientFactory interface) is not called. So the adjustment is totally useless.
@Telerik: Is this still a bug that will be fixed in the next version soon?
We need this really asap now. Please feedback what the problem is here.
If we cannot solve this issue, I am forced to take a separate solution from another vendor.
Thanks!
I have the timeout logic working in my application. I'm doing basically the same thing you are in the code, so maybe it's something subtle about my config file. I'll post both the code and config file for your consideration. You should also be aware that I'm running under Windows 7.
Note that I'm passing a parameter to my reports via the RenderBegin event, but that might not be relevant to your problem.
public partial class TaskReportControl : UserControl, IReportServiceClientFactory |
{ |
#region Properties |
private int ReportRequestKey { get; set; } |
#endregion Properties |
#region Constructors |
public TaskReportControl(string reportName, int reportRequestKey) |
{ |
InitializeComponent(); |
this.ReportViewer1.ReportServiceClientFactory = this; |
ReportViewer1.Report = string.Format("Tc.Web.Reports.{0}, Tc.Web, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=null", reportName); |
ReportRequestKey = reportRequestKey; |
this.ReportViewer1.RenderBegin += new RenderBeginEventHandler(ReportViewer1_RenderBegin); |
} |
#endregion Constructors |
#region Event Handlers |
private void ReportViewer1_RenderBegin(object sender, RenderBeginEventArgs args) |
{ |
args.ParameterValues["ReportRequestKey"] = ReportRequestKey; |
} |
#endregion Event Handlers |
#region IReportServiceClientFactory Members |
public ReportServiceClient Create(Uri remoteAddress) |
{ |
BasicHttpBinding binding = new BasicHttpBinding(); |
// |
// Increase the max message size in order to avoid the dreaded message: |
// System.ServiceModel.CommunicationException : The maximum message size quota for incoming |
// messages (65536) has been exceeded. To increase the quota, use the MaxReceivedMessageSize |
// property on the appropriate binding element. |
// |
binding.MaxReceivedMessageSize = Int32.MaxValue; |
// |
// Now set the timeout to an appropriate number of seconds. |
// TODO: Handle the timeout exception gracefully if it does happen, i.e., set the timeout to 5 seconds. |
// |
binding.SendTimeout = new System.TimeSpan(0, 0, 120); |
return new ReportServiceClient(binding, new EndpointAddress(remoteAddress)); |
} |
#endregion |
} |
I'll include the whole system.servicemodel section of my Web.config so you can look it over. The Tc.Web service/behaviors are my business layer service, so you can probably ignore those lines. I'm including them here for completeness.
<system.serviceModel> |
<behaviors> |
<serviceBehaviors> |
<behavior name="Tc.Web.ServiceBehavior"> |
<serviceMetadata httpGetEnabled="true"/> |
<serviceDebug includeExceptionDetailInFaults="false"/> |
</behavior> |
<behavior name="ReportServiceBehavior"> |
<serviceMetadata httpGetEnabled="true" /> |
<serviceDebug includeExceptionDetailInFaults="false" /> |
</behavior> |
</serviceBehaviors> |
<endpointBehaviors> |
<behavior name="WebBehavior"> |
<webHttp /> |
</behavior> |
</endpointBehaviors> |
</behaviors> |
<bindings> |
<customBinding> |
<binding name="customBinding0"> |
<binaryMessageEncoding/> |
<httpTransport/> |
</binding> |
</customBinding> |
</bindings> |
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/> |
<services> |
<service behaviorConfiguration="Tc.Web.ServiceBehavior" name="Tc.Web.Secure.Service"> |
<endpoint address="" binding="customBinding" bindingConfiguration="customBinding0" contract="Tc.Web.Secure.Service"/> |
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> |
</service> |
<service name="Telerik.Reporting.Service.ReportService" behaviorConfiguration="ReportServiceBehavior"> |
<endpoint address="" binding="basicHttpBinding" contract="Telerik.Reporting.Service.IReportService"> |
<identity> |
<dns value="localhost" /> |
</identity> |
</endpoint> |
<endpoint address="resources" binding="webHttpBinding" behaviorConfiguration="WebBehavior" contract="Telerik.Reporting.Service.IResourceService"/> |
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> |
</service> |
</services> |
</system.serviceModel> |
Note that I don't make any basic http binding settings in the config file, but am setting both MaxReceivedMessageSize and SendTimeout in the code.
Hope this helps,
Bob
<%@ServiceHost Service="Telerik.Reporting.Service.ReportService, Telerik.Reporting.Service, Version=3.2.9.1211, Culture=neutral, PublicKeyToken=A9D7983DFCC261BE" %> |
Thanks for sharing. So if you have put a break point in the create function, you can see that those lines have been executed, right? I just want to make sure that that is the issue for me.
Thanks,
Karlkim
Thank you very much for your detailed feedback. Your information lead me to determine the Telerik Bug.
The only change I made to my code now was that I removed the Report file declaration attribute from the XAML code and set the report name string within the code like you did in yours. Then the Create function is called correctly.
When I specify the report file in xaml code the Create function is not called! This is reproducable.
Looks for me like a bug that must have been found during testing.
My simple Xaml code:
<telerikReports:ReportViewer |
x:Name="repViewer" |
Margin="5" |
Width="Auto" |
Height="750" |
ReportServerUri="../ReportService.svc"> |
My simple init cs-code:
repViewer.ReportServiceClientFactory = this; |
repViewer.Report = "ERP.Reports.TransactionReport, ERP, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=null"; |
Best regards,
Heiko
I just try to follow your examples, and it seems to work for me now.
Thanks!
Karlkim
http://www.telerik.com/help/reporting/silverlight-report-viewer-using-custom-bindings.html
Is that correct? You can only do it this way?
Sobiya