【问题标题】:How do I prevent IE save file dialog when using fileupload in asp.net mvc在asp.net mvc中使用fileupload时如何防止IE保存文件对话框
【发布时间】:2012-03-14 03:34:51
【问题描述】:

当我尝试使用 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;
    }

查看下面的代码(摘要):

<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();
            }
        }

    }

【问题讨论】:

  • 您调用此操作的方式可能有误。有机会看到您的视图代码吗?你的javascript呢?也许您正在使用一些客户端文件上传组件(因为您使用 Ajax)?这个组件与 IE 兼容吗?从控制器操作返回 null 也不是一个好主意。如果客户端代码期望响应是某种特定格式(例如 JSON)返回 null 肯定会破坏它。
  • 嗨达林,我已经添加了视图代码。我正在使用 Jquery 的 ajaxForm。不确定这是否与它有关...
  • 哦,是的,这与您的问题有很大关系。看我的回答。

标签: asp.net-mvc internet-explorer file-upload opera


【解决方案1】:

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

由于无法使用浏览器的 XMLHttpRequest 对象,Form Plugin 使用隐藏的 iframe 元素 帮助完成任务。这是一种常见的技术,但它具有固有的 限制。 iframe 元素用作表单的目标 提交操作,这意味着服务器响应被写入 内嵌框架。如果响应类型是 HTML 或 XML,这很好,但是 如果响应类型是脚本或 JSON,则两者都不起作用 通常包含需要使用实体来表示的字符 在 HTML 标记中找到时的引用。

为了解决脚本和 JSON 响应的挑战,表单 插件允许将这些响应嵌入到 textarea 元素中,并且 建议您在使用这些响应类型时这样做 与文件上传结合。但请注意,如果有 表单中没有文件输入,则请求使用普通 XHR 提交 表单(不是 iframe)。这会给您的服务器代码带来负担 知道何时使用文本区域,何时不使用。

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

<textarea>{"foo":"bar"}</textarea>

代替:

{"foo":"bar"}

此外,在这种情况下,您不应使用 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";
    }
}

然后:

[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" });
}

现在您可能还需要调整成功处理程序以去除 &lt;textarea&gt; 标记:

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

【讨论】:

  • 感谢您的建议。我会试一试。你知道为什么我的代码可以在 FF 和 Chrome 中运行吗?为什么 IE 是个问题?
  • 我想 Firefox 和 Chrome 将 JSON 响应视为文本,并将其显示在 IFRAME 中。这不是一个好方法,因为它通常会被解析并放入一个简单的 HTML 文档中,如果通过 DOM 读回某些字符可能会变成 HTML 实体..
  • 这就是诀窍......然后我不得不解析我的 JSON 结果,但它起作用了......谢谢
  • @user1202717,那么也许您可以考虑接受my answer,除非您当然还有其他问题?
【解决方案2】:

我在使用 IE8 时遇到了同样的问题,这个答案对我帮助很大。但我需要进行一些在 IE8、Chrome 和 Firefox 中运行良好的更改。

按照以下更改:

success: function (responseText) {
    try{
        var response = $.parseJSON(responseText);
        //code ...
    }    
    catch(ex) {
        //error code
    }
}

[HttpPost]
public JsonResult Upload(HttpPostedFileBase file) {
    //code
    return Json(new { Success = "true", Message = "Done!" }, "text/html");
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-09
    • 1970-01-01
    • 1970-01-01
    • 2015-10-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多