【问题标题】:Can I separate JsonConvert objects?我可以分离 JsonConvert 对象吗?
【发布时间】:2012-01-10 18:56:24
【问题描述】:

我有以下只有名字和姓氏的代码。 DeserializeObject 正在寻找 FIRST MIDDLE LAST。所以约翰·史密斯会展示,但约翰·P·史密斯不会。有没有办法只查找名字和姓氏?

#region Fields
private string firstName;
private string middleInitial;
private string lastName;
#endregion

#region Properties
public string FirstName
{
    get { return firstName; }
    set { firstName = value; }
}
public string MiddleInitial
{
    get { return middleInitial; }
    set { middleInitial = value; }
}
public string LastName
{
    get { return lastName; }
    set { lastName = value; }
}
#endregion

#region Constructors
public NamedIndividual()
{

}

var namedIndividual = JsonConvert.DeserializeObject<NamedIndividual>(cov.GetAttribute("individual").Value);

【问题讨论】:

  • 你能粘贴 NamedIndividual 是如何声明的吗..
  • 在你的空构造函数内部你可以重载它或者设置你正在寻找的属性..否则从它的外观..看起来所有 3 个属性都将被设置..这样做有意义
  • 确实...谢谢!那么这是否意味着这不是一个真正的问题?我应该删除吗?
  • 你也没有,但你可以投票。如果其他用户遇到同样的问题,也许他们会发现这很有用。在构造函数 this.lastname this 中使用 this.construct .firstname 你听我说的吗?
  • 当你问有没有办法让 FIRST 和 LAST 显示时,你是什么意思?您只想反序列化 FIRST 和 LAST,还是希望 MIDDLE 是可选的?

标签: c# .net json attributes json.net


【解决方案1】:

JSON.NET 有一种很好的方法可以让您将属性标记为不需要 - 您可以使用 DataContractDataMember 属性。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using Newtonsoft.Json;

namespace ConsoleApplication1
{
    [DataContract]
    public class NamedIndividual
    {
        #region Fields
        private string firstName;
        private string middleInitial;
        private string lastName;
        #endregion

        #region Properties

        [DataMember(IsRequired = true)]
        public string FirstName
        {
            get { return firstName; }
            set { firstName = value; }
        }

        [DataMember(IsRequired = false)]
        public string MiddleInitial
        {
            get { return middleInitial; }
            set { middleInitial = value; }
        }

        [DataMember(IsRequired = true)]
        public string LastName
        {
            get { return lastName; }
            set { lastName = value; }
        }

        #endregion

        public NamedIndividual()
        {

        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            string name = "{'FirstName':'David', 'MiddleInitial':'Q', 'LastName':'Hoerster'}";
            string name1 = "{'FirstName':'David', 'LastName':'Hoerster'}";

            var obj = JsonConvert.DeserializeObject<NamedIndividual>(name);
            var obj1 = JsonConvert.DeserializeObject<NamedIndividual>(name1);

            Console.WriteLine(obj.MiddleInitial);
            Console.WriteLine("{0} {1} {2}",obj1.FirstName, obj1.MiddleInitial, obj1.LastName);
        }
    }
}

所以,我将MiddleInitial 标记为可选属性——所以我的 JSON 字符串可以包含或不包含它。如果我将属性标记为必需 (IsRequired=true),那么我的 JSON 字符串最好具有该属性,否则将引发异常。

更新我可能暗示您需要使用DataContract 属性才能使某些属性成为不需要或不需要的属性。 JSON.net 也有自己的一组属性,以及下面@L.B. 的评论,不使用任何属性提供了默认行为,这是不需要的。下面是一个使用 JsonObject 属性的简单示例:

[JsonObject(MemberSerialization=MemberSerialization.OptIn)]
public class NamedIndividual1
{
    [JsonProperty(Required = Required.Always)]
    public string FirstName { get; set; }
    [JsonProperty(Required = Required.Default)]
    public string MiddleInitial { get; set; }
    [JsonProperty(Required = Required.Always)]
    public string LastName { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        string name2 = "{'FirstName':'David', 'LastName':'Hoerster'}";

        var obj2 = JsonConvert.DeserializeObject<NamedIndividual>(name2);

        Console.WriteLine("{0} {1} {2}", obj2.FirstName, obj2.MiddleInitial, obj2.LastName);
    }
}

(我也不能使用任何属性来使所有内容都是可选的。)

希望这会有所帮助!

【讨论】:

  • 默认行为是什么(不指定属性时)?
  • 如果我不使用任何DataMember 除了“必须”属性的例外,我会松动什么。可以通过if(obj.FirstName==null) 轻松检查,速度更快。
  • @svick 默认行为,对于使用DataContract 属性声明的类,是隐藏成员,除非它们应用了DataMember 属性。类似于 WCF 服务。
  • @L.B 如果您仅将DataMember 应用于“必需”属性,则只有这些属性有效。我相信如果您不应用DataMember,那么该属性将不会被反序列化。您可能必须编写自己的转换器。
  • @DavidHoerster,JsonConvert 不需要任何 DataContractDataMember 属性。如果在 json 字符串中找不到,它不会简单地为属性/字段设置任何值(此行为是可变的)。
【解决方案2】:

您可以更改构造函数或将其保留为空构造函数并创建和重载构造函数

public NamedIndividual() 
{
  //empty Constructor
} 
//overloaded constructor
public NamedIndividual(string first, string last)
{
  this.firstname = first;
  this.lastname = last;
} 
 // or pass in the middle as an option

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-19
    • 2012-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-19
    • 1970-01-01
    相关资源
    最近更新 更多