C# 在C中使用WebRequest时为Microsoft Report Server提供凭据#

C# 在C中使用WebRequest时为Microsoft Report Server提供凭据#,c#,authentication,webrequest,reportserver,C#,Authentication,Webrequest,Reportserver,我想使用我的C#代码从我们的Microsoft报表服务器下载PDF报表。我不知道为什么,但我做错了什么。我总是返回一个错误,即身份验证失败(HTTP 401) 公共静态异步任务下载WebDocument(字符串url){ if(string.IsNullOrEmpty(url)) 抛出新ArgumentNullException(nameof(url)); WebRequest=WebRequest.Create(url); request.Method=“GET”; request.Authe

我想使用我的C#代码从我们的Microsoft报表服务器下载PDF报表。我不知道为什么,但我做错了什么。我总是返回一个错误,即身份验证失败(HTTP 401)

公共静态异步任务下载WebDocument(字符串url){
if(string.IsNullOrEmpty(url))
抛出新ArgumentNullException(nameof(url));
WebRequest=WebRequest.Create(url);
request.Method=“GET”;
request.AuthenticationLevel=System.Net.Security.AuthenticationLevel.MutualAuthRequested;
request.Credentials=newnetworkcredential(“MyUsername”、“MyPassword”、“MyDomain”);
//request.Headers.Add(“Authorization”,$”基本{Convert.ToBase64String(System.Text.Encoding.Default.GetBytes(“MyUsername:MyPassword”))});
试一试{
使用WebResponse=wait request.GetResponseAsync();
返回response.GetResponseStream();
}捕获(例外情况除外){
var a=例如消息;
投掷;
}
//返回等待下载的WebDocument(uri);
}
此代码总是遇到异常。但是为什么呢

PS:

根据要求,这里是堆栈跟踪。内部没有例外

   bei System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
   bei System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- Ende der Stapelüberwachung vom vorhergehenden Ort, an dem die Ausnahme ausgelöst wurde ---
   bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   bei System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   bei DE.ZA.TrailerLoadingAssistant.Web.Code.WebHelper.<DownloadWebDocument>d__0.MoveNext() in C:\Users\Reichelt\source\repos\DE.ZA.TrailerLoading\DE.ZA.TrailerLoadingAssistant.Web\Code\WebHelper.cs:Zeile 28.
bei System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
bei System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar、Func`2 endFunction、Action`1 endAction、Task`1 promise、Boolean requiresSynchronization)
---这是一个非常有趣的故事---
bei System.Runtime.CompilerServices.TaskWaiter.ThrowForNonSuccess(任务任务)
bei System.Runtime.CompilerServices.TaskWaiter.HandleNonSuccessAndDebuggerNotification(任务)
bei System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
C:\Users\Reichlet\source\repos\DE.ZA.TrailerLoadingAssistant\DE.ZA.TrailerLoadingAssistant.Web.Code.WebHelper.d\u 0.MoveNext()中的bei DE.ZA.TrailerLoadingAssistant.Web\Code\WebHelper.cs:Zeile 28。

实际上,我使用不同的方法将报告呈现为PDF文档:

    public static byte[] DownloadAsPDF(string ReportServer, string ReportPath)
    {
        ReportViewer ReportViewer1 = new ReportViewer();
        ReportViewer1.ServerReport.ReportServerCredentials = new 
CustomReportCredentials("MyUsername", "MyPassword", "MyDomain");
        ReportViewer1.ProcessingMode = 
Microsoft.Reporting.WebForms.ProcessingMode.Remote;
        ReportViewer1.ServerReport.ReportServerUrl = new Uri(ReportServer);
        ReportViewer1.ServerReport.ReportPath = ReportPath;

       
        byte[] bytes = ReportViewer1.ServerReport.Render("PDF");

        return bytes;
    }

    public class CustomReportCredentials : 
    Microsoft.Reporting.WebForms.IReportServerCredentials
    {
        // local variable for network credential.    
        private string _UserName;
        private string _PassWord;
        private string _DomainName;
        public CustomReportCredentials(string UserName, string PassWord, 
string DomainName)
        {
            _UserName = UserName;
            _PassWord = PassWord;
            _DomainName = DomainName;
        }

        public System.Security.Principal.WindowsIdentity ImpersonationUser
        {
            get
            {
                return null;  // not use ImpersonationUser        
            }
        }

        public ICredentials NetworkCredentials
        {
            get
            {
                // use NetworkCredentials            
                return new NetworkCredential(_UserName, _PassWord, 
_DomainName);
            }
        }

        public bool GetFormsCredentials(out Cookie authCookie, out string 
user, out string password, out string authority)
        {
            authCookie = null;
            user = password = authority = null;
            return false;
        }
    }
我意识到,如果我使用request.Credentials=CredentialCache.DefaultCredentials,它就会工作。所以我的证件肯定有问题。但这绝对不是打字错误

我遇到了这个问题,似乎有人在更改网络权限。一周使用凭据可以正常工作,下一周使用DefaultCredentials可以正常工作。真的很奇怪,所以我加入了Try/Catch并求助于DefaultCredentials。如果服务帐户失败,请参阅代码注释:

public class SRSHelper
{
    private ReportingService2005 rsServ;
    private ReportingExecution2005 rsExec = new ReportingExecution2005();
    private ReportParameter[] reportParameters;
    private ExecutionInfo execInfo = null;

    public SRSHelper(string reportUserName, string decryptedPassword, string reportDomain, string reportServerURL)
     {
        rsServ = new ReportingService2005(reportServerURL);
        rsExec.Url = reportServerURL + @"ReportExecution2005.asmx";

        System.Net.NetworkCredential creds = new System.Net.NetworkCredential();
        creds.UserName = reportUserName;
        creds.Password = decryptedPassword;
        creds.Domain = reportDomain;
        rsExec.Credentials = creds;
        rsServ.Credentials = creds;
     }

    public ReportParameter[] GetSRSReportParameters(string reportName)
    {
        string report = "/Reporting/" + reportName;
        bool forRendering = false;
        string historyID = null;
        ParameterValue[] values = null;
        DataSourceCredentials[] credentials = null;

        try
        {
            return rsServ.GetReportParameters(report, historyID, forRendering, values, credentials);
        }
        catch
        {
            //If the Service Account credentials fail to work - try the users credentials - XYZ vendor regularly change things around or the network fails or for some reason beyond our control we have to change the settings.
            rsExec.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
            rsServ.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
            return rsServ.GetReportParameters(report, historyID, forRendering, values, credentials);
        }
            
    }

能否提供有关引发的异常的更多详细信息?堆栈跟踪、内部异常、错误代码、响应正文?@MathiasR.Jessen无内部异常。我将在上面添加堆栈跟踪。异常类型+消息?@MathiasR.Jessen它是一个
WebException
。消息是“Der Remoteserver hat einen Fehler zurückgeben:(401)Nicht autorisert.”状态字段设置为
ProtocolError
。我意识到,如果我使用
request.CredentialCache=CredentialCache.DefaultCredentials
,它会工作。所以我的证件肯定有问题。但绝对没有错,谢谢。我可以在哪个库中找到
CustomReportCredentials
类?抱歉,我刚刚将其添加到我的答案中。谢谢您的想法。它似乎起作用了。但是有没有办法以异步方式下载文件?构建报表大约需要一分钟左右的时间,因此它会长时间阻塞该服务器线程。