我的错误处理修复了Form
的反序列化问题。
我现在的问题是,如何在不中断整个反序列化过程并重新尝试的情况下,重新尝试在进程中反序列化有问题的对象?
首先,我将错误处理设置如下JsonConvert.DeserializeObject
序列化程序类如下所示:
JsonSerializerSettings.Error = HandleCouldNotLoadAssemblyError;
public class Serializer
{
private JsonSerializerSettings Settings { get; set; }
public Serializer()
{
Settings = new JsonSerializerSettings(); // todo: add converters
Settings.TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Full;
Settings.TypeNameHandling = TypeNameHandling.Objects;
Settings.PreserveReferencesHandling = PreserveReferencesHandling.Objects;
Settings.Error = HandleCouldNotLoadAssemblyError;
}
private void HandleCouldNotLoadAssemblyError(object sender, ErrorEventArgs args)
{
if (args != null && args.ErrorContext != null && args.ErrorContext.Error != null && args.ErrorContext.Error.GetType() == typeof(JsonSerializationException))
{
Logger.Error(args.ErrorContext.Error);
foreach (var repository in DeviceInformationManager.InformationSources.OfType<DeviceDriverRepository.DeviceDriverRepository>())
{
var result = repository.LoadType(args.CurrentObject.GetType().FullName);
if (result != null)
{
//args.CurrentObject = JsonConvert.DeserializeObject("SUBSTRING OF SERIALIZED DATA");
args.ErrorContext.Handled = true;
break;
}
}
}
}
public string Serialize(object obj)
{
// Serialize
return JsonConvert.SerializeObject(obj, Formatting.Indented, Settings);
}
public T Deserialize<T>(string serializedData)
{
// Deserialize
return JsonConvert.DeserializeObject<T>(serializedData, Settings);
}
失败的原因是我的程序集在运行时动态加载。在错误处理中,我加载了缺少的程序集。
目前,反序列化只能通过调用json.net
两次来实现。
答案 0 :(得分:1)
dbc让我走上正轨。所以我编写了一个类型的活页夹来解决我的问题:
/// <summary>
/// This binder looks for not found <see cref="Type"/>s in the unloaded assemblies of the repositories.
/// </summary>
public class RepositoryTypesBinder : DefaultSerializationBinder
{
public override Type BindToType(string assemblyName, string typeName)
{
Type type = null;
try
{
type = base.BindToType(assemblyName, typeName);
if (type != null)
{
return type;
}
}
catch (JsonSerializationException)
{
// Type has not been found, so try to find type in some repositories
foreach (var repository in DeviceInformationManager.InformationSources.OfType<DeviceDriverRepository.DeviceDriverRepository>())
{
// Search for assembly paths and check their names
foreach (var driverUri in repository.GetDriverUris(null))
{
var targetAssemblyName = AssemblyName.GetAssemblyName(driverUri.LocalPath);
if (targetAssemblyName != null && targetAssemblyName.FullName.Equals(assemblyName))
{
// Load assembly into AppDomain
Assembly assembly = Assembly.Load(targetAssemblyName);
type = assembly.GetType(typeName, false);
if (type != null)
{
return type; // If type was found: finish
}
// else continue
}
}
}
// If not sufficient type has found until here: throw Error;
throw;
}
return null;
}
public override void BindToName(Type serializedType, out string assemblyName, out string typeName)
{
assemblyName = serializedType.Assembly.FullName;
typeName = serializedType.FullName;
}
}
像这样使用:
var Settings = new JsonSerializerSettings();
Settings.Binder = new RepositoryTypesBinder();
JsonConvert.DeserializeObject<T>(serializedData, Settings);