从sql报表服务器下载XML文件



我正试图从Azure SQL报告服务器下载一个xml文件,该文件需要身份验证才能获取。我正在尝试以下两种方法:

方法1

在这种方法中,我尝试了下面的c控制台应用程序,它从服务器下载文件。它很好用!

void DownloadFile(string uname, string password)
{
ServerReport report = new ServerReport();
report.ReportServerUrl = new System.Uri("https://xxxxx.reporting.windows.net/ReportServer", System.UriKind.Absolute);
report.ReportPath = "/Demo2.rdl";
report.ReportServerCredentials.SetFormsCredentials(null, uname, password, "xxxxx.reporting.windows.net");
byte[] data = report.Render("XML");
FileStream fs = new FileStream(@"c:output.xml", FileMode.Create);
fs.Write(data, 0, data.Length);
fs.Close();
}

方法2

现在我想从windows手机应用程序下载相同的文件。现在,由于ServerReport在windows phone中不存在,我依靠WebClient下载文件。所以我正在尝试下面的代码,但它似乎不起作用:

void DownloadFile(string uname, string password)
{
WebClient webClient = new WebClient();
webClient.Credentials = new NetworkCredential(uname, password, "xxxxx.reporting.windows.net");    
webClient.DownloadFile("https://xxxxx.reporting.windows.net/ReportServer?%2fDemo2.rdl&rs:Command=Render&rs:Format=XML", @"c:output.xml");
}

下面是方法2的输出:看起来它正在重定向到登录页面?

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >

<html lang="en-US">
<head id="Head1"><meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1" /><link rel="Stylesheet" type="text/css" href="Public/Logon.css" /><title>
Windows Azure SQL Reporting
</title></head>
<body >
<form name="Logon" method="post" action="logon.aspx?ReturnUrl=%2fReportServer%3f%252fDemo2.rdl%26rs%3aCommand%3dRender%26rs%3aFormat%3dXML&amp;%2fDemo2.rdl&amp;rs%3aCommand=Render&amp;rs%3aFormat=XML" id="Logon">
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/XXXX" />
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/YYYY" />
<h1 id="Title"><span id="LblTitleContent">Windows Azure</span></h1>
<hr />
<div class="ClsIntro">
<span id="LblIntro"></span>
</div>
<div class="ClsInput">
<div>
<label for="TxtUser" id="LblUser">User name</label>
</div>
<div>
<input name="TxtUser" type="text" id="TxtUser" tabindex="1" />
</div>
</div>
<div class="ClsInput">
<div>
<label for="TxtPwd" id="LblPwd">Password</label>
</div>
<div>
<input name="TxtPwd" type="password" id="TxtPwd" tabindex="2" />
</div>
</div>
<div class="ClsSignIn">
<input type="submit" name="BtnLogon" value="Sign in" id="BtnLogon" tabindex="4" /><input type="image" name="BtnLogonArrow" id="BtnLogonArrow" tabindex="5" src="Public/WhiteRightArrow.png" alt="Sign in" align="baseline" border="0" />
</div>
<div class="ClsErrMsg">
<span id="lblMessage"></span>
</div>
<hr />
</form>
</body>
</html>

方法2可能有什么问题,我们遗漏了什么吗?

更新

我对这个azure和web服务还很陌生。我可能在问一些愚蠢的问题。以下是我尝试过的:

  • 我尝试在我的windowsphone 7项目中向azure-sql报告服务器添加一个"服务引用"。我注意到的一件事是,我不能将服务添加为"Web引用",因为它在windowsphone7应用程序中被禁用
  • 在将serive添加到我的应用程序后,我得到了一组类。其中之一是ReportExecutionServiceSoapClient
  • ReportExecutionService不可用
  • 我不太确定如何使用ReportExecutionServiceSoapClient api来获取可以用于WebClient的cookie
  • 任何关于如何使用这些API的示例应用程序都将非常棒。我试着在网上搜索,但无法获得更多信息
  • 以下是我尝试过的内容,但cookie计数为空。

    ReportExecutionServiceSoapClient client = new ReportExecutionServiceSoapClient();
    void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
    client.ClientCredentials.UserName.UserName = "XXXX";
    client.ClientCredentials.UserName.Password = "XXXX";
    client.CookieContainer = new CookieContainer();
    client.LogonUserCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(client_LogonUserCompleted);
    client.LogonUserAsync("XXXX", "XXXX", "xxxx.reporting.windows.net");
    }
    void client_LogonUserCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
    {
    int count = client.CookieContainer.Count;  // NULL COOKIE COUNT!!!
    }
    

