Asp.Net MVC2 RenderAction 更改页面 mime 类型?
如果子操作的类型与父操作的类型不同,则在 Asp.Net MVC2 应用程序中调用 Html.RenderAction
似乎可以更改页面的 mime 类型。
下面的代码(在 MVC2 RTM 中测试)对我来说似乎很合理,在调用 Home/Index
时将返回 application/json
类型的结果。浏览器不会显示页面,而是会询问您是否要下载它。
我的问题:我错过了什么吗?这是一个错误吗?如果是这样,最好的解决方法是什么?
控制器:
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>
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.
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.
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>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我认为这是一个错误。如果这是正在渲染的子操作,为什么它会改变父操作响应?
Html.Action 也会发生同样的情况,它将其呈现为字符串。我的解决方法是:
调用 Html.Action 之后。我想有人可以编写一个包装器 Html Helper 扩展,例如:
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:
after calling Html.Action. I suppose someone could write a wrapper Html Helper extension, something like:
这不是一个错误。
JsonResult
类型应该将结果设置为 JSON,因为这通常是您想要的。您实际上并不想要一个 JSON 结果,您需要一个 JSON 字符串。那么为什么不直接写呢?
It's not a bug. The
JsonResult
type is supposed to set the result to JSON, because that's usually what you want.You don't really want a JSON result here, you want a JSON string. So why not just write that?
你没有错过任何东西(除非我也错过了),我认为这是一个错误。我在 ASP.NET MVC3 中也遇到同样的问题。
我们有一个控制器操作,它从简单的内容管理系统返回内容。 CMS 允许用户定义返回内容的内容类型(例如 text/plain 或 text/xml)。
控制器操作可以直接调用,也可以作为子操作调用,以允许视图包含内容管理元素。
如果使用“text/plain”内容类型创建一段内容,并将其嵌入到 ASP.NET MVC 视图中,则父级的内容类型将被覆盖,浏览器将显示 HTML。
加布,我认为你说得一针见血,因为似乎不存在子级行为凌驾于父级之上的情况是理想的结果。
我的解决方案是在
ControllerContext.IsChildAction
上分支并构造我自己的返回对象,但在我看来,这是应该由框架处理的事情。我确信您已经意识到这一点,但在您的情况下,我建议将
JsonResult.ContentType
显式设置为父级的内容类型。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.
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).
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.
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.
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.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.这可以通过显式强制 mime 类型“返回”到
text/html
来解决:不过,这似乎不是必要的。
This can be solved by explicitly forcing the mime type "back" to
text/html
:It doesn't seem like this should be necessary, though.
就像 Craig Stuntz 所说的内容类型是应该改变。
更好的方法是使用 AJAX 调用该操作,然后将返回的对象分配给 JavaScript 代码中的
states
变量。Like Craig Stuntz said the content type is supposed to change.
A better approach would be calling that action with AJAX and then assigning the returned object to the
states
variable in the JavaScript code.我今天遇到了问题。原因是我需要重用现有的子操作来填充页面上的一些 json 数据,以便避免不必要的 ajax 请求。
基于 Jamie 和 Niv 的想法,我创建了以下辅助方法。
当您需要使用返回 json 数据的子操作结果时,请调用 Html.ChildAction 而不是 Html.Action。
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.
Based on Jamie and Niv's idea, I created following helper method.
Call Html.ChildAction instead of Html.Action when you need to use result of child action that returns json data.