如何将数据从webform页面发布到HTTPHandler.ashx文件?

时间:2009-08-18 21:56:52

标签: c# asp.net post httpwebrequest httphandler

我有一个Web应用程序项目,支持对供应商产品后端的文件传输操作。它由2个HTTPHandler文件组成,这些文件被编译到带有IIS 6.0的Win2003服务器上的网站:

  • UploadHandler.ashx
  • DownloadHandler.ashx

这些文件从暴露用户界面的ColdFusion网站上“发布到”。在某种程度上,我的工作已经完成,因为这些处理程序工作并且必须从ColdFusion调用。

然而,我非常沮丧,因为我无法将自己的“测试用户界面”(default.aspx)用于独立于ColdFusion的测试/优化。

<asp:Button ID="DownloadButton" PostBackUrl="~/DownloadHandler.ashx"  runat="server" Text="Download"/>

使用PostBackUrl进行下载非常有效 - 当输入DownloadHandler.ashx时,它会在 context.Request.Form [“txtRecordNumber”]中找到其键输入值;

但是我无法使用这种技术进行上传,因为我必须进行一些处理 (以某种方式将所选fileupload1.postedfile中的字节读入FORM变量,这样我的UploadHandler.ashx文件就可以从中获取输入Request.Form和下载一样)

My first approach tried using HTTPWebRequest看起来过于复杂,我无法开始工作。症状从HTTP 401状态代码开始,然后变成302状态代码,因此我研究了其他想法。

以下是我的default.aspx中的最新代码段:

protected void UploadHandlerButton_Click(object sender, EventArgs e)
{
    if (FileUpload1.HasFile)
    {
        try
        {
            BuildFormData();
            //Server.Transfer("UploadHandler.ashx", true);
            Response.Redirect("~/UploadHandler.ashx");
        }
        catch (Exception someError)
        {
            LogText("FAILURE: " + someError.Message);
        }
    }
}
protected void BuildFormData()
{
    BinaryReader b = new BinaryReader(FileUpload1.PostedFile.InputStream);
    int numBytes = FileUpload1.PostedFile.ContentLength;
    byte[] fileContent = b.ReadBytes(numBytes);
    objBinaryData.Text = System.Text.Encoding.UTF8.GetString(fileContent);
    b64fileName.Text = FileUpload1.PostedFile.FileName;
    // create arbitrary MetaData in a string
    strMetaData.Text = "recAuthorLoc=anyname1~udf:OPEAnalyst=anyname2~udf:Grant Number=0102030405";
}

尝试在我的.ashx文件中使用Server.Transfer(上面)导致错误:     执行UploadHandler.ashx的子请求时出错

尝试在我的.ashx文件中使用Response.Redirect(上面)导致GET(而不是POST),而Trace.axd当然在Form集合中没有显示任何内容,所以这似乎也是错误的。

我甚至尝试克隆我的.ashx文件并创建了UploadPage.aspx(一个没有HTML元素的webform),然后尝试了:

Server.Transfer("UploadPage.aspx", true);
//Response.Redirect("~/UploadPage.aspx");

这些都不允许我在处理上传请求的代码中看到我需要在Request.Form中看到的表单数据。我显然在这里遗漏了一些东西......在此先感谢您的帮助。

修改-UPDATE: 我想我可以澄清我的问题。当从ColdFusion发布UploadHandler.ashx时,它所需的所有输入都可以在FORM集合中使用(例如Request.Form [“fileData”]等。)

但是当我使用这个 控件时,它会生成一个回发到我的启动网页(即default.aspx)。这使我能够通过 FileUpload1.PostedFile 来引用内容,如下所示:

protected void BuildFormData()
{
    BinaryReader b = new BinaryReader(FileUpload1.PostedFile.InputStream);
    int numBytes = FileUpload1.PostedFile.ContentLength;
    byte[] fileContent = b.ReadBytes(numBytes);
    objBinaryData.Text = System.Text.Encoding.UTF8.GetString(fileContent);
    b64fileName.Text = FileUpload1.PostedFile.FileName;
}

