【问题标题】:How to post data from a webform page to an HTTPHandler.ashx file?如何将数据从 web 表单页面发布到 HTTPHandler.ashx 文件?
【发布时间】:2010-11-20 18:33:11
【问题描述】:

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

  • UploadHandler.ashx
  • 下载Handler.ashx

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

然而,我无法让自己的“测试 UI”(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 中的最新代码 sn-p:

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 元素的网络表单),然后尝试:

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

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

编辑更新: 我想我可以澄清我的问题。当从 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 方法将文件保存在我的网络服务器上的某个位置。我需要以某种方式 - 原谅这里的语言 - "re-post" 将这些数据放到一个完全不同的文件中 - 即我的 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);
}

【问题讨论】:

  • 如果我理解正确,您使用的是 ASP.NET 文件上传控件(它会进行回发)。但是您是否必须使用该控件?我的答案中显示的方法不适用于您的测试页吗?
  • @Martin - 它可能有效,但使用 FileUpload 控件显然是“较新”的做事方式,我不想重做我原来的 ASP.NET Web 应用程序中已有的技术.这是尝试使用额外的 BUTTON 扩展原始 Web 客户端,这将影响对 UploadHandler.ashx 的调用,其方式与从 ColdFusion 发布时相同。我希望这是有道理的。此外,我从来没有学会没有 FileUpload 控件的“老式方式”上传。

标签: c# asp.net post httpwebrequest httphandler


【解决方案1】:

约翰·高尔特,

做你想做的事的唯一方法是使用 HttpWebRequest。

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

您只需要注意“SendPhoto”功能,即可获得有关您必须做什么以使 HttpWebRequest 完成工作的提示。

【讨论】:

  • @Cleiton - 感谢您的意见。我关注了您的链接,并看到了您的示例。同时,我想我也得出结论(通过另一个例子),注入新表单和一些 Javascript 的类似技术也可能有效 - 请参阅:netomatix.com/Development/PostRequestForm.aspx
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    对不起,如果我遗漏了什么,但您不能简单地使用纯 HTML 表单将文件上传到您的处理程序:

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

    【讨论】:

    • @Martin - 谢谢。我记得有一段时间尝试过,但由于这个控件,我无法获得您建议的更简单的方法(即 FileUpload Web 控件似乎需要回发到自身来设置 FileUpload1.PostedFile 属性):
    • 请在原帖中查看我的 EDIT-UPDATE。
    • 我很难提供简洁的评论,但我认为这比您建议的答案更复杂。请参阅我所做的 EDIT-UPDATE 以及 Cleiton 和我的 cmets 的答案。这与“重新发布”的需要有关。
    猜你喜欢
    • 2019-08-02
    • 2015-04-18
    • 2015-05-05
    • 2010-09-17
    • 2015-02-18
    • 2011-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多