我繼承了一個應用程序,該應用程序使用Microsoft Web ReportViewer在本地運行小型報告。我們的應用程序允許您通過單擊將用戶路由到允許他們以PDF格式下載報告的URL的特定按鈕來「預覽/打印」報告。我們最近收到了將這些PDF保存到數據庫中的文檔表的要求。我已經能夠在localhost上成功運行了;然而,當我發佈應用程序到我們的IIS服務器,我收到以下錯誤:本地ReportViewer在不必要的數據庫登錄時失敗
System.Data.SqlClient.SqlException: Login failed for user 'Domain\Servername$'.
我查看了所有的網站,我能找到涉及這個錯誤(包括this one) - 最點添加服務器帳戶到SQL數據庫;然而,這不應該成爲一個問題,因爲預覽/打印文檔的按鈕仍然可以正常工作,並在應用程序發佈時按預期工作,並且所有數據都保存在本地對象中,該對象先前已從數據庫中提取(下面的模型參數)。按鈕和自動生成功能使用相同的兩種方法創建PDF文檔(請參見下文)。
下面是一些代碼:
public static byte[] CreatePDFDocument(DocumentTemplateType template, Request model)
{
Warning[] warnings;
string[] streamIds;
string mimeType = string.Empty;
string encoding = string.Empty;
string extension = string.Empty;
ReportViewer viewer = new ReportViewer();
viewer.ProcessingMode = ProcessingMode.Local;
viewer.LocalReport.ReportEmbeddedResource = "Xxx.Xxx.Bll.ReportViewerRDLCs." + template.RdlcFilename;
switch ((DocumentType)template.DocumentTypeId)
{
case eDocumentType.Report1:
viewer.LocalReport.SetParameters(GetForm1Parameters(model));
break;
/**
* Several other reports are in this switch. All reports have the
* same issue - all but one are removed for brevity.
*/
}
byte[] bytes = viewer.LocalReport.Render("PDF", null, out mimeType, out encoding, out extension, out streamIds, out warnings);
return bytes;
//return new byte[5] {5,6,7,8,9}; - used for troubleshooting.
}
public static List<ReportParameter> GetReport1Parameters(Request model)
{
List<ReportParameter> rptParams = new List<ReportParameter>();
//Start comment
rptParams.Add(new ReportParameter("EmployeeFullName", string.Format("{0:NN}", model.Employee)));
rptParams.Add(new ReportParameter("EmployeePhoneNumber", string.Format("{0:(###) ###-####}", Convert.ToInt64(model.Employee.PhoneNumber))));
rptParams.Add(new ReportParameter("HrchyShortDesc", model.Employee.HrchyShortDesc));
rptParams.Add(new ReportParameter("RequestDate", model.RequestDate.ToShortDateString()));
rptParams.Add(new ReportParameter("RequestRequested", model.RequestRequestType));
rptParams.Add(new ReportParameter("ReasonForRequest", model.RequestRequestReason));
rptParams.Add(new ReportParameter("LogNumber", model.CaseId));
if (!string.IsNullOrWhiteSpace(model.TimeSensitiveReason)) rptParams.Add(new ReportParameter("TimeSensitiveReason", model.TimeSensitiveReason));
var lastAction = model.LastActionOfType(WorkflowStateActionType.EmployeeConfirmation);
if (lastAction != null)
{
rptParams.Add(new ReportParameter("TodaysDate", lastAction.ActionDate.ToShortDateString()));
rptParams.Add(new ReportParameter("EmpConfirmed", "true"));
}
else rptParams.Add(new ReportParameter("TodaysDate", DateTime.Now.ToShortDateString()));
//end comment
return rptParams;
}
通過大量的評論和退出,並推到我們的服務器,我已經推導出以下幾點:
- 從我所知道的,錯誤調用GetReport1Parameters時發生。在上面的代碼中,我包含了一個開始和結束註釋 - 我已經註釋掉了它們之間的所有內容,只留下列表初始化和返回語句(空列表),但仍然收到錯誤。
- 我已經註釋掉了對GetReport1Parameters的調用,並返回了一個無意義的字節數組,並且沒有收到異常。
- 所有的功能在localhost上都能正常工作,當我逐步完成這些功能時,所有的變量都顯得很正常。
事情我已經嘗試做亡羊補牢: 1.從app.config中刪除的連接字符串,使應用程序去web.config文件以獲得正確的字符串(即使他們是一樣的)。 2.評論不同部分的代碼以確定問題區域。 3.嘗試調用GetReport1Parameters方法並返回null,導致空引用異常。 4.嘗試使用空參數列表調用GetReport1Parameters,導致上述錯誤。 5.嘗試運行報告沒有參數(甚至沒有空白列表),得到ReportProcessingException缺少參數。
一些額外的信息:
- 我們使用服務帳戶在web.config中使用冒充身份的申請。該行在localhost上被註釋掉,但在IIS上運行。
- 所有其他數據庫交互都能正常工作。
- 我們所有的數據庫交互操作都是使用LINQ to SQL完成的 - 模型是一個基於數據庫表的對象,具有一些動態計算的附加信息。
我希望的結果是自動生成的文檔和預覽/打印文檔都可以工作。我有一種感覺,這可能是我忽略的簡單事情,但我今天已經花了幾個小時試圖解決這個問題。
我想不出任何其他相關信息,但如果您有任何疑問,我會很樂意回答。
編輯:其他試圖找到解決方案:
嘗試設置LINQ延遲加載等於假。這造成了比解決問題更多的問題。
實施了IReportServerCredentials,併爲ReportViewer的ServerReport.ReportServerCredentials分配了正確的數據庫憑證。
將所有相關的報告參數分配給Dictionary,然後在每個對象上調用.ToString()以確保它從數據庫中被拉出。然後將字典中的字符串分配給報告參數,以便ReportViewer應該從字符串池接收數據,而不是從數據庫中提取數據。
你是否附加了一個調試器,並在返回之前查看rptParams? – Chris
我還沒有嘗試遠程調試,但是當我在本地主機上調試時,所有參數似乎都正確返回。正如我在上面的回答中所提到的,傳遞到創建報告參數的方法的對象在打印/預覽選項和自動生成選項上都是相同的。 – floppsb
這是否在本地主機上或僅在部署時失敗? – Chris