14

Html.RenderAction如果子操作的类型与父操作的类型不同,则在 Asp.Net MVC2 应用程序中调用似乎可以更改页面的 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>
4

6 回答 6

9

我认为这是一个错误。如果这是正在呈现的操作,为什么它会更改操作响应?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;
于 2010-11-16T19:19:16.060 回答
8

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

你真的不想要一个 JSON结果,你想要一个 JSON string。那么为什么不直接写呢?

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

    return new JavaScriptSerializer().Serialize(states);
}
于 2010-03-15T15:47:00.833 回答
4

你并没有错过什么(除非我也是),我认为这是一个错误。我在 ASP.NET MVC3 中有同样的问题。

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

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

如果创建内容类型为“text/plain”的内容,并且该内容嵌入在 ASP.NET MVC 视图中,则父级的内容类型将被覆盖,并且浏览器显示 HTML。

Gabe,我认为您已经一针见血了,因为似乎没有这样一种情况,即孩子的行动凌驾于父母之上是理想的结果。

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

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

于 2011-10-14T15:41:08.327 回答
3

这可以通过显式强制 mime 类型“返回”来解决text/html

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

不过,这似乎不是必需的。

于 2010-03-15T15:47:54.897 回答
1

就像Craig Stuntz 所说的内容类型应该改变。

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

于 2010-03-15T16:00:52.547 回答
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。

于 2013-05-22T07:31:35.733 回答