WebRequest在ASP.NET应用程序中失败,“414 Request URI太长”

时间:2012-12-05 16:39:30

标签: c# iis reporting-services httpwebrequest getresponse

我们有一个ASP.NET应用程序,它在将报告的参数作为WebRequest传递后,以HTML格式请求SSRS 2005报告。只有在请求具有大量多选参数的报表时,应用程序才会失败,在webRequest.GetResponse()行处抛出“414:Request URI too long”错误。

用于发出请求的代码是:

HttpWebRequest webRequest = null;
HttpWebResponse webResponse = null;
string webRequestURL = _ReportManager.GetRSUrl(reportID); //this passes the report link on the SSRS server

//make the request

Byte[] bytes = Encoding.UTF8.GetBytes("xml_doc=" + HttpUtility.UrlEncode(webRequestURL));

webRequest = (HttpWebRequest)WebRequest.Create(webRequestURL);
webRequest.Method = "POST";
webRequest.ContentLength = bytes.Length;
webRequest.Timeout = Configuration.WebRequestTimeOut;

RSExecution2005.ReportExecutionService rsE = new RSExecution2005.ReportExecutionService();
rsE.Url = Configuration.ReportExecutionServiceUrl2005;
rsE.Credentials = System.Net.CredentialCache.DefaultCredentials;
webRequest.Credentials = rsE.Credentials;

Stream reqStream = null;
reqStream = webRequest.GetRequestStream();
reqStream.Write(bytes, 0, bytes.Length);
reqStream.Close();

webResponse = (HttpWebResponse)webRequest.GetResponse();

由于报告在服务器端失败,我已经查看了IIS和ReportServer属性,以字节数(按this article)增加maxUrl,maxRequestLength,MaxQueryString等,但应用程序仍然会抛出错误。我在web.config文件中尝试过这个,直接在IIS管理器上。

2005年的报告服务器版本,它托管在运行IIS 7的Windows Server 2008上。


关于David Lively的建议我尝试通过将参数放在正文中来请求URI。这适用于较小的请求,但仍然无法用于大型多选参数。修改后的代码如下:

HttpWebRequest webRequest = null;
HttpWebResponse webResponse = null;
string webRequestURL = _ReportManager.GetRSUrl(reportID); //this passes the report link on the SSRS server

string postData = string.Empty;
string URIrequest = string.Empty;
URIrequest = webRequestURL.Substring(0, webRequestURL.IndexOf("&"));
int requestLen = webRequestURL.Length;
int postDataStart = webRequestURL.IndexOf("&") + 1;
postData = webRequestURL.Substring(postDataStart, (requestLen - postDataStart));

Byte[] bytes1 = Encoding.UTF8.GetBytes(postData);

webRequest = (HttpWebRequest)WebRequest.Create(URIrequest);
                webRequest.Method = "POST";
                webRequest.ContentType = "application/x-www-form-urlencoded";
                webRequest.ContentLength = bytes1.Length;
                webRequest.Timeout = Configuration.WebRequestTimeOut;

RSExecution2005.ReportExecutionService rsE = new RSExecution2005.ReportExecutionService();
rsE.Url = Configuration.ReportExecutionServiceUrl2005;
rsE.Credentials = System.Net.CredentialCache.DefaultCredentials;
webRequest.Credentials = rsE.Credentials;

Stream reqStream = webRequest.GetRequestStream();
reqStream.Write(bytes1, 0, bytes1.Length);
reqStream.Close();
webResponse = (HttpWebResponse)webRequest.GetResponse();

即使webRequest的requestURI没有存储参数,似乎GetReponse()函数也将参数添加到webRequest的'address'属性中。这可能是问题吗?如果是的话,怎么解决呢。

7 个答案:

答案 0 :(得分:5)

您是否可以使用POST变量而不是GET?这样,我没有任何限制,因为所有数据都将以数据包而不是HTTP标头发送。

实际上,您可能正在使用代码中的POST。您是否可以查看服务器日志以验证导致此失败的URI?如果您要发送POST数据,请求uri不应成为问题,除非它与您正在发布的数据无关。

答案 1 :(得分:3)

检查服务的绑定设置。我想该服务将允许字符串长达8192。将te readerQuotas设置为更大的尺寸。可能有帮助。

...

 <basicHttpBinding>
        <binding name="largeBuffer">
          <readerQuotas
                        maxDepth="2147483647"
                        maxStringContentLength="2147483647"
                        maxArrayLength="2147483647"
                        maxBytesPerRead="2147483647"
                        maxNameTableCharCount="2147483647" />
          <security mode="None"></security></binding>
  </basicHttpBinding>

.....

答案 2 :(得分:2)

由于您已经使用POST来获取报告,因此我建议您将当前在查询字符串中传递的参数放在请求正文中。查询字符串参数适用于有限数量的参数,但不适用于大量项目。

答案 3 :(得分:1)

你能展示webRequestURL的价值吗?

它会“太大”。

如果要将参数传递给此URL,那么它们是否可以在POST主体中?

答案 4 :(得分:1)

webRequestURL.IndexOf(“&amp;”)......这是否意味着“?”而不是“&amp;”?我猜你构建了一个有效的URL来查询页面,然后通过在第一个'&amp;'之前查找URL来反向设计它作为POST请求...

但是,GetResponse可能会将正文附加到URL,因为它会在URL中看到问号,并假设参数必须放在URL中?尝试使用零参数进行更精确的URL匹配,而不是'?'。

答案 5 :(得分:1)

我在IIS7网站上运行了这个。通过注册表黑客修复它,我可以搜索它但在3/1之前无法工作。同时,如果你在使用ip-address而不是正常的URL时遇到错误,请尝试,否则很可能是同样的问题。

答案 6 :(得分:0)

有一个类似的问题,除了POST正在工作,但第二个具有完全相同参数的POST返回414。

设置req.KeepAlive = false;解决了这个问题,天知道为什么。