c# - 从 sql 报告服务器下载 XML 文件

标签 c# windows-phone-7 azure reporting-services

我正在尝试从 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 Phone 应用程序下载相同的文件。现在,由于 Windows Phone 中不存在 ServerReport,我依靠 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 服务还很陌生。我可能会问一些愚蠢的问题。这是我尝试过的:

  • 我尝试在 Windows Phone 7 项目中向 azure sql 报告服务器添加“服务引用”。我注意到的一件事是,我无法将该服务添加为“Web 引用”,因为它在 Windows Phone 7 应用程序中被禁用。
  • 将服务添加到我的应用程序后,我得到了一组类(class)。其中之一是 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::LogonUserAsync。 - 将获得的 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 方法来获取将在所有其他请求中使用的表单例份验证 cookie (就像渲染为 XML)。

在 WP7 应用程序中的 WebClient 上使用凭据不包括此内容。您有 2 个选择:

  • 尝试通过调用 LogonUser 获取 cookie 并在 WebClient 中使用它
  • 不要使用 WebClient,而是通过 ReportExecutionService 呈现报表

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

关于c# - 从 sql 报告服务器下载 XML 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13854356/

相关文章:

c# - Blazor WASM OIDC 指出无论我做什么,重定向 uri 都未定义

windows-phone-7 - ListPicker - 如何在全页 View 打开时显示当前选择

c# - 授权 USB 驱动器

c# - 抑制 .NET 中流的过早终结

c# - 从 Windows Phone 7 设备静默发送电子邮件?

c# - Azure:如何在表存储中保存 IDictionary<String>?

python - 网格搜索需要 30 多分钟,有什么方法可以减少这个时间吗? (Jupyter Azure)

asp.net - 我可以在模拟器之外使用 Azure 内存缓存(主要用于开发目的)吗?

c# - FFmpeg.AutoGen 使用 avfilter_graph_create_filter 返回 -22

windows-phone-7 - WP7 在其他控件之上显示控件