C# 如何序列化ViewModel并将其推送到HTML页面以使用JSON结构?

C# 如何序列化ViewModel并将其推送到HTML页面以使用JSON结构?,c#,javascript,asp.net-mvc,json,razor,C#,Javascript,Asp.net Mvc,Json,Razor,我喜欢将视图模型结构推送到视图中,然后在javascript中使用这些结构。有什么更优雅的方法可以做到这一点?这些代码行有点难看 <script type="text/javascript"> var PartChangeModel = @Html.Raw(Json.Encode(Model.PartChange)); var PartModel = @Html.Raw(Json.Encode(Model.Part)); var BOMIte

我喜欢将视图模型结构推送到视图中,然后在javascript中使用这些结构。有什么更优雅的方法可以做到这一点?这些代码行有点难看

<script type="text/javascript">
       var PartChangeModel = @Html.Raw(Json.Encode(Model.PartChange));
       var PartModel = @Html.Raw(Json.Encode(Model.Part));
       var BOMItemModel = @Html.Raw(Json.Encode(Model.BOMItem));
</script>

var PartChangeModel=@Html.Raw(Json.Encode(Model.PartChange));
var PartModel=@Html.Raw(Json.Encode(Model.Part));
var bomitemodel=@Html.Raw(Json.Encode(Model.BOMItem));

如果您不想将Razor标记与JavaScript混合,那么AJAX调用可能是最好的选择。使用jQuery,您可以向返回序列化模型的控制器端点发出get请求。主要的警告当然是,这种方法需要在初始页面加载的基础上额外往返到服务器,但我不会因此而停止

客户端

$(function() {
    $.getJSON('part/get', function(data) {
      // do something with response
    });
}
服务器端

public class PartChangeModel { }

public class PartModel { }

public class BOMItemModel { }

public class PartViewModel { }

public class PartController : Controller {
    public ActionResult Get() {
        var partChangeModel = new PartChangeModel { /* init properties via repo, etc. */ }
        var partModel = new PartModel { /* init properties via repo, etc. */ }
        var bomItemModel = new BOMItemModel { /* init properties via repo, etc. */ }

        var viewModel = new PartViewModel {
            PartChangeModel = partChangeModel,
            PartModel = partModel,
            BOMItemModel = bomItemModel
        }

        return Json(viewModel);
    }
}

正在为此尝试一些HTML帮助程序。这似乎奏效了

 public static MvcHtmlString SerializeJsonForClient(this HtmlHelper helper, string JavascriptVariableName, object ObjectToSerialize)
        {
            return MvcHtmlString.Create(String.Format("var {0} = {1};", JavascriptVariableName, Json.Encode(ObjectToSerialize)));
        }
然后你可以这样从Razor中调用它:

<script type="text/javascript">
    @Html.SerializeJsonForClient("PartChangeModel", Model.PartChange)
    @Html.SerializeJsonForClient("PartModel", Model.Part)
    @Html.SerializeJsonForClient("BOMItemModel", Model.BOMItem)
</script>
<script type="text/javascript">
    @Model.PartChange.ToJson("PartChangeModel")
    @Model.Part.ToJson("PartModel")
    @Model.BOMItem.ToJson("BOMItemModel")
</script>

@SerializeJsonForClient(“PartChangeModel”,Model.PartChange)
@SerializeJsonForClient(“PartModel”,Model.Part)
@SerializeJsonForClient(“bomiteModel”,Model.BOMItem)

根据A-Dubb的建议,我将其放入扩展方法中。哪种方式更有意义?大概6.5打之类的

 public static MvcHtmlString ToJson(this Object ObjectToSerialize, string JavascriptVariableName)
        {
            return MvcHtmlString.Create(String.Format("var {0} = {1};", JavascriptVariableName, Json.Encode(ObjectToSerialize)));
        }
然后你可以这样从Razor中调用它:

<script type="text/javascript">
    @Html.SerializeJsonForClient("PartChangeModel", Model.PartChange)
    @Html.SerializeJsonForClient("PartModel", Model.Part)
    @Html.SerializeJsonForClient("BOMItemModel", Model.BOMItem)
</script>
<script type="text/javascript">
    @Model.PartChange.ToJson("PartChangeModel")
    @Model.Part.ToJson("PartModel")
    @Model.BOMItem.ToJson("BOMItemModel")
</script>

@Model.PartChange.ToJson(“PartChangeModel”)
@Model.Part.ToJson(“PartModel”)
@Model.BOMItem.ToJson(“BOMItemModel”)

是的,我考虑过这一点,但我非常努力地抑制HTTP调用,我仍然希望将其推到服务器端。我做了足够多的HTTP调用来提取我所有的json数据。:)我倾向于采用的另一种方法是在对象上实现.ToJson()扩展方法,并将其置于Newtonsoft.Json之类的东西之上。因此,在您看来,您可以执行类似var PartChangeModel=@Model.PartChange.ToJson()的操作;var PartModel=@Model.Part.ToJson();var BOMItemModel=@Model.BOMItem.ToJson();我不知道记号显然是转义的/html编码的,所以我想你需要这样做,除非你使用@:语法来呈现纯文本。我为此创建了一个HTML帮助程序。我考虑了一个扩展方法,但是我要扩展什么类型的对象,对象?我不想让那个方法出现在所有东西上,这就是为什么你要命名它。它只会在您引用该名称空间后显示。就像在调用Select、Where、OrderBy等之前必须使用System.Linq添加一样,这里有一个类似的问题,但仍然像我一样: