使用JQuery和ASP.NET通用处理程序进行文件上传 - 可行吗?

7

我希望你能帮我解决一个小问题。我使用大部分客户端(JQuery/JavaScript)代码构建了一个完整的ASP.NET Web应用程序。我使用通用处理程序来进行一些数据的懒加载,以及自动完成等功能。

其中一个要求是某个页面需要能够上传文件,并显示有关上传文件的元信息。

我想知道是否有一种方法可以完全使用JQuery/JavaScript来上传文件。我研究了许多插件,但它们都依赖于具有php后端。

我的想法是创建一个post:

$(function(){
    $('#submit').live('click', function(event){

        $.post('/SomeOtherHandler.ashx',  //can be '/someotherpage.aspx'
        { 
            filename: $('#fileUpload').val(), 
            timestamp: (new Date()).toString() 
        }, function(data){
             //do something if the post is successful.
        });

    });
});

这样行吗?我知道如果包含 json 对象 { filename: value, timestamp: value },它将显示在 HttpContext.Request.Params 集合中,我可以毫无问题地读取它。
但是问题在于,由于 FileUpload html 控件仅在其值中存储文件名,因此我将发送一个包含文件名的字符串而不是字节数组到我的服务器。
如果您有任何想法,请不吝赐教!

请纠正我,但无论何时使用<input type="file".../>,都会创建一种特殊类型的POST:其中提供了文件的MIME类型以及其他一些内容。该POST将被发送到您的 <form action="".../>指向的位置。当你点击一个 <input type="submit".../> 时,整个表单的内容通过http POST发送到服务器端代码,包括文件位。我不是要求从JavaScript中抓取文件,而只是要重新创建该http POST,以便我的处理程序/页面可以从<input type="file".../>字段获取数据。 - bleepzter
JavaScript 无法提交带有文件输入类型的表单,它将无法上传文件。 - Jeremy B.
我遇到了类似的问题。通过使用File对象,实现HTML5的拖放功能非常简单。但是,对于那些不支持拖放功能的浏览器(主要是IE和旧版本浏览器),我的<input type='file' />仍然存在问题。我还在努力寻找解决方法。 - harsimranb
6个回答

4

