问题描述
我将以下Json存储为动态环境变量:
{
"LogLevel": 3,"ServiceEndpointId": "11111111-2222-3333-4444-555555555555","ServiceEndpointType": 1
}
检索配置后得到的信息如下:
在“ QuickWatch”中看到过:
格式化后看起来像这样:
到目前为止一切顺利。但是当我序列化结果时,出现以下错误:
'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中而不是在项目本身中时会引起这样的问题吗?
任何提示都非常感谢!