将数据从WCF服务导出到Excel

时间:2010-06-09 21:42:19

标签: c# wcf export-to-excel datalist ihttpmodule

我需要为从WCF Web服务返回的大量数据提供导出到excel功能。

加载datalist的代码如下:

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

我正在使用Reponse对象来完成这项工作:

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();

问题是WCF服务因大量数据(大约5000行)而超时,结果集为空。当我调试服务时,我可以看到保存/打开Excel工作表的窗口出现在服务返回结果之前,因此excel工作表总是为空。请帮我解决这个问题。

EDITED TO ADD - 用于重写URL的WCF站点的IHttpModule被调用两次或三次。这可能是因为aspnet_wp回收?在那种情况下,我应该在应用程序事件日志中看到错误,对吧?但我没有。请帮我解决这个问题。

这是我的自定义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); 
        } 
    }; 
} 

}

我看到appln.AuthorizeRequest被调用两次。我认为这就是我看到操作超时或连接关闭异常的原因。如何阻止它两次这样做。我只创建了一个请求。

2 个答案:

答案 0 :(得分:1)

您遇到了多种WCF / IIS超时和限制之一。这个特定的可能是MaxReceivedMessageSize。默认值为64 KB。在服务的绑定上配置它。

其他限制是(这些不是所有绑定参数):

  • MaxItemsInObjectGraph(65536)
  • maxRequestLength(4 MB)
  • executionTimeout(90秒)
  • 客户端
  • sendTimeout(10分钟)

答案 1 :(得分:0)

Tor的回应对我有所帮助。我必须将MaxItemsInObjectGraph设置为更高的值才能使此异常消失。但是,我无法设置此值,因为我没有设置它以及设置它的位置。

这个article帮助我了解了有关WCF Rest服务和限制的更多信息。实际上对我有用的是为我的服务类设置ServiceBehavior属性。

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

{      等等...    }

如果您不必担心必须一遍又一遍地更改最大限制,您可以很高兴在代码中指定它并享受看到它全部工作的乐趣。