ASP.NET MVC:如何将视图模型转换为Json对象
我是Java新的.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。 我似乎有一些真正简单的方法在控制器中完成,而不是在视图中。 我想这是一个基本的问题,我已经花了几个小时试图做出这个光华。
在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是相当糟糕的。
在控制器中做它至less使它可testing(虽然不完全像上面 – 你可能想要一个ISerializer作为依赖,所以你可以嘲笑它)
更新也关于你的JavaScript,这是一个很好的习惯,把上面所有的小部件JS包装起来,例如:
( // all js here )();
这样,如果你在一个页面上放置多个小部件,你就不会发生冲突(除非你需要从页面的其他地方访问这些方法,但是在这种情况下,你应该使用一些小部件框架来注册这个小部件)。 现在可能不是什么问题,但现在增加括号是为了在将来成为一个需求时节省自己的努力,这是一个很好的习惯,封装function也是很好的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()); } }
它不是超级复杂的,但它解决了把它放在哪里的问题(在Controller中还是在视图中?)答案显然是:既不;)
你可以直接使用Json
,
你的行为将是这样的:
virtual public JsonResult DisplaySomeWidget(int id) { SomeModelView returnData = someDataMapper.getbyid(1); return Json(returnData); }
编辑
只是看到你认为这是一个视图Model
,所以上述不是严格正确的,你将不得不作出一个Ajax
调用控制器方法来获得这个, ascx
不会有一个模型本身,我会留下我的代码,以防万一它对你有用,你可以修改通话
@ Html.Raw(Json.Encode(object))可用于将视图模态对象转换为JSON
<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))'>
从戴夫延伸的伟大答案。 你可以创build一个简单的HtmlHelper 。
public static IHtmlString RenderAsJson(this HtmlHelper helper, object model) { return helper.Raw(Json.Encode(model)); }
在你看来:
@Html.RenderAsJson(Model)
这样,如果您出于某种原因希望稍后更改逻辑,则可以集中创buildJSON的逻辑。
安德鲁有很好的回应,但我想稍微微调一下。 这是不同的方式是我喜欢我的ModelViews没有开销数据。 只是对象的数据。 ViewData似乎适合头顶数据的账单,但我当然是新手。 我build议做这样的事情。
调节器
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"] %>;
它为你做了什么,它会为你提供与你的ModelView相同的数据,所以你可以将JSON返回给你的控制器,它将包含所有的部分。 这与通过JSONRequest请求它类似,但它需要less一个呼叫,所以它可以节省您的开销。 顺便说一句,这是date时髦,但似乎是另一个线程。