Пример #1
0
        /// <summary>
        /// Deserialize a Threat Model and adds it to the list of known Threat Models.
        /// </summary>
        /// <param name="json">Serialized Json of the Threat Model, as byte array.</param>
        /// <param name="ignoreMissingMembers">Optional flag to specify to ignore information that is unknown.</param>
        /// <param name="newThreatModelId">Optional identifier to be used for the Threat Model replacing its configured one.</param>
        /// <returns>The deserialized Threat Model.</returns>
        public static IThreatModel Deserialize([NotNull] byte[] json,
                                               bool ignoreMissingMembers = false, Guid?newThreatModelId = null)//, bool addToKnownInstances = true)
        {
            IThreatModel result = null;

            if (json.Length > 0)
            {
                string jsonText = null;

                if (json[0] == 0xFF)
                {
                    jsonText = Encoding.Unicode.GetString(json, 2, json.Length - 2);
                }
                else
                {
                    jsonText = Encoding.Unicode.GetString(json);
                }

                if (newThreatModelId.HasValue && newThreatModelId != Guid.Empty)
                {
                    var parsed = JObject.Parse(jsonText);
                    var id     = parsed.GetValue("id")?.ToObject <string>();
                    if (!string.IsNullOrWhiteSpace(id))
                    {
                        jsonText = jsonText.Replace(id, newThreatModelId?.ToString("D"));
                    }
                }

                var binder = new KnownTypesBinder();

                using (var textReader = new StringReader(jsonText))
                    using (var reader = new JsonTextReader(textReader))
                    {
                        var serializer = new JsonSerializer
                        {
                            TypeNameHandling      = TypeNameHandling.All,
                            SerializationBinder   = binder,
                            MaxDepth              = 128,
                            MissingMemberHandling = ignoreMissingMembers
                            ? MissingMemberHandling.Ignore
                            : MissingMemberHandling.Error
                        };
                        result = serializer.Deserialize <IThreatModel>(reader);
                    }

                if (result != null)
                {
                    try
                    {
                        if (!binder.HasUnknownTypes)
                        {
                            result.ResetDirty();
                        }

                        result.SuspendDirty();

                        if (_instances.Any(x => x.Id == result.Id))
                        {
                            throw new ExistingModelException(result);
                        }
                        else
                        {
                            result.Cleanup();
                            result.PropertySchemasNormalization();

                            _instances.Add(result);

                            var method = result.GetType()
                                         .GetMethod("RegisterEvents", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, new Type[] { }, null);
                            if (method != null)
                            {
                                method.Invoke(result, null);
                            }

                            var processors = ExtensionUtils.GetExtensions <IPostLoadProcessor>()?.ToArray();
                            if (processors?.Any() ?? false)
                            {
                                foreach (var processor in processors)
                                {
                                    processor.Process(result);
                                }
                            }
                        }
                    }
                    finally
                    {
                        result.ResumeDirty();
                    }
                }
            }

            return(result);
        }