views:

233

answers:

2

I need to provide an export to excel feature for a large amount of data returned from a WCF web service.

The code to load the datalist is as below:

List<resultSet> r = myObject.ReturnResultSet(myWebRequestUrl);  //call to WCF service
myDataList.DataSource = r;
myDataList.DataBind();

I am using the Reponse object to do the job:

Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/vnd.ms-excel";
Response.AddHeader("Content-Disposition", "attachment; filename=MyExcel.xls");
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
HtmlTextWriter tw = new HtmlTextWriter(sw);
myDataList.RenderControl(tw);
Response.Write(sb.ToString());
Response.End();

The problem is that WCF Service times out for large amount of data (about 5000 rows) and the result set is null. When I debug the service, I can see the window for saving/opening the excel sheet appear before the service returns the result and hence the excel sheet is always empty. Please help me figure this out.

EDITED TO ADD - WCF site's IHttpModule used to rewriting the URL is being called twice or thrice. Could this be because of a aspnet_wp recycle? In that case I should be seeing the error on my Application Event Log, right? But I don't. Please help me with this issue.

Here is my custom HttpModule: public class CustomHttpModule : IHttpModule { public void Dispose() { }

public void Init(HttpApplication appln) 
{ 
    appln.AuthorizeRequest+= delegate 
    { 
        HttpContext tcontext= HttpContext.Current; 
        string path = tcontext.Request.AppRelativeCurrentExecutionFilePath; 

        int i = path.IndexOf('/', 2); 
        if (i > 0) 
        { 
            string svc = path.Substring(0, i) + ".svc"; 
            string fu = path.Substring(i, path.Length - i); 
            tcontext.RewritePath(svc, fu, tcontext.Request.QueryString.ToString(), false); 
        } 
    }; 
} 

}

I see that appln.AuthorizeRequest is called twice. I think this is why I am seeing the operation time out or the connection closed exception. How do I stop it from doing it twice. I only create one request.

+1  A: 

You've run into one of many kinds of WCF/IIS timeouts and limits. This particular one may be MaxReceivedMessageSize. Default is 64 KB. Configure this on the service's binding.

Other limits are (these aren't all binding parameters):

  • MaxItemsInObjectGraph (65536)
  • maxRequestLength (4 MB)
  • executionTimeout (90 seconds)
  • sendTimeout on client (10 minutes)
Tor Hovland
I get "Underlying connection was closed" exception. This is a REST WCFservice so I had to change the time out for the HttpRequest. Whats weird is the request call is made just once, but the service method is hit twice or thrice until this exception arises. I don't understand why this is happenning. I even have the KeepAlive set to false since I thought the request calls are made to keep the connection alive until the data is returned. This happens only when exporting large data. There may be work arounds but I would like to know how to fix the existing issue instead of starting a work around.
Dave
I edited my question. I find that when exporting the entire data, IHttpModule's init is called twice or thrice. This doesn't happen when the data is relatively small. Could this be aspnet_wp recycle. If so, how do I fix it?
Dave
A: 

Tor's response helped me a little bit. I had to set the MaxItemsInObjectGraph to a higher value for this exception to go away. However, I had trouble setting this value because I didn't how to set it and where to set it.

This article helped me understand more about WCF Rest service and throttling. What actually worked for me was setting the ServiceBehavior attribute for my service class.

[ServiceBehavior(MaxItemsInObjectGraph=2147483646)]
public abstract class MyService: IMyService

{ blah... }

If you aren't concerned about having to change the max limit over and over, you could be happy with specifying it in code and have the fun in seeing it all working.

Dave