使用DataContractJsonSerializer进行序列化时获取InvalidDataContractException

问题描述

我将以下Json存储为动态环境变量:

{
"LogLevel": 3,"ServiceEndpointId": "11111111-2222-3333-4444-555555555555","ServiceEndpointType": 1
}

检索配置后得到的信息如下:

在“ QuickWatch”中看到过:

Quick Watch

格式化后看起来像这样:

Quick Watch formatted

到目前为止一切顺利。但是当我序列化结果时,出现以下错误:

'System.Runtime.Serialization.InvalidDataContractException: Type 'Common.Logging.LogConfigCurrent' cannot be serialized. Consider marking it with the DataContractAttribute attribute,and marking all of its members you want serialized with the DataMemberAttribute attribute.  If the type is a collection,consider marking it with the CollectionDataContractAttribute.  See the Microsoft .NET Framework documentation for other supported types.
   at System.Runtime.Serialization.DataContract.DataContractCriticalHelper.ThrowInvalidDataContractException(String message,Type type)
   at System.Runtime.Serialization.DataContract.DataContractCriticalHelper.CreateDataContract(Int32 id,RuntimeTypeHandle typeHandle,Type type)
   at System.Runtime.Serialization.DataContract.DataContractCriticalHelper.GetDataContractSkipValidation(Int32 id,Type type)
   at System.Runtime.Serialization.Json.DataContractJsonSerializer.get_RootContract()
   at System.Runtime.Serialization.Json.DataContractJsonSerializer.InternalIsStartObject(XmlReaderDelegator reader)
   at System.Runtime.Serialization.Json.DataContractJsonSerializer.InternalReadObject(XmlReaderDelegator xmlReader,Boolean verifyObjectName)
   at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader,Boolean verifyObjectName,DataContractResolver dataContractResolver)
   at System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadObject(XmlDictionaryReader reader)
   at Common.Serializer.JsonSerializer.GetObjectsFromJson[T](String json)
   at Common.Logging.LogConfig.InitLoggerConfig(IOrganizationService orgService,ITracingService tracer)'
   at Common.Logging.LoggingConfig..ctor(IOrganizationService orgService,ITracingService tracer)
   at Common.Logging..ctor(IOrganizationService orgService,IServiceEndpointNotificationService serviceEndpointNotificationService,IExecutionContext context,ITracingService traceService)'

我这样序列化:

更新:添加DataContractAttribute没有帮助。我删除了“例外”中的建议,因为几天前该建议没有问题。

var logSettings = JsonSerializer.GetObjectsFromJson<LogConfigCurrent>(result.Entities[0].GetAttributeValue<string>("value"));

以及来自NameSpace“ Common.Serializer”的相应方法:

public static T GetObjectsFromJson<T>(string json) where T : class
        {
            using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(json)))
            {
                var ser = new DataContractJsonSerializer(typeof(T));
                var rootObject = ser.ReadObject(ms) as T;
                ms.Close();
                return rootObject;
            }
        } 

和班级:

using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Sdk;
using System;
using System.Diagnostics;
using System.Linq;
using System.ServiceModel.Dispatcher;
using System.Text.RegularExpressions;
using Common.Serializer;

namespace Common.Logging
{
    public sealed class LogConfigCurrent
    {
        public int LogLevel { get; set; }
        public string ServiceEndpointId { get; set; }
        public int ServiceEndpointType { get; set; }
    }

    public sealed class LoggingConfig
    {
        public TraceLevel LogLevel { get; private set; } = TraceLevel.Info;

        public Guid ServiceEndpointId { get; private set; }

        public ServiceEndpointType EndpointType { get; private set; }

        public LoggingConfig(IOrganizationService orgService,ITracingService tracer)
        {
            try
            {
                InitLoggerConfig(orgService,tracer);
            }
            catch(Exception ex)
            {
                throw ex;
            }
        }

         private void InitLoggerConfig(IOrganizationService orgService,ITracingService tracer)
        {
            try
            {
                var fetchXml = "<fetch>" +
                                   "<entity name='environmentvariablevalue'>" +
                                    "<attribute name='value'/>" +
                                     "<link-entity name='environmentvariabledefinition' from='environmentvariabledefinitionid' to='environmentvariabledefinitionid' link-type='inner' alias='ah'>" +
                                      "<filter type='and'>" +
                                        "<condition attribute='schemaname' operator='eq' value='configuration' />" +
                                      "</filter>" +
                                     "</link-entity>" +
                                   "</entity>" +
                                  "</fetch>";

                var conversionRequest = new FetchXmlToQueryExpressionRequest
                {
                    FetchXml = fetchXml
                };

                var conversionResponse = (FetchXmlToQueryExpressionResponse)orgService.Execute(conversionRequest);

                var queryExpression = conversionResponse.Query;

                var result = orgService.RetrieveMultiple(queryExpression);

                if (result.Entities.Any())
                {
                    var logSettings = JsonSerializer.GetObjectsFromJson<LogConfigCurrent>(result.Entities[0].GetAttributeValue<string>("value"));
                    EndpointType = (ServiceEndpointType)logSettings.ServiceEndpointType;
                    ServiceEndpointId = new Guid(logSettings.ServiceEndpointId);
                    LogLevel = (TraceLevel)logSettings.LogLevel;
                }
                else
                {
                    EndpointType = ServiceEndpointType.ServiceEndpoint;
                    ServiceEndpointId = Guid.Empty;
                    LogLevel = TraceLevel.Off;
                    tracer.Trace($"No Configuration found! LogLevel was set to {TraceLevel.Off}");
                }
            }
            catch(Exception ex)
            {
                throw new Exception($"Configuration could not be loaded: Error '{ex.ToString()}'");
            }
        }
    }
}

这可能是转义的问题,还是我在这里错过了重要的事情?有人可以给我提示吗?

解决方法

我要分享的更新:

我已经找到了解决此问题的方法,但是我不明白为什么会发生这种情况。

上述JsonSerializer的代码

JsonSerializer.GetObjectsFromJson<....>(....);
序列化/反序列化的

最初是在我开发的自定义nuget中实现的。然后,在主要项目中引用了此nuget并提供了它。

因此,我尝试从nuget中删除Serializer-Class,并在项目中直接添加了完全相同的类。之后,不再抛出异常,并且对数据进行反序列化也没有问题。

插件程序集和nuget具有相同的.net版本。

有人知道为什么将这样的代码放在nuget中而不是在项目本身中时会引起这样的问题吗?

任何提示都非常感谢!

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...