我正在使用uploadify插件(http://www.uploadify.com/) - 正如Jeremy所说,它不是JavaScript编写的 - 这是不可能的。它是用Flash编写的。它非常容易安装。

$('#file_upload').uploadify({
   'uploader'  : '/uploadify/uploadify.swf',
   'script'    : '/uploadify/uploadify.ashx',
   'cancelImg' : '/uploadify/cancel.png',
   'folder'    : '/uploads',
   'auto'      : true,      
   'fileExt': '*.xls;*.xlsx;*.csv',
   'buttonText': 'Select your file',
   'onError'     : function (event,ID,fileObj,errorObj) {

  alert(errorObj.type + ' Error: ' + errorObj.info);

},
'onComplete'  : function(event, ID, fileObj, response, data) 
                {
                    var obj = jQuery.parseJSON(response);
                    if (obj.error != "" & obj.errror != null)
                    {
                        lblTable.html("error : " + obj.error);
                    }
                    else


                    {
                        lblTable.html(obj.table);
                       lblEditData.show();
                       lblTable.hide();
                    }

                }
 });

在uploadify.ashx文件中:
public class uploadify : IHttpHandler
{

    public void ProcessRequest(HttpContext context)
    {
        System.Web.HttpPostedFile file = context.Request.Files["Filedata"];

        //Check extension
        string extension = "";
        try
        {
            extension = file.FileName.Split('.')[file.FileName.Split('.').Length - 1];
            if (extension != "xls" & extension != "xlsx" & extension != "csv") throw new Exception("Error of the extension");
        }
        catch
        {
            context.Response.Write("{\"error\",\"Error with the extension of the file\"");
        }


        string linkFile = System.Web.HttpContext.Current.Server.MapPath("~") + "uploads" + "\\" + DateTime.Now.ToString("yyMMddHHmm") + APIReportPro.DocumentPDF.RandomString(4) + "." + extension;

        file.SaveAs(linkFile);


  ...etc...

我找到了最好的asp.net解决方案。


快速问题...是否可以将以下内容动态添加到脚本的URL中:/uploadify/uploadify.ashx?type=create&val1=val1&val2=val2...?否则会出现竞争条件。如果需要val1和val2以及要保存到SQL的文件流,则您无法确定文件是否首先上传,或者val1和val2是否及时到达... - bleepzter
1
我不确定我理解你的意思... 我没有尝试过,但猜测你可以在你的get查询中添加参数到/upladify.ashx。 - Zitun
@Zitun 你可以使用 System.IO.Path.GetExtension 来获取文件扩展名。 - Alexandre

3

上传文件到服务器时,你有三种选择:使用原生的html文件上传功能、Flash或Java。Javascript无法将文件上传到服务器,它只能装饰内置的html功能。假设你想模仿ajax上传功能,那么可以使用iframe来上传文件,这样看起来就像是在使用ajax。

你需要创建一个表单。

<form id="file_upload_form" method="post" enctype="multipart/form-data" action="upload.aspx">
    <input name="file" id="file" size="27" type="file" /><br />
    <input type="submit" name="action" value="Upload" /><br />
    <iframe id="upload_target" name="upload_target" src="" style="width:0;height:0;border:0px solid #fff;"></iframe>
</form>

这个表单使用iframe来上传文件,这样主页面就不会刷新。您可以连接jquery来处理iframe返回的响应并处理用户信息。

如果这不是您要解决的问题,请随时评论并澄清您想要完成的任务。


1
那么如何使用iframe呢?只需将表单的action指向“upload.aspx”即可。 - bleepzter

2
如果您可以指定应用程序可以通过哪些浏览器访问(例如,它是一种内部业务应用程序),那么值得查看最新浏览器中出现的“HTML5”技术堆栈的一部分 - 新的文件API。这使您可以通过客户端JavaScript直接访问文件,而无需首先将文件发布到服务器。
如果您的应用程序面向公众,则仍然可以使用文件API,但您需要在代码中检查是否支持它,并为那些使用较旧浏览器的用户应用某种后备机制(例如Uploadify)。
您可以在其他地方这里这里阅读有关文件API的更多信息。

哇,如果这个得到广泛支持就太好了...我们已经等了很长时间来处理上传的一个体面的方式。 - Chris B. Behrens
我认为这是一个会长期存在的技术,前提是它不会遇到重大安全问题 - 它已经被一些大型网站(例如Box.net)使用。是时候了! - Luke Bennett
2
我支持Chrome、Safari和Firefox在我的站点上使用它。 它效果很好。太遗憾了IE9对此不再支持。Opera不支持File API,但它们支持在文件输入上的多个属性。 - Todd Smith
我本来要发帖子:“你猜哪个主流浏览器不支持这个功能,相比市场上其他所有浏览器!” - Chris B. Behrens

1

我非常确定这是不可能的;如果可以的话,那么这将是一个巨大的安全漏洞 - Javascript 不应该能够从用户的硬盘获取字节。

因此,您只能使用本机输入类型=file或使用预先存在的桌面字节,例如 Flash。几个流行的上传器使用此方法... 我最喜欢的是 Uploadify。看看它,看看它是否适合您的需求。

希望对您有所帮助。


Uploadify 依赖于 PHP 后端。 - bleepzter
2
完全不是问题 - 我在 ASP.Net 中已经多次使用过这个:http://www.uploadify.com/forums/discussion/45/asp.net-c-code-to-replace-upload.php-upload.ashx/p1。 - Chris B. Behrens
抱歉,bleepzter,你是错误的 - Uploadify不需要PHP。 - Luke Bennett

0

使用jQuery,您可以做类似以下的事情:

<input type="file" name="file" id="file1" runat="server" />

$("#<%=file1.ClientID%>").change(function () {
  //Do stuff
   $(this).upload('youHandler.ashx', function (res) {
     //do stuff on success
   }
}

现在在yourHandler.ashx文件中,你可以这样做:

public void ProcessRequest(HttpContext context)
{
   if (context.Request.Files.Count > 0)
   {
      var fileCount = context.Request.Files.Count;
      var fileStram = var file = context.Request.Files[0].InputStream;

      //Do whatever you want
   }
}

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接