Json.net反序列化:处理错误,重试反序列化无法反序列化的对象并继续反序列化

时间:2016-01-12 13:32:34

标签: c# json.net

我的错误处理修复了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两次来实现。

1 个答案:

答案 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);