然而,我没有使用 FileUpload1.PostedFile.SaveAs方法将文件保存在我的Web服务器上。我需要以某种方式 - 原谅这里的语言 - “重新发布” 这个数据到一个完全不同的文件 - 即我的UploadHandler.ashx处理程序。我上面尝试的所有愚蠢技术都无法实现我的需要。

EDIT-UPDATE(2009年8月20日) - 使用Javascript的最终解决方案:

protected void UploadHandlerButton_Click(object sender, EventArgs e)
{
    if (FileUpload1.HasFile)
    {
        try
        {
            ctlForm.Text = BuildFormData();
            String strJS = InjectJS("_xclick");
            ctlPostScript.Text = strJS;
        }
        catch (Exception someError)
        {
            LogText("FAILURE: " + someError.Message);
        }
    }
}
private String InjectJS(String strFormId)
{
    StringBuilder strScript = new StringBuilder();
    strScript.Append("<script language='javascript'>");
    strScript.Append("var ctlForm1 = document.forms.namedItem('{0}');");
    strScript.Append("ctlForm1.submit();");
    strScript.Append("</script>");
    return String.Format(strScript.ToString(), strFormId);
}
protected string BuildFormData()
{
    BinaryReader b = new BinaryReader(FileUpload1.PostedFile.InputStream);
    int numBytes = FileUpload1.PostedFile.ContentLength;
    byte[] fileContent = b.ReadBytes(numBytes);
    // Convert the binary input into Base64 UUEncoded output.
    string base64String;
    base64String =
           System.Convert.ToBase64String(fileContent,
                                         0,
                                         fileContent.Length);
    objBinaryData.Text = base64String;
    b64fileName.Text = FileUpload1.PostedFile.FileName;
    // create arbitrary MetaData in a string
    strMetaData.Text = "recAuthorLoc=Patterson, Fred~udf:OPEAnalyst=Tiger Woods~udf:Grant Number=0102030405";

    StringBuilder strForm = new StringBuilder();
    strForm.Append("<form id=\"_xclick\" name=\"_xclick\" target=\"_self\" action=\"http://localhost/HTTPHandleTRIM/UploadHandler.ashx\" method=\"post\">");
    strForm.Append("<input type=\"hidden\" name=\"strTrimURL\"    value=\"{0}\" />");
    strForm.Append("<input type=\"hidden\" name=\"objBinaryData\" value=\"{1}\" />");
    strForm.Append("<input type=\"hidden\" name=\"b64fileName\"   value=\"{2}\" />");
    strForm.Append("<input type=\"hidden\" name=\"strDocument\"   value=\"{3}\" />");
    strForm.Append("<input type=\"hidden\" name=\"strMetaData\"   value=\"{4}\" />");
    strForm.Append("</form>");
    return String.Format(strForm.ToString()
        , txtTrimURL.Text
        , objBinaryData.Text
        , b64fileName.Text
        , txtTrimRecordType.Text
        , strMetaData.Text);
}

3 个答案:

答案 0 :(得分:0)

很抱歉,如果我遗漏了某些内容,但您不能简单地使用纯HTML表单将文件上传到处理程序:

<form action="UploadHandler.ashx" method="post" enctype="multipart/form-data">
  Choose file to upload:
  <input name="file" type="file" size="50">
</form>

答案 1 :(得分:0)

John Galt,

执行所需操作的唯一方法是使用HttpWebRequest。

Here是一个做你想要的类的好例子。我已经将图像和表单值发送到picassa服务了一段时间(我知道我可以使用Picassa API,但我这样做是为了好玩)。

您只需要注意“ SendPhoto ”功能,以获取有关使HttpWebRequest完成工作所需做的提示。

答案 2 :(得分:0)

对我来说有用的是注入一个新的FORM和一些Javascript来将FORM提交给UploadHandler.ashx。这(对我来说)比HTTPWebRequest技术更容易掌握。