Asp.Net MVC2 RenderAction更改页面mime类型?

时间:2021-07-05 04:03:59

It appears that calling Html.RenderAction in Asp.Net MVC2 apps can alter the mime type of the page if the child action's type is different than the parent action's.

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

The code below (testing in MVC2 RTM), which seems sensible to me, will return a result of type application/json when calling Home/Index. Instead of dispylaying the page, the browser will barf and ask you if you want to download it.

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

My question: Am I missing something? Is this a bug? If so, what's the best workaround?

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

controller:

控制器:

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

view:

视图:

<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 个解决方案

#1


8  

It's not a bug. The JsonResult type is supposed to set the result to JSON, because that's usually what you want.

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

You don't really want a JSON result here, you want a JSON string. So why not just write that?

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

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

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

#2


8  

I Consider this a bug. If this is a child action being rendered, why it would change the parent action response? The same happens with Html.Action, which renders it into a string. My workaround is doing:

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

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

after calling Html.Action. I suppose someone could write a wrapper Html Helper extension, something like:

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

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

#3


4  

You're not missing something (unless I am too) and I think this is a bug. I have the same issue in ASP.NET MVC3.

你不会错过任何东西(除非我也是),我认为这是一个错误。我在ASP.NET MVC3中遇到了同样的问题。

We have a controller action which returns content from a simple content managment system. The CMS allows the user to define the content type of what is returned (for example text/plain or text/xml).

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

The controller action is either called directly, or called as a child action to allow a view to contain content managed elements.

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

If a piece of content is created with a content type of "text/plain", and this is embedded on an ASP.NET MVC view, the content type of the parent is overridden and the browser displays HTML.

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

Gabe, I think you've hit the nail on the head in that there does not appear to be a scenario where the child action overriding the parent is a desirable outcome.

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

My solution is to branch on ControllerContext.IsChildAction and construct my own return object, but this in my opinion is something that should be handled by the framework.

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

I'm sure you're aware of this, but in your case I would suggest explicitly setting JsonResult.ContentType to the content type of the parent.

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

#4


3  

This can be solved by explicitly forcing the mime type "back" to text/html:

这可以通过明确强制mime类型“back”到text / html来解决:

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

It doesn't seem like this should be necessary, though.

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

#5


1  

Like Craig Stuntz said the content type is supposed to change.

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

A better approach would be calling that action with AJAX and then assigning the returned object to the states variable in the JavaScript code.

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

#6


1  

I had the problem today. The reason was I need to reuse an existing child action to populate some json data on the page so that unnecessary ajax requests can be avoided.

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

Based on Jamie and Niv's idea, I created following helper method.

基于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;
}

Call Html.ChildAction instead of Html.Action when you need to use result of child action that returns json data.

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

#1


8  

It's not a bug. The JsonResult type is supposed to set the result to JSON, because that's usually what you want.

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

You don't really want a JSON result here, you want a JSON string. So why not just write that?

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

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

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

#2


8  

I Consider this a bug. If this is a child action being rendered, why it would change the parent action response? The same happens with Html.Action, which renders it into a string. My workaround is doing:

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

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

after calling Html.Action. I suppose someone could write a wrapper Html Helper extension, something like:

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

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

#3


4  

You're not missing something (unless I am too) and I think this is a bug. I have the same issue in ASP.NET MVC3.

你不会错过任何东西(除非我也是),我认为这是一个错误。我在ASP.NET MVC3中遇到了同样的问题。

We have a controller action which returns content from a simple content managment system. The CMS allows the user to define the content type of what is returned (for example text/plain or text/xml).

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

The controller action is either called directly, or called as a child action to allow a view to contain content managed elements.

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

If a piece of content is created with a content type of "text/plain", and this is embedded on an ASP.NET MVC view, the content type of the parent is overridden and the browser displays HTML.

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

Gabe, I think you've hit the nail on the head in that there does not appear to be a scenario where the child action overriding the parent is a desirable outcome.

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

My solution is to branch on ControllerContext.IsChildAction and construct my own return object, but this in my opinion is something that should be handled by the framework.

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

I'm sure you're aware of this, but in your case I would suggest explicitly setting JsonResult.ContentType to the content type of the parent.

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

#4


3  

This can be solved by explicitly forcing the mime type "back" to text/html:

这可以通过明确强制mime类型“back”到text / html来解决:

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

It doesn't seem like this should be necessary, though.

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

#5


1  

Like Craig Stuntz said the content type is supposed to change.

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

A better approach would be calling that action with AJAX and then assigning the returned object to the states variable in the JavaScript code.

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

#6


1  

I had the problem today. The reason was I need to reuse an existing child action to populate some json data on the page so that unnecessary ajax requests can be avoided.

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

Based on Jamie and Niv's idea, I created following helper method.

基于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;
}

Call Html.ChildAction instead of Html.Action when you need to use result of child action that returns json data.

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