簡體   English   中英

如何在 ASP.NET MVC 中將視圖模型轉換為 JSON 對象?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM