.net - net - mvc model to json




ASP.NET MVC: How to convert View Model into Json object (6)

I am Java developer new to .NET. I am working on a .Net MVC2 project where I want to have a partial view to wrap a widget. Each JS widget object has a JSON data object that would be populated by the model data. Then methods to update this data bound to events when data is changed in the widget or if that data is changed in another widget. The code is something like this.

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>

What I don't know is how to send the data over as SomeModelView and then be able to use that to populate the widget as well as convert that to Json. I had seem some real simple ways to do it in the controller but not in the view. I figure this is a basic question bu I've been going for a few hours trying to make this slick.


@Html.Raw(Json.Encode(object)) can be used to convert the View Modal Object to JSON


Andrew had a great response but I wanted to tweek it a little. The way this is different is that I like my ModelViews to not have overhead data in them. Just the data for the object. It seem that ViewData fits the bill for over head data, but of course I'm new at this. I suggest doing something like this.

Controller

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

View

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

What This does for you is it gives you the same data in your JSON as in your ModelView so you can potentially return the JSON back to your controller and it would have all the parts. This is similar to just requesting it via a JSONRequest however it requires one less call so it saves you that overhead. BTW this is funky for Dates but that seems like another thread.


I found it to be pretty nice to do it like this (usage in the view):

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

Here is the according helper method 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());
    }
}

It is not super-sofisticated, but it solves the problem of where to put it (in Controller or in view?) The answer is obviously: neither ;)


In mvc3 with razor @Html.Raw(Json.Encode(object)) seems to do the trick.


You can use Json from the action directly,

Your action would be something like this:

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

Edit

Just saw that you assume this is the Model of a View so the above isn't strictly correct, you would have to make an Ajax call to the controller method to get this, the ascx would not then have a model per se, I will leave my code in just in case it is useful to you and you can amend the call






json