JSON解串器无法创建&填充对象 [英] JSON deserializer cannot create & populate object

查看:87
本文介绍了JSON解串器无法创建&填充对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,



我一直在争论将某个json片段反序列化为部署IEnumerable接口的对象,这样我就可以遍历其列表并使用一些它的属性作为SQL查询中的参数。



我已经收到一些没有解决问题的答案。你可以在这里查看:



c# - 将JSON反序列化为IEnumerable错误< T>对象 - 堆栈溢出 [ ^ ]



我将发布一个json字符串的示例,我的类来处理反序列化,错误我当我尝试这样做时接收,以及在正确反序列化时如何使用新对象。



我尝试了什么:



Hello,

I've been wrangling with deserializing a certain json snippet into an object that deploys the IEnumerable interface so I can loop through its list and use some of its attributes as parameters in a SQL query.

I already received a few answers that didn't solve the problem. You can view them here:

c# - Error Deserializing JSON into IEnumerable<T> Object - Stack Overflow[^]

I will post an example of the json string, my classes to handle the deserialization, the error I'm receiving when I attempt to do so, and how the new object will be being used when it is correctly deserialized.

What I have tried:

//Json Example:

{
    	"ErrorCode":""
    	,"ErrorMessage":""
    	,"AppointmentReasonList":[
    		{
    			"ClassCode":"851"
    			,"ClassDescription":"newpat"
    			,"Active":true
    			,"IsPatientRelated":true
    			,"ReasonCodeList":[
    				{
    					"Code":"851"
    					,"Description":"Emergency New Patient Visit"
    					,"Duration":15
    					,"Active":true
    				}
    				,{
    					"Code":"BH NEW"
    					,"Description":"BH NEW"
    					,"Duration":15
    					,"Active":true
    				}
    							]
    		}
    		,{
    			"ClassCode":"ANE"
    			,"ClassDescription":"Anesthesia"
    			,"Active":true
    			,"IsPatientRelated":true
    			,"ReasonCodeList":[
    				{
    					"Code":"123456"
    					,"Description":"This is only a test"
    					,"Duration":15
    					,"Active":true
    				}
    								]
    		}					
    							]
    }

 //Classes to handle JSON structure

        public class AppointmentReasonResponse
        {
            public string ErrorCode { get; set; }
            public string ErrorMessage { get; set; }
            public AppointmentReasonList AppointmentReasonList { get; set; }
        }

        public class AppointmentReasonList : IEnumerable<AppointmentReason>
        {

            public List<AppointmentReason> AppointmentReasonLi { get; set; }

            IEnumerator<AppointmentReason> IEnumerable<AppointmentReason>.GetEnumerator()
            {
                foreach (AppointmentReason ApptReason in AppointmentReasonLi)
                {
                    yield return ApptReason;
                }
            }

            public IEnumerator<AppointmentReason> GetEnumerator()
            {
                return AppointmentReasonLi.GetEnumerator();
            }

            IEnumerator IEnumerable.GetEnumerator()
            {
                return this.GetEnumerator();
            }
        }

        public class AppointmentReason 
        {

            public string ClassCode { get; set; }
            public string ClassDescription { get; set; }
            public bool Active { get; set; }
            public bool IsPatientRelated { get; set; }
            public ReasonCodeList ReasonCodeList { get; set; }
        }

        public class ReasonCodeList : IEnumerable<ReasonCode>
        {
            public List<ReasonCode> ReasonCodeLi { get; set; }

            IEnumerator<ReasonCode> IEnumerable<ReasonCode>.GetEnumerator()
            {
                // Return the array object's IEnumerator.
                foreach (ReasonCode Reason in ReasonCodeLi)
                {
                    yield return Reason;
                }
            }

            public IEnumerator<ReasonCode> GetEnumerator()
            {
                // Return the array object's IEnumerator.
                return ReasonCodeLi.GetEnumerator();
            }

            IEnumerator IEnumerable.GetEnumerator()
            {
                // call the generic version of the method
                return this.GetEnumerator();
            }
        }

        public class ReasonCode
        {
            public string Code { get; set; }
            public string Description { get; set; }
            public int Duration { get; set; }
            public bool Active { get; set; }
        }

//use of resulting object

jarray = JsonConvert.DeserializeObject<AppointmentReasonResponse>(json);
        foreach (AppointmentReason ApptReason in jarray.AppointmentReasonList)
        {
            foreach (ReasonCode Reason in ApptReason)
            {
                AddInterfacePMReasonCode(PracticeID, Reason.Code, Reason.Description);
            }
        }





这是我得到的错误:





Here is the error I'm getting:

Quote:

{无法创建和填充列表类型AppointmentReasonList。路径'AppointmentReasonList',第1行,第59位。}}

