【问题标题】:DataContractJsonSerializer throws exception Expecting state 'Element'.. Encountered 'Text' with name '', namespace ''DataContractJsonSerializer 抛出异常期望状态'元素'..遇到名称为'',命名空间''的'文本'
【发布时间】:2012-03-07 16:29:45
【问题描述】:

我需要帮助来序列化一段 json。

我收到来自休息服务的响应,该服务正在返回 json。之后,我想将请求映射到一个类。我正在使用 DataContractJsonSerializer,但我无法让它工作。

当数据被序列化时,会抛出以下异常:

"Expecting state 'Element'.. Encountered 'Text'  with name '', namespace ''. "

代码如下:

HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse();

Stream responseStreamm = response.GetResponseStream();

StreamReader reader = new StreamReader(responseStreamm);

string streamAsString = reader.ReadToEnd();

MemoryStream memoryStream = new MemoryStream(Encoding.Unicode.GetBytes(streamAsString)) {Position = 0};

DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(List<MyClass>));

List<MyClass> myClass = (List<MyClass>)serializer.ReadObject(memoryStream);

这里是 MyClass:

[DataContract]
public class MyClass
{
    [DataMember]
    public string RawData { get; set; }

    [DataMember]
    public string StudentIdentity { get; set; }

    [DataMember]
    public string FirstName { get; set; }

    [DataMember]
    public string LastName { get; set; }

    [DataMember]
    public string SchoolName { get; set; }

    [DataMember]
    public string SchoolCode { get; set; }

    [DataMember]
    public string TypeOfEducation { get; set; }

    [DataMember]
    public string EducationCode { get; set; }

    [DataMember]
    public string NationalProgram { get; set; }

    [DataMember]
    public string Objective { get; set; }

    [DataMember]
    public string IssuingDate { get; set; }

    [DataMember]
    public string GradeType { get; set; }

    [DataMember]
    public string ProgramRange { get; set; }

    [DataMember]
    public string HourTotal { get; set; }

    [DataMember]
    public string BasicEligibility { get; set; }

    [DataMember]
    public string OccupationCompetence { get; set; }

    [DataMember]
    public string CourseOfStudyFromSchool { get; set; }

    [DataMember]
    public string Software { get; set; }

    [DataMember]
    public string SoftwareProvider { get; set; }

    [DataMember]
    public string ProgramType { get; set; }

    [DataMember]
    public string Note { get; set; }
}

服务的响应是:

"[{\"RawData\":\"\",\"StudentIdentity\":\"450101\",\"FirstName\":\"Kalle\",\"LastName\":\"Karlsson\",\"SchoolName\":\"\",\"SchoolCode\":\"SKL123\",\"TypeOfEducation\":\"\",\"EducationCode\":\"Code\",\"NationalProgram\":\"\",\"Objective\":\"Obj\",\"IssuingDate\":\"2012-01-28\",\"GradeType\":\"GradeType\",\"ProgramRange\":\"1\",\"HourTotal\":\"2000\",\"BasicEligibility\":\"BE\",\"OccupationCompetence\":\"OC\",\"CourseOfStudyFromSchool\":\"Y\",\"Software\":\"HAL213\",\"SoftwareProvider\":\"SchoolSoft\",\"ProgramType\":\"C\",\"Note\":\"Notering\",\"CourseInformation\":[{\"CourseCode\":\"ABC555\",\"Grade\":\"VG\",\"GradeDate\":\"2012-01-28\",\"Points\":\"50\",\"Comment1\":\"Kommentar1\",\"Comment2\":\"\",\"Comment3\":\"\",\"AddtionalInformation\":\"Info\",\"Exceptions\":null},{\"CourseCode\":\"DFG333\",\"Grade\":\"G\",\"GradeDate\":\"2012-01-28\",\"Points\":\"60\",\"Comment1\":\"\",\"Comment2\":\"\",\"Comment3\":\"\",\"AddtionalInformation\":\"\",\"Exceptions\":null}],\"Exceptions\":[]}]"

非常感谢您的帮助!

编辑:

