在asp.net mvc中使用fileupload时,如何防止IE保存文件对话框

jaf*_*ffa 4 asp.net-mvc opera internet-explorer file-upload

当我尝试使用ASP.NET MVC上传文件时,它在FF && Chrome中工作正常,但在IE和Opera中弹出一个对话框,要求我下载,保存或取消.

选择其中一个选项可防止文件上载工作.我怎样才能解决这个问题?

 public class ImportModel
    {                     
        [Required]
        [FileExtensions("csv", ErrorMessage = "Please upload a valid .csv file")]
        public HttpPostedFileBase File { get; set; }
    }



[HttpPost]
    public virtual ActionResult StartImport(ImportModel model = null)
    {
        if (model != null)
        {
            var status = _importService.StartImport(model);
            return Json(status, JsonRequestBehavior.AllowGet);
        }
        return null;
    }
Run Code Online (Sandbox Code Playgroud)

查看以下代码(摘要):

<div id="dlgImport" class="hidden">

        @using (Html.BeginForm(MVC.Import.StartImport(), FormMethod.Post, new { @class = "smallForm", id = "frmImport", enctype = "multipart/form-data" }))
        {            
            <div class="fields-inline">
                <div class="editor-label">
                    @Html.Label("File")
                </div>
                <div class="editor-field">
                    @Html.TextBoxFor(x => x.File, new { @class="input-file", type = "file" })
                    @Html.ValidationMessageFor(x => x.File)
                </div>              
            </div>
        }
    </div>

</div>



$(function() {
        $("#frmImport").ajaxForm({
            success: function (responseHtml) {
                // response is wrapped in pre tags by the browser - the ajax upload is carried out using an iframe                                                
                var response = $.parseJSON($(responseHtml).text());
            }
        });
});


 var vm = {

        startImport: function () {

            if ($("#frmImport").valid()) {                
                $("#frmImport").submit();
            }
        }

    }
Run Code Online (Sandbox Code Playgroud)

Dar*_*rov 13

现在您已经发布了代码,看起来您正在使用jquery表单插件.如文档中所述,此插件支持使用AJAX上传文件但您无法从服务器端脚本返回JSON:

由于无法使用浏览器的XMLHttpRequest对象上载文件,因此Form Plugin使用隐藏的iframe元素来帮助完成任务.这是一种常见的技术,但它具有固有的局限性.iframe元素用作表单提交操作的目标,这意味着服务器响应被写入iframe.这是好的,如果响应类型是HTML或XML,但如果数据类型是script或JSON,两者一般都需要用实体引用来repesented在HTML标记时发现字符不正常工作.

为了解释的脚本和JSON响应的困难,这个插件允许嵌入到textarea元素,这些反应,所以建议您在与一起选择文件上传使用时,这些响应类型这样做.但请注意,如果表单中没有文件输入,则请求使用普通XHR提交表单(而不是iframe).这会给您的服务器代码带来负担,以便知道何时使用textarea以及何时不使用.

所以基本上你的上传控制器动作应该响应:

<textarea>{"foo":"bar"}</textarea>
Run Code Online (Sandbox Code Playgroud)

代替:

{"foo":"bar"}
Run Code Online (Sandbox Code Playgroud)

此外,application/json在这种情况下,您不应使用响应内容类型.

您可以编写自定义操作结果来实现:

public class FileJsonResult : JsonResult
{
    public FileJsonResult(object data)
        : base()
    {
        Data = data;
        JsonRequestBehavior = JsonRequestBehavior.AllowGet;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        context.HttpContext.Response.Write("<textarea>");
        base.ExecuteResult(context);
        context.HttpContext.Response.Write("</textarea>");
        context.HttpContext.Response.ContentType = "text/html";
    }
}
Run Code Online (Sandbox Code Playgroud)

然后:

[HttpPost]
public virtual ActionResult StartImport(ImportModel model = null)
{
    if (model != null)
    {
        var status = _importService.StartImport(model);
        return new FileJsonResult(status);
    }
    new FileJsonResult(new { status = false, errorMessage = "The model was null" });
}
Run Code Online (Sandbox Code Playgroud)

现在,您可能还需要调整成功处理程序以剥离<textarea>标记:

$('#frmImport').ajaxForm({
    success: function (responseHtml) {
        var responseHtml = responseHtml
            .replace(/\<textarea\>/i, '')
            .replace(/\<\/textarea\>/i, '');
        var response = $.parseJSON(responseHtml);
        // do something with the response
    }
});
Run Code Online (Sandbox Code Playgroud)