如果子操作的类型与父操作的类型不同,在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>
答案 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。