如何在服务器上打开本地htm文件

时间:2012-07-25 18:28:40

标签: c# asp.net iis-7 webserver file-permissions

我们的应用程序将合同文件保存到C:\ Contracts。合同在aspx网页上填写,一旦提交,合同将作为.htm文件保存到该目录,合同的文件路径存储在OnlineCustomerDocuments对象中,然后发送到数据库。稍后,我们希望能够通过Web应用程序在Web浏览器中打开这些合同。客户显示在gridview中,每行都有合同链接。

这是我现在打开合同的代码:

 protected void grdWebs_RowCommand(object sender, GridViewCommandEventArgs e)
    {
        int intId = 0;
        Web objWeb = new Web();
        try
        {
            string strContractFilePath;
            GridViewRow row1;
            List<OnlineCustomerDocuments> lstOnlineCustomerDocuments;
            OnlineCustomerDocuments contract;
            string strContractpath;
            switch (e.CommandName)
            {
                case "View_Details":
                //GridViewRow row = (GridViewRow) (((Button)e.CommandSource).NamingContainer);
                  GridViewRow row = (GridViewRow)(((LinkButton)e.CommandSource).NamingContainer);
                intId = Convert.ToInt32(grdWebs.DataKeys[row.RowIndex].Value.ToString());
                Response.Redirect("DetailsForm.aspx?Id=" + intId.ToString(), false);
                break;
            case "Print_Contract":                    
                strContractFilePath = ConfigurationManager.AppSettings["CustomerContractsDirectory"].ToString();
                row1 = (GridViewRow)(((LinkButton)e.CommandSource).NamingContainer);
                intId = Convert.ToInt32(grdWebs.DataKeys[row1.RowIndex].Value.ToString());
                objWeb = QDServiceHelper._QDClient.GetDetails(intId);
                lstOnlineCustomerDocuments = QDServiceHelper._QDClient.GetOnlineCustomerDocumentsByID(intId);
                contract = lstOnlineCustomerDocuments.ElementAt(0);
                strContractpath = contract.DocumentFileName;                    
                System.Diagnostics.Process.Start(strContractpath);                    
                break;                
            default:
                break;            
            }
        }
        catch (Exception ex)
        {
            log.Error(ex.ToString());
        }           
    }

按钮启动合同:

 <asp:LinkButton ID="btnPrintContract" runat="server"  CommandName="Print_Contract" Text="View Signed Contract" width="100px" CssClass ="GeneralHyperlink"></asp:LinkButton>

基本上,抓取所选行,并抓取该客户ID的合同。在本地计算机上测试应用程序时,会创建合同,正确更新数据库,并且可以打开合同。但是,当我将应用程序发布到Web服务器时,我无法打开合同。代码执行到Process.start(),但没有任何反应。我检查了文件路径,并且链接按钮的__doPostBack是正确的。我唯一能想到的是存在一些许可问题。如果是这样的话,最好尝试使用asp.net模拟等方法来确定如何授予这些权限,还是有更好的方法?

更新 *

所以我试着读取html文档,并使用像nathan建议的响应写入,但我真的需要在新窗口中打开合同,并且desoite尝试了几个不同的window.open方法我无法让它工作。我最终按照建议设置了一个虚拟目录,现在一切都很好。更新了以下代码。感谢nathan的所有帮助。

string strContractFilePath;
            GridViewRow row1;
            List<OnlineCustomerDocuments> lstOnlineCustomerDocuments;
            OnlineCustomerDocuments contract;
            string strfileName;
            string file;
            string pathlead;
            string vDir = "/Webfiles/";

            switch (e.CommandName)
            {
                case "View_Details":
                    //GridViewRow row = (GridViewRow) (((Button)e.CommandSource).NamingContainer);
                    GridViewRow row = (GridViewRow)(((LinkButton)e.CommandSource).NamingContainer);
                    intId = Convert.ToInt32(grdWebs.DataKeys[row.RowIndex].Value.ToString());
                    Response.Redirect("DetailsForm.aspx?Id=" + intId.ToString(), false);
                    break;
                case "Print_Contract":
                    strContractFilePath = ConfigurationManager.AppSettings["CustomerContractsDirectory"].ToString();
                    row1 = (GridViewRow)(((LinkButton)e.CommandSource).NamingContainer);
                    intId = Convert.ToInt32(grdWebs.DataKeys[row1.RowIndex].Value.ToString());
                    lstOnlineCustomerDocuments = QDServiceHelper._QDClient.GetOnlineCustomerDocumentsByID(intId);
                    contract = lstOnlineCustomerDocuments.ElementAt(0);
                    strfileName = contract.DocumentFileName;

                    //path to the virtual directory on server                       
                    pathlead = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority);
                    if (HttpContext.Current.Request.Url.AbsoluteUri.Contains("CA"))
                    {
                        vDir = "/CA/WebFiles/CA1003/Contracts/";
                        file = pathlead + vDir + strfileName;
                        //Response.Redirect("~/WebFiles/contract.htm");

                        Response.Write("<script>");
                        Response.Write("window.open('" + file + "','_blank')");
                        Response.Write("</script>");
                    }
                    //For testing on local machines
                    else
                    {
                        System.Diagnostics.Process.Start(strContractFilePath + strfileName);
                    }

                    break;

1 个答案:

答案 0 :(得分:2)

System.Diagnostics.Process.Start(strContractpath);

这将打开不在客户端上的服务器上的文档。由于您在本地测试它是有效的,因为您是服务器客户端

换句话说,这行代码只是在服务器上启动一个进程(在这种情况下是一个Web浏览器,因为默认情况下它与.htm文件相关联)。当您在本地测试时,您看到页面处于打开状态,因为您的计算机充当server,但这实际上并不是将页面提供给客户端,它只是打开一个程序。当您将此发布到服务器时,您无法看到进程启动,因为它发生在服务器上,得到了它?

您真正想要做的是通过网络服务器将文件内容提供给客户端。

我正在考虑一种可以实现这一目标的方法。


您可以在IIS中创建虚拟目录并将其指向包含这些文件的目录,然后在您的回复中执行Response.Redirect(<URL to file>);

或者您可以获取文件的内容并将其填充到响应中。我个人从未这样做,但SO这篇文章可能会指出你正确的方向。在我看来,这可能是您的最佳选择,因为您不必更改任何服务器设置。

修改

以下是 可以完成此操作的示例。请注意,这是未经测试的,因为我没有网络环境。

...
case "Print_Contract":
     strContractFilePath = ConfigurationManager.AppSettings["CustomerContractsDirectory"].ToString();
     row1 = (GridViewRow)(((LinkButton)e.CommandSource).NamingContainer);
     intId = Convert.ToInt32(grdWebs.DataKeys[row1.RowIndex].Value.ToString());
     objWeb = QDServiceHelper._QDClient.GetDetails(intId);
     lstOnlineCustomerDocuments = QDServiceHelper._QDClient.GetOnlineCustomerDocumentsByID(intId);
     contract = lstOnlineCustomerDocuments.ElementAt(0);
     strContractpath = contract.DocumentFileName;                    

     //System.Diagnostics.Process.Start(strContractpath);

     StreamReader sr = new StreamReader(strContractpath);
     while(sr.Peek() >= 0)
     {
          line=sr.ReadLine();
          Response.Write(line);
     }

     break;               
...