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

我是一个 Java 开发人员,新手。NET.我正在做一个。NET MVC2项目,其中我希望有一个部分视图来包装小部件。每个 JavaScript 小部件对象都有一个由模型数据填充的 JSON 数据对象。然后,更新此数据的方法绑定到小部件中的数据更改时或该数据在另一个小部件中更改时的事件。

代码是这样的:

返回文章页面

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


return View(myview, returnData);
}

返回文章页面

<%@ 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。我在控制器中看到了一些真正简单的方法,但在视图中没有。我认为这是一个基本的问题,但我已经花了几个小时,试图使这个圆滑。

229683 次浏览

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

你的行为是这样的:

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

剪辑

刚刚看到你假设这是一个视图的 Model,所以上面的不是严格正确的,你必须对控制器方法进行 Ajax调用才能得到这个,那么 ascx本身就不会有一个模型,我将留下我的代码,以防它对你有用,你可以修改这个调用

编辑2 把 ID 输入密码

很好,你刚刚开始使用 MVC,你已经发现了它的第一个主要缺陷。

您并不真正想要在视图中将其转换为 JSON,并且您也不真正想要在控制器中将其转换为 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 %>

请注意,标准的.NETJavaScriptSerializer 是相当垃圾的。

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

更新 关于你的 JavaScript,最好像下面这样包装所有的小部件:

(
// all js here
)();

这样,如果您在一个页面上放置多个小部件,就不会产生冲突(除非您需要从页面的其他地方访问这些方法,但在这种情况下,您应该使用某个小部件框架注册这个小部件)。现在这可能不是一个问题,但是现在添加括号将是一个很好的实践,以便在将来它成为一个需求时节省很多工作,封装功能也是一个很好的面向对象实践。

安德鲁的反应很好,但我想稍微修改一下。不同之处在于,我希望我的 ModelView 中没有开销数据。只有对象的数据。看起来 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 请求它,但是它需要更少的调用,因此可以节省开销。顺便说一下,这是时髦的日期,但这似乎是另一个线程。

在 mvc3与剃刀 @Html.Raw(Json.Encode(object))似乎做的诀窍。

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

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

下面是相应的 helper 方法 Extension 类:

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

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

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

戴夫扩展了这个伟大的答案。你可以创建一个简单的 HtmlHelper

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

在你看来:

@Html.RenderAsJson(Model)

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

可以使用@Html. Raw (JSON.Encode (Object))将视图模态对象转换为 JSON

对于 ASP.NET Core 3.1和更高版本,您可以使用 System.Text.Json名称空间将 ViewModel 序列化为 JSON:

@using System.Text.Json


...


@section Scripts {
<script>
const model = @Html.Raw(JsonSerializer.Serialize(Model));
</script>
}