【问题标题】:Rendering a JsonResult to a string in Razor将 JsonResult 渲染到 Razor 中的字符串
【发布时间】:2015-01-05 14:43:00
【问题描述】:

我有一个服务器生成的对象,我需要将其转换为 JSON 对象以供 JavaScript 使用。我更喜欢在视图呈现时将这个 JSON 对象直接呈现到 JS 变量中,以防止额外的 HTTP 请求。

这是在我的控制器中:

public virtual JsonResult GetTheThings()
{
    return Json(new
    {
        foo = "hello world",
        bar = 3,
    }, JsonRequestBehavior.AllowGet);
}

我可以通过http://localhost:32243/MyController/GetTheThings 直接访问它,并在我的浏览器中呈现以下内容。 {"foo":"hello world", "bar":3}。完美!

所以,现在我基本上只是想把这个视图的结果渲染成一个字符串。我该怎么做呢?我在下面的内容不起作用,但希望它能给你这个想法。

这是我的尝试

<script>
  var myObj = @Html.RenderPartial(MVC.MyController.GetTheThings());
</script>

请注意,我也在使用 T4 模板。

最后,这就是我想要在视图中呈现的内容。

<script>
  var myObj = {"foo":"hello world", "bar":3};
</script>

【问题讨论】:

  • 你可以试试Html.Action,但我不确定这是否可行
  • 你试过var myObj = MVC.MyController.GetTheThings();吗?
  • 或者Html.Partial...
  • @Shoe 是的,这只会输出var myObj = T4MVC_System_Web_Mvc_JsonResult;

标签: c# asp.net-mvc json razor t4mvc


【解决方案1】:

由于您只希望在呈现视图时呈现对象(而不是通过 AJAX 调用),因此最好的选择可能是将其作为模型的一部分。创建一个字符串属性并将 JSON 保存为字符串,然后在 View 中使用 JSON.parse 将其转换为对象。

例子:

<script>
    var myObj = JSON.parse("@Html.Raw(Model.JsonString)");
</script>

这样会更干净,而且确实没有任何充分的理由让您的控制器这样做,因为您不是通过 AJAX 请求对象。

【讨论】:

  • 但是如何从我的控制器获取 JSON 字符串?这是我的主要问题。
  • 为什么需要控制器提供它?控制器实际上应该只处理 HTTP 请求,而不是指示您的应用程序逻辑。
  • 嗯...是的,我认为您可能是对的。谢谢。我会以不同的方式来做这件事!
【解决方案2】:

您可以像这样创建一个 HtmlHelper 扩展,而不是使用 JsonResult,而是使用强类型视图(假设使用 JSON.Net):

public static class HtmlHelperEx
{
    public static string ToJson(this HtmlHelper html, object obj)
    {
        return JsonConvert.SerializeObject(obj);
    }
}

控制器动作:

public ActionResult Index() 
{
   return View(new ModelToSerialize());
}

然后在你的视图中使用它:

@model ModelToSerialize

<script type="text/javascript">
    var myObj = @Html.ToJson(Model)
</script>

【讨论】:

  • 完美解决方案。并且能够在返回之前在 HTML 中使用模型作为 JSON。只需添加@Html.Raw(@Html.ToJson(Model));避免对 json 进行 htmlencoding。
【解决方案3】:

理论上你可以这样做:

<script>
  var myObj = json.parse('@Html.RenderPartial(MVC.MyController.GetTheThings());');
</script>

虽然GetTheThings() 不会在这里真正触发,它只是一个 T4MVC 占位符。您可能应该将您的值存储到视图模型中,然后将其放入 javascript 中,如下所示。如果您想单独调用控制器来获取此值,则需要进行 ajax 调用。

public class MyController
{ 
    public ActionResult MyView(){
        var vm = new MyViewModel();
        vm.MyObjectAsJsonString = GetMyJsonString();
        return View(vm);
    }
    public string GetMyJsonString(){
         return ""; //get your json 
    }
}

public class MyViewModel
{
    public string MyObjectAsJsonString{ get; set; }
}

@model MyViewModel
<script>
  var myObj = json.parse('@Model.MyObjectAsJsonString');
</script>

通过 ajax 实现:

<script>
    $.ajax({
        url: '@Url.Action(MVC.MyController.GetTheThings())',
        type: 'get',
    }).done(function (result){
        var myObj = result;
    });
</script>

【讨论】:

  • 我在解析 json 对象时没有问题,我在让 MVC 在这里渲染视图时遇到问题。另外,正如我上面所说,我想在视图中呈现它而不是另一个 AJAX 调用以避免额外的 HTTP 请求。
  • 您可以在没有 ajax 调用的情况下执行此操作,但您需要将其存储在视图模型中。视图不能直接调用控制器,在渲染视图时控制器已经使用完毕。
  • 查看我的编辑,了解如何从视图模型中的 json 进行解析的示例。
【解决方案4】:
<script>
  var myObj = '@Html.RenderPartial("Getthethings","controller name");'
</script>

【讨论】:

  • 谢谢,但这样做会忽略该项目使用的强类型 T4 模板。
【解决方案5】:

使用 @Html.Raw(...) 包装器。

在我自己的项目中,我确实引用了从控制器本身下来的现有模型,但是没有理由你不能获得与局部相同的效果......这并不是使用的真正核心目的异步调用...你应该使用它而不是依赖 html 渲染引擎来完成你的“脏”工作。

【讨论】:

    猜你喜欢
    • 2018-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-08
    • 1970-01-01
    • 1970-01-01
    • 2020-10-03
    • 1970-01-01
    相关资源
    最近更新 更多