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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3365551/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 04:19:40  来源:igfitidea点击:

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

.netjavascriptasp.net-mvcjson

提问by Chris Stephens

I am a 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 JavaScript widget object has a JSON data object that would be populated by the model data. Then methods to update this data are bound to events when data is changed in the widget or if that data is changed in another widget.

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

The code is something like this:

代码是这样的:

MyController:

MyController

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

  return View(myview, returnData);
}

myview.ascx:

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 SomeModelViewand then be able to use that to populate the widget as well as convert that to JSON. I had seen some real simple ways to do it in the controller but not in the view. I figure this is a basic question but I've been going for a few hours trying to make this slick.

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

回答by Dave

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

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

回答by Andrew Bullock

Well done, you've only just started using MVC and you've found its first major flaw.

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

You don't really want to be converting it to JSON in the view, and you don't really want to convert it in the controller, as neither of these locations make sense. Unfortunately, you're stuck with this situation.

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

The best thing I've found to do is send the JSON to the view in a ViewModel, like this:

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

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

return View("viewname", viewModel);

then use

然后使用

<%= Model.JsonData %>

in your view. Be aware that the standard .NET JavaScriptSerializer is pretty crap.

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

doing it in the controller at least makes it testable (although not exactly like the above - you probably want to take an ISerializer as a dependency so you can mock it)

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

Updatealso, regarding your JavaScript, it would be good practice to wrap ALL the widget JS you have above like so:

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

(
    // all js here
)();

this way if you put multiple widgets on a page, you won't get conflicts (unless you need to access the methods from elsewhere in the page, but in that case you should be registering the widget with some widget framework anyway). It may not be a problem now, but it would be good practice to add the brackets now to save yourself muchos effort in the future when it becomes a requirement, it's also good OO practice to encapsulate the functionality.

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

回答by Wolfgang

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

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

回答by Pharabus

You can use Jsonfrom the action directly,

您可以Json直接从操作中使用,

Your action would be something like this:

您的操作将是这样的:

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

Edit

编辑

Just saw that you assume this is the Modelof a View so the above isn't strictly correct, you would have to make an Ajaxcall to the controller method to get this, the ascxwould 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

刚刚看到你假设这是Model一个视图,所以上面的内容并不完全正确,你必须Ajax调用控制器方法来获取它,ascx然后本身就没有模型,我会留下我的代码以防万一它对您有用,您可以修改电话

Edit 2just put id into the code

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

回答by Priya Payyavula

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

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

回答by Chris Stephens

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.

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

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.

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

回答by user2330678

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

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

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

I did below and it works like charm.

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

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

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

回答by smoksnes

Extending the great answer from Dave. You can create a simple HtmlHelper.

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

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

And in your view:

在您看来:

@Html.RenderAsJson(Model)

This way you can centralize the logic for creating the JSON if you, for some reason, would like to change the logic later.

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