1

我正在通过 C# MVC 控制器返回一些 Json。其他浏览器工作正常,但 Internet Explorer (IE9) 尝试将返回的 Json 数据另存为文本文件。任何想法如何防止这种情况发生?

//MVC Controller Code...
return Json(new { redirectToUrl = Url.Action("Create", "Album",
                  new { url = url, isLocalFile = isLocalFile})});

//Clientside Javascript Code
$("#uploadImageForm").ajaxForm({
  beforeSubmit: function () {

  },
  success: function (data, textStatus, xhr) {
          window.location.href = data.redirectToUrl;
  },
  error: function (data, textStatus, xhr) {
  } 
});

我尝试将“text/plain”和“text/json”添加到 return Json 方法的第二个参数,它不起作用。

非常感谢!

4

2 回答 2

2

从插件的文档中引用:jquery.form

支持 XMLHttpRequest Level 2 的浏览器将能够无缝上传文件,甚至在上传过程中获得进度更新。对于较旧的浏览器,使用涉及 iframe 的后备技术,因为无法使用 XMLHttpRequest 对象的 1 级实现来上传文件。这是一种常见的后备技术,但它具有固有的局限性。iframe 元素用作表单提交操作的目标,这意味着将服务器响应写入 iframe。如果响应类型是 HTML 或 XML,这很好,但如果响应类型是脚本或 JSON,则效果不佳,这两种类型通常都包含在 HTML 标记中找到时需要使用实体引用来表示的字符。

为了解决使用 iframe 模式时脚本和 JSON 响应的挑战,Form Plugin 允许将这些响应嵌入到 textarea 元素中,建议您在与文件上传和旧版本结合使用时对这些响应类型这样做浏览器。但是请注意,如果表单中没有文件输入,则请求使用普通 XHR 提交表单(不是 iframe)。这给你的服务器代码增加了知道什么时候使用 textarea 什么时候不使用的负担。

这意味着如果您的表单包含文件输入字段并且您将此表单提交给返回 JSON 的控制器操作,则必须将此 JSON 包装在<textarea>标签中。

所以你的回复不应该是这样的:

{ "redirectToUrl":"some url" }

它应该是这样的:

<textarea>{ "redirectToUrl":"some url" }</textarea>

为了实现这一点,您可以使用自定义操作结果,该结果将使用这些标签包装响应:

public class TextareaJsonResult : JsonResult
{
    public TextareaJsonResult(object data)
    {
        this.Data = data;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        var response = context.HttpContext.Response;
        bool shouldWrap = !context.HttpContext.Request.IsAjaxRequest();
        if (shouldWrap)
        {
            response.Write("<textarea>");
        }

        base.ExecuteResult(context);

        if (shouldWrap)
        {
            response.ContentType = "text/html";
            response.Write("</textarea>");
        }
    }
}

然后让您的控制器操作返回此自定义结果:

[HttpPost]
public ActionResult Upload(HttpPostedFileBase file)
{
    // ... some processing

    var redirectToUrl = Url.Action(
        "Create", 
        "Album",
        new { url = url, isLocalFile = isLocalFile }
    );
    return new TextareaJsonResult(new { redirectToUrl = redirectToUrl });
}

现在显然在您的 AJAX 成功回调中,您还需要通过测试typeof result和在旧版浏览器(例如 Internet Explorer)的情况下手动解析响应来解释这种差异。您可以查看我链接到的页面的源代码。

但是话虽如此,我可以看到在您的成功回调中,您正在重定向到服务器返回的 JSON 响应中包含的控制器操作。我的问题来了:如果要重定向,首先使用 AJAX 有什么意义?为什么不使用标准表单发布到控制器操作并让控制器操作直接执行重定向?当您想留在同一页面上时,应该使用 AJAX。

于 2012-06-16T09:19:30.517 回答
1

我同意 Jesse 的评论,这可能是他提供的链接的副本。

因此,我将提供一个替代方案。我更喜欢使用类似于 fiddler http://www.fiddler2.com/fiddler2/的 http 代理查看通过网络传输的 json 。我提到提琴手是因为它适用于所有浏览器。优点是您可以获得解析后的 json 的树形视图。阅读和查找所需内容要容易得多。

另外,我相信firefox的firebug、chrome开发工具和ie开发工具都提供相同的功能。(我知道chrome有treeview,我想我记得firebug有它,如果考虑到其他2个现代IE没有它,我会感到惊讶。)

于 2012-06-16T06:17:21.340 回答