{"Cannot create and populate list type AppointmentReasonList. Path 'AppointmentReasonList', line 1, position 59."}





非常喜欢你能提供的任何帮助反馈。



Would love any help feedback you can provide.

推荐答案

你最大的问题是 AppointmentReasonList ReasonCodeList 类。在您的JSON文档中,这些表示为集合。但是,由于这两个类只是实现 IEnumerable {T} ,因此反序列化器无法向集合中添加元素。



考虑直接从 List {T} 类继承或实现 ICollection {T} IList {T}



在我的实验中,这两个都解决了你注意到的问题。



另外,你的一个 foreach 循环无效, AppointmentReason 不是可枚举的,你可能意味着 ApptReason.ReasonCodeList



所以,只是为了澄清,下面是推荐的修复。每个都在VS 2017中进行了测试(调用了缺少的AddInterfaceRMReasonCode注释掉)。



这是 foreach <的推荐修复/ code>循环:



You're biggest problems are with the AppointmentReasonList and ReasonCodeList classes. In your JSON document, these are represented as collections. However, since both classes simply implement IEnumerable{T}, there is no way the de-serializer can add elements to the collection.

Consider either inheriting directly from the List{T} class or implementing ICollection{T} or IList{T}.

In my experiments, both of these resolved the issue you note.

Separately, one of your foreach loops is not valid, AppointmentReason is not enumerable, you probably mean ApptReason.ReasonCodeList.

So, just to clarify, below are the recommended fixes. Each has been tested in VS 2017 (with the call to the missing AddInterfaceRMReasonCode commented out).

This is the recommended fix to the foreach loop:

foreach (AppointmentReason ApptReason in jarray.AppointmentReasonList)
{
  foreach (ReasonCode Reason in ApptReason.ReasonCodeList)
  {
    AddInterfacePMReasonCode(PracticeID, Reason.Code, Reason.Description);
  }
}





这是解决课程问题的最简单方法:





This is the easiest fix to the problems with your classes:

public class AppointmentReasonList : List<AppointmentReason>
{
}

public class ReasonCodeList : List<ReasonCode>
{
}





如果您只是提供一些代码片段,并且有理由不使用最简单的修复,下面是一个最接近原始代码的修复:





In case you were simply providing some code clips, and have a reason for not using the simplest fix, below is a fix that is closest to your original code:

public class AppointmentReasonList : ICollection<AppointmentReason>
{
	public AppointmentReasonList()
	{
		AppointmentReasonLi = new List<AppointmentReason>();
	}

	public List<AppointmentReason> AppointmentReasonLi { get; set; }

	public int Count
	{
		get { return AppointmentReasonLi.Count; }
	}

	public bool IsReadOnly
	{
		get
		{
			return false;
		}
	}

	public void Add(AppointmentReason item)
	{
		AppointmentReasonLi.Add(item);
	}

	public void Clear()
	{
		AppointmentReasonLi.Clear();
	}

	public bool Contains(AppointmentReason item)
	{
		return AppointmentReasonLi.Contains(item);
	}

	public void CopyTo(AppointmentReason[] array, int arrayIndex)
	{
		AppointmentReasonLi.CopyTo(array, arrayIndex);
	}

	public IEnumerator<AppointmentReason> GetEnumerator()
	{
		return AppointmentReasonLi.GetEnumerator();
	}

	public bool Remove(AppointmentReason item)
	{
		return AppointmentReasonLi.Remove(item);
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return GetEnumerator();
	}
}

public class ReasonCodeList : ICollection<ReasonCode>
{
	public ReasonCodeList()
	{
		ReasonCodeLi = new List<ReasonCode>();
	}

	public List<ReasonCode> ReasonCodeLi { get; set; }

	public int Count
	{
		get { return ReasonCodeLi.Count; }
	}

	public bool IsReadOnly
	{
		get
		{
			return false;
		}
	}

	public void Add(ReasonCode item)
	{
		ReasonCodeLi.Add(item);
	}

	public void Clear()
	{
		ReasonCodeLi.Clear();
	}

	public bool Contains(ReasonCode item)
	{
		return ReasonCodeLi.Contains(item);
	}


	public void CopyTo(ReasonCode[] array, int arrayIndex)
	{
		ReasonCodeLi.CopyTo(array, arrayIndex);
	}

	public IEnumerator<ReasonCode> GetEnumerator()
	{
		return ReasonCodeLi.GetEnumerator();
	}


	public bool Remove(ReasonCode item)
	{
		return ReasonCodeLi.Remove(item);
	}


	IEnumerator IEnumerable.GetEnumerator()
	{
		return GetEnumerator();
	}
}





祝你好运,希望这会有所帮助。



-Eric。



Good luck, hope this helps.

-Eric.


这篇关于JSON解串器无法创建&amp;填充对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