ASP.NET MVC:如何将View Model转换为Json对象

时间:2010-07-29 17:57:22

标签: .net javascript asp.net-mvc json

我是.NET新手。我正在开发.Net MVC2项目,我希望有一个局部视图来包装一个小部件。每个JS小部件对象都有一个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。我似乎有一些真正简单的方法在控制器中执行它但不在视图中。我认为这是一个基本问题,我已经花了几个小时试图制作这个光滑的。

8 个答案:

答案 0 :(得分:324)

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

答案 1 :(得分:30)

干得好,你刚刚开始使用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实践。

答案 2 :(得分:18)

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

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

这是相应的辅助方法Extension class:

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());
    }
}

它不是超级软化,但是它解决了把它放在哪里的问题(在Controller或视图中?)答案很明显:既不是;)

答案 3 :(得分:5)

您可以直接使用操作中的Json

你的行动将是这样的:

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

修改

只是看到你认为这是View的Model所以上面的内容并不完全正确,你必须对控制器方法进行Ajax调用才能得到这个,{ {1}}本身不会有模型,我会留下我的代码以防万一它对你有用,你可以修改调用

答案 4 :(得分:3)

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

答案 5 :(得分:0)

安德鲁有很好的回应,但我想稍微调整一下。不同的方式是我喜欢我的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请求它,但它需要少一个调用,因此它可以节省您的开销。顺便说一句,这对于日期来说很时髦,但这似乎是另一个主题。

答案 6 :(得分:0)

<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))'>

答案 7 :(得分:0)

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

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

在你看来:

@Html.RenderAsJson(Model)

这样,如果由于某种原因,您希望稍后更改逻辑,则可以集中创建JSON的逻辑。