Asp.Net MVC2 RenderAction改变了页面的mime类型?

时间:2010-03-15 15:25:45

标签: asp.net-mvc asp.net-mvc-2 mime-types renderaction

如果子操作的类型与父操作的类型不同,在Asp.Net MVC2应用程序中调用Html.RenderAction似乎可以改变页面的mime类型。

下面的代码(在MVC2 RTM中测试)对我来说很合理,在调用application/json时会返回Home/Index类型的结果。浏览器不会显示页面,而是会禁止并询问您是否要下载它。

我的问题:我错过了什么吗?这是一个错误吗?如果是这样,最好的解决方法是什么?

控制器:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewData[ "Message" ] = "Welcome to ASP.NET MVC!";

        return View();
    }

    [ChildActionOnly]
    public JsonResult States()
    {
        string[] states = new[] { "AK", "AL", "AR", "AZ", };

        return Json(states, JsonRequestBehavior.AllowGet);
    }
}

视图:

<h2><%= Html.Encode(ViewData["Message"]) %></h2>
<p>
    To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.
</p>
<script>
  var states = <% Html.RenderAction("States"); %>;
</script>

6 个答案:

答案 0 :(得分:8)

这不是一个错误。 JsonResult类型应该将结果设置为JSON,因为这通常是你想要的。

你真的不想要JSON 结果,你想要一个JSON 字符串。那么为什么不写这个呢?

[NonAction]
public string States()
{
    string[] states = new[] { "AK", "AL", "AR", "AZ", };

    return new JavaScriptSerializer().Serialize(states);
}

答案 1 :(得分:8)

我认为这是一个错误。如果这是正在呈现的操作,为什么它会更改操作响应? Html.Action也是如此,它将它呈现为一个字符串。我的解决方法是:

Html.ViewContext.HttpContext.Response.ContentType = "text/html";

调用Html.Action后。我想有人可以编写一个包装器Html Helper扩展,类似于:

var aux = Html.ViewContext.HttpContext.Response.ContentType;
Html.Action(....); // or Html.RenderAction(...)
Html.ViewContext.HttpContext.Response.ContentType = aux;

答案 2 :(得分:4)

你没有遗漏某些东西(除非我也是),我认为这是一个错误。我在ASP.NET MVC3中遇到了同样的问题。

我们有一个控制器动作,它从简单的内容管理系统返回内容。 CMS允许用户定义返回内容的内容类型(例如text / plain或text / xml)。

可以直接调用控制器操作,也可以将其作为子操作调用,以允许视图包含内容管理元素。

如果使用内容类型“text / plain”创建了一段内容,并将其嵌入到ASP.NET MVC视图中,则会覆盖父级的内容类型,并且浏览器会显示HTML。

加布,我认为你已经敲定了头部,因为看起来似乎没有一种情况下,孩子的行为压倒父母是一个理想的结果。

我的解决方案是在ControllerContext.IsChildAction上分支并构建我自己的返回对象,但在我看来,这是应该由框架处理的。

我确定您已经知道这一点,但在您的情况下,我建议明确将JsonResult.ContentType设置为父级的内容类型。

答案 3 :(得分:3)

这可以通过明确强制将mime类型“返回”到text/html

来解决
return Json(states, "text/html", JsonRequestBehavior.AllowGet);

但这似乎不应该是必要的。

答案 4 :(得分:1)

Craig Stuntz said类似,内容类型应该更改。

更好的方法是使用AJAX调用该操作,然后将返回的对象分配给JavaScript代码中的states变量。

答案 5 :(得分:1)

我今天遇到了问题。原因是我需要重用现有的子操作来填充页面上的一些json数据,以便可以避免不必要的ajax请求。

根据Jamie和Niv的想法,我创建了以下辅助方法。

public static MvcHtmlString ChildAction( this HtmlHelper htmlHelper, ActionResult result )
{
   var aux = htmlHelper.ViewContext.HttpContext.Response.ContentType;
   var actionResult = htmlHelper.Action( result );
   htmlHelper.ViewContext.HttpContext.Response.ContentType = aux;
   return actionResult;
}

当您需要使用返回json数据的子操作的结果时,调用Html.ChildAction而不是Html.Action。