Asp.net mvc ASP.NET MVC:视图有时返回为application/json而不是text/html
我有一个视图,从中调用另一个视图,在html中的脚本标记中呈现一些json:Asp.net mvc ASP.NET MVC:视图有时返回为application/json而不是text/html,asp.net-mvc,json,content-type,Asp.net Mvc,Json,Content Type,我有一个视图,从中调用另一个视图,在html中的脚本标记中呈现一些json: public ActionResult App() { return View(); } public JsonResult SomeJsonData() { // ... here goes the code that generates the model return Json(model, JsonRequestBehavior.AllowGet); } 在我的App.cshtml文件中,我有如
public ActionResult App()
{
return View();
}
public JsonResult SomeJsonData()
{
// ... here goes the code that generates the model
return Json(model, JsonRequestBehavior.AllowGet);
}
在我的App.cshtml文件中,我有如下内容:
<script type='text/javascript'>
var myJsonData = @Html.Action("SomeJsonData", "MyController");
</script>
var myJsonData=@Html.Action(“SomeJsonData”、“MyController”);
问题是,有时当我在浏览器中重新加载页面时(现在使用Chrome 20),它会显示所有标记,如果我转到开发人员工具中的“网络”选项卡,我会看到页面请求的内容类型为“application/json”。如果我只是重新加载页面,那么它会正确加载(内容类型应该是“text/html”)
你知道为什么会这样吗?或者我做错了什么?当您返回
JsonResult
时,您正在将响应内容类型修改为application/json
。因此,您首先调用App
controller操作,该操作返回一个视图,并显然将内容类型设置为text/html
,在返回的视图中调用SomeJsonData
操作,该操作将删除先前的内容类型,并将其修改为application/json
。当然最后一个赢了,这就是用户代理在一天结束时看到的:application/json
因此,以下是如何继续:
public ActionResult App()
{
// ... here goes the code that generates the model
var model = ...
return View(model);
}
在强类型视图中:
@model MyViewModel
<script type="text/javascript">
var myJsonData = @Html.Raw(Json.Encode(Model));
</script>
@model MyViewModel
var myJsonData=@Html.Raw(Json.Encode(Model));
事实上,我刚刚发现了另一个相关问题
在我发布之前,我找不到任何东西
我将采用的方法是在返回json数据时更改内容类型:
public JsonResult SomeJsonData(bool returnAsHtml = false)
{
// ... here goes the code that generates the model
return returnAsHtml ?Json(model, "text/html", JsonRequestBehavior.AllowGet) : Json(model, JsonRequestBehavior.AllowGet);
}
和在App.cshtml上
<script type='text/javascript'>
var myJsonData = @Html.Action("SomeJsonData", "MyController", new {returnAsHtml = true});
</script>
var myJsonData=@Html.Action(“SomeJsonData”,“MyController”,new{returnAsHtml=true});
我还添加了一个标志,允许从其他需要应用程序/json响应的地方调用actionmethod。正如其他人所说,返回json的操作正在更改响应的内容类型 我可以通过使用HtmlHelper将JSON放入页面来解决这个问题。我避免使用控制器和动作;我的HtmlHelper正在调用一个静态方法。这种解决方案可能不会在所有情况下都有效,而且是一种黑客行为,但您可以避免以这种方式将数据放入一组视图模型中
namespace System.Web.Mvc.Html
{
public static class JsonDataProviderHelper
{
public static MvcHtmlString JsonDataProvider(this HtmlHelper helper, JsonDataType jsonDataType)
{
switch (jsonDataType)
{
case JsonDataType.YARDSALE_MINI_CALENDAR:
var yardsales = SalesEventCrud.GetByMonthForJavascript(null, MvcApplication.CurrentPortalId);
return new MvcHtmlString(JsonConvert.SerializeObject(SalesEventCrud.GetByMonthForJavascript(null, MvcApplication.CurrentPortalId)));
default:
return new MvcHtmlString("");
}
}
public enum JsonDataType
{
YARDSALE_MINI_CALENDAR
}
}
}
我正在使用json.net进行序列化。我有switch
语句,因为我计划在其他情况下也使用这个助手返回JSON
在页面中:
<script type="text/javascript">
jQuery(document).ready(function () {
setupSmallSidebarCalendar(@Html.JsonDataProvider(JsonDataProviderHelper.JsonDataType.YARDSALE_MINI_CALENDAR));
});
</script>
jQuery(文档).ready(函数(){
setupSmallSidebarCalendar(@Html.JsonDataProvider(JsonDataProviderHelper.JsonDataType.YARDSALE_MINI_CALENDAR));
});
在页面中,数据是直接用JSON写入的,因此不需要对数据进行其他解析/处理。@Daran找到了原因-ContentType被上次执行的操作覆盖。他的解决方案应该是可行的,但是如果您仍然喜欢Action方法模式,那么您应该能够执行以下操作,并在返回之前简单地更改ContentType。它仍然是JSON数据,但内容类型在HTML视图中表现良好
[HttpPost]
public JsonResult GetJson(int someId, int foobar)
{
JsonResult result = CreateResult(someId, foobar);
result.ContentType = "text/html";
return result;
}
缺点是,这是,嗯,有点奇怪和/或意外的行为。例如,如果您通过AJAX调用端点,我怀疑这是否有效。但它看起来几乎可以工作,如果它在一个共享的代码库中,可能会引起一些混乱。因此,如果您这样做,那么以一种不会被误用的方式命名端点可能是值得的。您甚至可以创建一种新类型的结果,这种结果是以这种方式设计的,而不是使用JsonResult 事实上,我已经有了一个模型,我从那个ActionMethod返回的数据与模型无关,我必须将它添加到ViewBag或类似的东西中。哦,不,上帝可能禁止你使用ViewBag。求求你,发发发慈悲吧。使用视图模型。如果您已经从
应用程序
操作返回了一个模型,那么只需向该视图模型添加一个属性(我强烈主张使用“视图模型”一词,不要与“模型”混淆),该属性将包含所需的信息。如果出于某种无法解释的原因,您决定使用ViewBag,我想简单地说这是废话,但它会起作用:ViewBag.FooBar=someModel代码>和视图内部var myJsonData=@Html.Raw(Json.Encode(ViewBag.FooBar))代码>。但答应我你不会使用ViewBag。我知道,我讨厌使用ViewBag,在我可以避免的时候尽量不要使用它。但是我需要的某些视图的数据并不属于该视图模型。但是我需要的某些视图的数据不属于该视图模型。
=>这是一个矛盾的句子。问题是:如果视图需要一些数据,那么这些数据属于视图模型。句号。不可能进行进一步讨论。你可以采取任何你想要的方法,但如果你不使用视图模型将数据传递给你的视图,你的方法将完全是错误的(根据我的个人标准,你可以随意忽略:-),我只需要向阅读本文的其他人指出这一点,以避免犯与你相同的错误),例如,如果我的站点上有一个使用当前用户实例的标题,那么您应该将该用户属性添加到基本视图模型中,并确保站点中的每个视图都使用从该基本视图继承的模型?