下面是ClientConfig文件。我添加了enableHttpCookieContainer="true"。

<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="ReportExecutionServiceSoap" maxBufferSize="2147483647"
enableHttpCookieContainer="true"
maxReceivedMessageSize="2147483647">
<security mode="Transport" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://xxxx.reporting.windows.net:443/ReportServer/ReportExecution2005.asmx"
binding="basicHttpBinding" bindingConfiguration="ReportExecutionServiceSoap"
contract="SqlReportingService.ReportExecutionServiceSoap"
name="ReportExecutionServiceSoap" />
</client>
</system.serviceModel>
</configuration>
  • 请告诉我缺少什么

已解决-终于可以从Azure Sql报告服务器下载xml文件了。-以下是解决方案。-首先添加对Sql报表服务器的服务引用。-然后执行ReportExecutionServiceSoapClient::LogonUserSync。-将获得的cookie与WebClient一起用于进一步请求。

public class WebClientExtended : WebClient
{
private CookieContainer myContainer;
private HttpWebRequest myRequest;
[SecuritySafeCritical]
public WebClientExtended()
{
}
[SecuritySafeCritical]
public WebClientExtended(CookieContainer containter) 
{ 
myContainer = containter; 
}
public CookieContainer Cookies
{
get { return myContainer; }
set { myContainer = value; }
}
protected override WebRequest GetWebRequest(Uri address)
{
myRequest = (HttpWebRequest)base.GetWebRequest(address);
myRequest.Method = "GET";
myRequest.CookieContainer = Cookies;
return myRequest;
}
protected override WebResponse GetWebResponse(WebRequest request, IAsyncResult result)
{
return myRequest.EndGetResponse(result);
}
}
ReportExecutionServiceSoapClient rs = new ReportExecutionServiceSoapClient();
string servername = "XXXX.reporting.windows.net";
string uname = "XXXX";
string password = "XXXX";
public void LoadReport()
{
rs.ClientCredentials.UserName.UserName = uname;
rs.ClientCredentials.UserName.Password = password;
rs.CookieContainer = new CookieContainer();
rs.LogonUserCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(rs_LogonUserCompleted);
rs.LogonUserAsync(uname, password, servername);
}
void rs_LogonUserCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
WebClientExtended webClient = new WebClientExtended(rs.CookieContainer);
webClient.Credentials = new NetworkCredential(uname, password, servername);
webClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webClient_DownloadStringCompleted);
webClient.DownloadStringAsync(new Uri(String.Format("https://{0}/ReportServer?%2fDemo2.rdl&rs:Command=Render&rs:Format=XML", servername)));
}
void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
MessageBox.Show(e.Result);
}

ServerReport类将调用ReportExecutionService上的LogonUser方法,以获取将在所有其他请求中使用的Forms Authentication cookie(如呈现为XML)。

在WP7应用程序中的WebClient上使用凭据并不能解决此问题。您有两个选项:

  • 尝试通过调用LogoUser获取cookie并在您的WebClient中使用
  • 不使用WebClient,而是通过ReportExecutionService呈现报告

看看Windows Azure SQL Reporting:使用SOAP API博客文章,开始在SQL Azure中使用此服务。

方法更新:即使代码说cookie不存在,您也可能实际收到了cookie。这些只是因为"安全问题"而隐藏在CookieContainer中的某个地方。

只需尝试将CookieContainer的相同实例插入到下一个WebRequest中,并尝试验证它是否有效。

最新更新