![](/img/trans.png)
[英]Is it possible to send more than one model object to an ASP.NET MVC View?
[英]How to convert View Model into JSON object in ASP.NET MVC?
我是一名 Java 开发人员,刚接触 .NET。 我正在处理一个 .NET MVC2 项目,我想在其中使用局部视图来包装小部件。 每个 JavaScript 小部件对象都有一个 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 非常垃圾。
在控制器中执行它至少使它可测试(尽管与上面的不完全一样 - 您可能希望将 ISerializer 作为依赖项,以便您可以模拟它)
还要更新,关于您的 JavaScript,最好将上面所有的小部件 JS 包装起来,如下所示:
(
// all js here
)();
这样,如果您在一个页面上放置多个小部件,就不会发生冲突(除非您需要从页面的其他地方访问这些方法,但在这种情况下,您无论如何都应该向某个小部件框架注册小部件)。 现在可能不是问题,但是现在添加括号是一种很好的做法,以便在将来成为需求时节省自己的大量精力,封装功能也是一种很好的 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());
}
}
它不是超级复杂,但它解决了把它放在哪里的问题(在控制器中还是在视图中?)答案显然是:两者都不是;)
您可以直接从动作中使用Json
,
您的操作将是这样的:
virtual public JsonResult DisplaySomeWidget(int id)
{
SomeModelView returnData = someDataMapper.getbyid(id);
return Json(returnData);
}
编辑
刚刚看到您假设这是视图的Model
,因此上述内容并不完全正确,您必须对控制器方法进行Ajax
调用才能获得此信息,然后ascx
本身就没有模型,我会留下我的代码,以防万一它对你有用,你可以修改调用
编辑 2只是将 id 放入代码中
@Html.Raw(Json.Encode(object)) 可用于将视图模态对象转换为 JSON
扩展Dave的精彩回答。 您可以创建一个简单的HtmlHelper 。
public static IHtmlString RenderAsJson(this HtmlHelper helper, object model)
{
return helper.Raw(Json.Encode(model));
}
在你看来:
@Html.RenderAsJson(Model)
如果您出于某种原因想稍后更改逻辑,则可以通过这种方式集中创建 JSON 的逻辑。
安德鲁有一个很好的回应,但我想稍微调整一下。 不同之处在于我喜欢我的 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 请求它,但是它需要更少的调用,因此可以节省您的开销。 顺便说一句,这对于 Dates 来说很时髦,但这似乎是另一个线程。
<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))'>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.