繁体   English   中英

如何在 ASP.NET MVC 中将视图模型转换为 JSON 对象?

[英]How to convert View Model into JSON object in ASP.NET MVC?

我是一名 Java 开发人员,刚接触 .NET。 我正在处理一个 .NET MVC2 项目,我想在其中使用局部视图来包装小部件。 每个 JavaScript 小部件对象都有一个 JSON 数据对象,该对象将由模型数据填充。 然后,当小部件中的数据更改或另一个小部件中的数据更改时,更新此数据的方法将绑定到事件。

代码是这样的:

MyController

virtual public ActionResult DisplaySomeWidget(int id) {
  SomeModelView returnData = someDataMapper.getbyid(1);

  return View(myview, returnData);
}

myview.ascx

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<SomeModelView>" %>

<script type="text/javascript">
  //creates base widget object;
  var thisWidgetName = new Widget();

  thisWidgetName.updateTable = function() {
    //  UpdatesData
  };
  $(document).ready(function () {
    thisWidgetName.data = <% converttoJSON(model) %>
    $(document).bind('DATA_CHANGED', thisWidgetName.updateTable());
  });
</script>

<div><%:model.name%></div>

我不知道如何将数据作为SomeModelView发送,然后能够使用它来填充小部件并将其转换为 JSON。 我在控制器中看到了一些真正简单的方法,但在视图中却没有。 我认为这是一个基本问题,但我已经花了几个小时试图使这个问题变得光滑。

在 mvc3 中使用剃刀@Html.Raw(Json.Encode(object))似乎可以解决问题。

干得好,您才刚刚开始使用 MVC,并且发现了它的第一个主要缺陷。

您真的不想在视图中将其转换为 JSON,也不想在控制器中将其转换,因为这两个位置都没有意义。 不幸的是,您遇到了这种情况。

我发现做的最好的事情是将 JSON 发送到 ViewModel 中的视图,如下所示:

var data = somedata;
var viewModel = new ViewModel();
var serializer = new JavaScriptSerializer();
viewModel.JsonData = serializer.Serialize(data);

return View("viewname", viewModel);

然后使用

<%= Model.JsonData %>

在你看来。 请注意,标准的 .NET JavaScriptSerializer 非常垃圾。

在控制器中执行它至少使它可测试(尽管与上面的不完全一样 - 您可能希望将 ISerializer 作为依赖项,以便您可以模拟它)

还要更新,关于您的 JavaScript,最好将上面所有的小部件 JS 包装起来,如下所示:

(
    // all js here
)();

这样,如果您在一个页面上放置多个小部件,就不会发生冲突(除非您需要从页面的其他地方访问这些方法,但在这种情况下,您无论如何都应该向某个小部件框架注册小部件)。 现在可能不是问题,但是现在添加括号是一种很好的做法,以便在将来成为需求时节省自己的大量精力,封装功能也是一种很好的 OO 做法。

我发现这样做非常好(在视图中使用):

    @Html.HiddenJsonFor(m => m.TrackingTypes)

这是相应的辅助方法扩展类:

public static class DataHelpers
{
    public static MvcHtmlString HiddenJsonFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
    {
        return HiddenJsonFor(htmlHelper, expression, (IDictionary<string, object>) null);
    }

    public static MvcHtmlString HiddenJsonFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes)
    {
        return HiddenJsonFor(htmlHelper, expression, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
    }

    public static MvcHtmlString HiddenJsonFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes)
    {
        var name = ExpressionHelper.GetExpressionText(expression);
        var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);

        var tagBuilder = new TagBuilder("input");
        tagBuilder.MergeAttributes(htmlAttributes);
        tagBuilder.MergeAttribute("name", name);
        tagBuilder.MergeAttribute("type", "hidden");

        var json = JsonConvert.SerializeObject(metadata.Model);

        tagBuilder.MergeAttribute("value", json);

        return MvcHtmlString.Create(tagBuilder.ToString());
    }
}

它不是超级复杂,但它解决了把它放在哪里的问题(在控制器中还是在视图中?)答案显然是:两者都不是;)

您可以直接从动作中使用Json

您的操作将是这样的:

virtual public JsonResult DisplaySomeWidget(int id)
{
    SomeModelView returnData = someDataMapper.getbyid(id);
    return Json(returnData);
}

编辑

刚刚看到您假设这是视图的Model ,因此上述内容并不完全正确,您必须对控制器方法进行Ajax调用才能获得此信息,然后ascx本身就没有模型,我会留下我的代码,以防万一它对你有用,你可以修改调用

编辑 2只是将 id 放入代码中

@Html.Raw(Json.Encode(object)) 可用于将视图模态对象转换为 JSON

扩展Dave的精彩回答。 您可以创建一个简单的HtmlHelper

public static IHtmlString RenderAsJson(this HtmlHelper helper, object model)
{
    return helper.Raw(Json.Encode(model));
}

在你看来:

@Html.RenderAsJson(Model)

如果您出于某种原因想稍后更改逻辑,则可以通过这种方式集中创建 JSON 的逻辑。

安德鲁有一个很好的回应,但我想稍微调整一下。 不同之处在于我喜欢我的 ModelViews 中没有开销数据。 只是对象的数据。 似乎 ViewData 符合开销数据的要求,但当然我是新手。 我建议做这样的事情。

控制器

virtual public ActionResult DisplaySomeWidget(int id)
{
    SomeModelView returnData = someDataMapper.getbyid(1);
    var serializer = new JavaScriptSerializer();
    ViewData["JSON"] = serializer.Serialize(returnData);
    return View(myview, returnData);
}

看法

//create base js object;
var myWidget= new Widget(); //Widget is a class with a public member variable called data.
myWidget.data= <%= ViewData["JSON"] %>;

这对您的作用是它在您的 JSON 中为您提供与 ModelView 中相同的数据,因此您可以潜在地将 JSON 返回到您的控制器,并且它将包含所有部分。 这类似于仅通过 JSONRequest 请求它,但是它需要更少的调用,因此可以节省您的开销。 顺便说一句,这对于 Dates 来说很时髦,但这似乎是另一个线程。

<htmltag id=’elementId’ data-ZZZZ’=’@Html.Raw(Json.Encode(Model))’ />

参考https://highspeedlowdrag.wordpress.com/2014/08/23/mvc-data-to-jquery-data/

我在下面做了,它就像魅力一样。

<input id="hdnElement" class="hdnElement" type="hidden" value='@Html.Raw(Json.Encode(Model))'>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM