【问题标题】:Output same JSON as in ApiController in Razor view在 Razor 视图中输出与 ApiController 中相同的 JSON
【发布时间】:2012-06-19 16:18:16
【问题描述】:

我正在尝试在我的 Razor 视图中直接输出 JSON。被序列化的对象是IEnumerable<ItemDto>(见下面的定义)。我想将它序列化为从ApiController 返回的相同 JSON。这是我尝试过的:

  • 使用@Json.Encode(theValue) 时,它会忽略DataMember,因此属性名称错误(首字母大写)。
  • 当使用DataContractJsonSerializer(并将IEnumerable<ItemDto> 转换为IList<ItemDto>)时,它将ImageDto.Sizes 输出为[{ Key: 'foo', Value: <object> }],但ApiController 正确地执行{ 'foo': <object> }

这是我的课程:

    [DataContract]
    public class ItemDto
    {
        [DataMember(Name = "id")]
        public int Id { get; set; }

        [DataMember(Name = "title")]
        public string Title { get; set; }

        [DataMember(Name = "image")]
        public ImageDto Image { get; set; }

        [DataMember(Name = "price")]
        public decimal Price { get; set; }
    }

    [DataContract]
    public class ImageDto
    {
        [DataMember(Name = "id")]
        public Guid Id { get; set; }
        [DataMember(Name = "sizes")]
        public Dictionary<String, ImageSizeDto> Sizes { get; set; }
    }

    [DataContract]
    public class ImageSizeDto
    {
        [DataMember(Name = "url")]
        public string Url { get; set; }
        [DataMember(Name = "w")]
        public int Width { get; set; }
        [DataMember(Name = "h")]
        public int Height { get; set; }
    }

目标是避免单独的GET 请求几乎每个页面都需要数据。

所需的 JSON:

[{"id":6,
 "title":"Foo bar baz",
 "image":
    {"id":"fb2a3b4a-5ae5-4d9d-baff-72e107aa6e9c",
     "sizes":
        {"Original": {"url":"http://example.com/a", "w":-1, "h":-1},
         "Thumbnail": {"url":"http://example.com/b", "w":130, "h":73},
         "LargeThumbnail": {"url":"http://example.com/c", "w":220,"h":124},
         "Popup": {"url":"http://example.com/d", "w":256, "h":256},
         "FullWidth": {"url":"http://example.com/e", "w":930, "h":524}}},
 "price":79}]

【问题讨论】:

    标签: asp.net-mvc razor asp.net-web-api


    【解决方案1】:

    你可以使用Json.NET:

    [DataContract]
    public class ItemDto
    {
        [DataMember(Name = "id")]
        public int Id { get; set; }
    
        [DataMember(Name = "title")]
        public string Title { get; set; }
    
        [DataMember(Name = "image")]
        public ImageDto Image { get; set; }
    
        [DataMember(Name = "price")]
        public decimal Price { get; set; }
    }
    
    [DataContract]
    public class ImageDto
    {
        [DataMember(Name = "id")]
        public Guid Id { get; set; }
        [DataMember(Name = "sizes")]
        public Dictionary<String, ImageSizeDto> Sizes { get; set; }
    }
    
    [DataContract]
    public class ImageSizeDto
    {
        [DataMember(Name = "url")]
        public string Url { get; set; }
        [DataMember(Name = "w")]
        public int Width { get; set; }
        [DataMember(Name = "h")]
        public int Height { get; set; }
    }
    
    class Program
    {
        static void Main()
        {
            var items = new[] 
            {
                new ItemDto
                {
                    Id = 6,
                    Title = "Foo bar baz",
                    Image = new ImageDto
                    {
                        Id = Guid.NewGuid(),
                        Sizes = new Dictionary<string, ImageSizeDto>
                        {
                            { "Original", new ImageSizeDto { Url = "http://example.com/a", Width = -1, Height = -1 } },
                            { "Thumbnail", new ImageSizeDto { Url = "http://example.com/b", Width = 130, Height = 73 } },
                        },
                    },
                    Price = 79
                }
            };
    
            Console.WriteLine(JsonConvert.SerializeObject(items));
        }
    }
    

    输出:

    [
        {
            "id": 6,
            "title": "Foo bar baz",
            "image": {
                "id": "6a1c1d34-3e78-4303-8edd-d8541dd915e7",
                "sizes": {
                    "Original": {
                        "url": "http://example.com/a",
                        "w": -1,
                        "h": -1
                    },
                    "Thumbnail": {
                        "url": "http://example.com/b",
                        "w": 130,
                        "h": 73
                    }
                }
            },
            "price": 79
        }
    ]
    

    请注意,在 ASP.NET MVC 4 RTM Json.Net 中将是 default serialzier。在此之前,只需将内置序列化程序与 Json.NET 交换即可,如 Scott Hanselman 的博客文章所述。

    【讨论】:

    • 谢谢!直到现在我才知道 Json.Net 有多棒...... :)
    • @Darin,你有任何关于 MVC 4 RTM 将使用 JSON.NET 的参考吗?我发现很多说 Web API 使用它(并且可以确认在 RC 中就是这种情况),但似乎 MVC 4 使用 DataContractSerializer。我不希望在 RC + RTM 之间发生如此重大的变化。
    • @Richard,你没看我的回答吗?我在其中提供了指向此参考的链接:hanselman.com/blog/…。如果您还没有阅读,我引用 Hanselman:We on the web team will be including JSON.NET as the default JSON Serializer in Web API when it releases, so that'll be nice.
    • 包含在您的报价中:“在 Web API 中”。在您的回答中,您说这将是 MVC 中的默认设置。虽然 Web API 构成了 ASP.NET MVC4 的一部分,但它们并不是一回事。 MVC4 RC 中视图页面的 Json.Encode 使用 DataContractSerializer。 Web API 使用 JSON.NET
    • 抱歉,如果您误解了我的回答。 Json.NET 将成为 Web API 的默认序列化程序。不知道 ASP.NET MVC。对我来说,它是自早期以来的默认序列化程序,所以我真的不在乎它是否是默认值:-) 如果它是默认值,我所要做的就是删除我当前正在替换 JavaScriptSerializer 的自定义扩展方法使用 Json.NET。如果不是,我只是保留它们。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-22
    • 1970-01-01
    • 1970-01-01
    • 2014-05-08
    • 1970-01-01
    • 2016-06-19
    相关资源
    最近更新 更多