我补充的是服务代码:

List<MyClass> myClass = validationManager.GetXmlAsAListOfEducationInformationObject();

JavaScriptSerializerserializer = new JavaScriptSerializer();

string jsonData = serializer.Serialize(myClass);

return jsonData;

【问题讨论】:

  • 你能发布更多关于服务代码的上下文吗?我怀疑额外的编码层来自将您的字符串包装在 JSON 字符串中的服务层。您可能希望您的服务函数返回类型 List&lt;MyClass&gt;,而不是 string,它可能会自动执行 JSON 序列化。取决于您使用的服务。
  • 当被解码的数据不是有效的 JSON 时,你也会得到这个错误。例如:字符串"1,2,3"在解码时会报错,因为"1,2,3"是一个有效的JSON但不是一个有效的object;如果数据是“[1,2,3]”,它会起作用,因为这是一个数组对象,可以解码为一个数组。

标签: c# json serialization


【解决方案1】:

我遇到了同样的问题。

我正在从客户端(使用 jQuery 的浏览器)向我的服务器应用程序(使用 c# 的 IIS-ASP.NET)发送一个 JSON 对象。

JSON 包含内部 JSON 对象,因此存在问题。

下面我列出了 JSON 对象(示例案例的最小版本)、必须构造的 c# 类以及将 JSON 反序列化为 C# 数据类的代码。

JSON 对象:

"{"Conference_id":"9","SubmissionType":{"Value":"1"},"TextPublishType":[{"Value":"12"},{"Value":"9"}],"Title":"aTitle"}"  

注意:SubmissionType 属性包含一个内部 JSON 作为其值,TextPublishType 属性包含一个 JSON 对象数组作为其值。

必须构造的C#类(取决于JSON结构):

public class Abstract 
{
    public int Conference_id { get; set; }
    public SubmissionTypeClass SubmissionType { get; set; }
    public List<TextPublishTypeClass> TextPublishType{ get; set; }
}  

SubmissionType 定义为不同的类,因为它包含一个内部 JSON 对象。
TextPublishType 定义为不同类的列表,因为它包含一个内部数组 JSON 对象。

public class SubmissionTypeClass 
{
    public int Value { get; set; }
}

public class TextPublishTypeClass 
{
    public int Value { get; set; }
}

这两个类只包含一个属性。这是因为在 JSON 对象上,内部 JSON 仅包含一个属性(值)。这是一个仅针对答案案例的简单示例。如果您想要 JSON 对象上的更多属性,则必须在类定义中使用相同的键名来定义它们。

反序列化代码:

Abstract theAbstract = Activator.CreateInstance<Abstract>();
MemoryStream memoryStream = new MemoryStream(Encoding.Unicode.GetBytes("the above JSON text"));
DataContractJsonSerializer serializer = new DataContractJsonSerializer(theAbstract.GetType());
theAbstract = (Abstract)serializer.ReadObject(memoryStream);
memoryStream.Dispose();

对于更复杂的 JSON 对象,唯一要做的就是创建更复杂的类结构。
我希望它会有所帮助。

【讨论】:

  • 谢谢乔治 - 这个人真的应该给你正确的答案状态。
  • 我必须说我遇到了这个问题,但我的问题是我的序列化根本不是 json...在发送正确的 json 和嵌套对象后,我没有触及任何我的类类型,一切正常。也许只是向所有涉及的类型添加无参数构造函数就不需要执行上述操作(标记类抽象等)?这是我的场景。
【解决方案2】:

当我反序列化它时,该服务响应有效,这让我怀疑您与 MemoryStream 的额外舞蹈导致某处出现空流。只需简化它并将响应流直接传递给序列化器:

HttpWebResponse response = webRequest.GetResponse();
var serializer = new DataContractJsonSerializer(typeof(List<MyClass>));
var list = (List<MyClass>)serializer.ReadObject(response.GetResponseStream());

【讨论】:

  • 恐怕这会产生与我在原始代码中遇到的相同的异常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-30
  • 1970-01-01
  • 2013-04-04
  • 2015-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多