J'ai le fichier de configuration basé sur Json suivant:
{ "ProcessRecognitionConfiguration": { "OrderSelectionConfiguration": { "SelectionDaysInterval": 30, "SelectionDaysMaximum": 365 } } }
En tant que cadre de sérialisation, j'utilise Newtonsoft . Pour sérialiser cette configuration en objets, j'ai implémenté les classes suivantes:
this.ConfigurationSection.GetSection("Processing").Get<ProcessRecognitionConfiguration>()
Dans une classe, j'essaie de sérialiser une section de configuration spécifique dans ces structures de classe en utilisant IConfigurationSection.Get ( ) .
var serializedConfiguration = this.ConfigurationSection.Get<RecognitionConfiguration>();
Mais quand je débogue le code, j'obtiens toujours une variable "vide" serializedConfiguration qui n'est pas nulle, mais toutes les propriétés sont nulles.
Si j'utilise
[JsonObject(MemberSerialization.OptIn)] public class RecognitionConfiguration { [JsonProperty(PropertyName = "PostProcessing", Required = Required.Always)] public PostRecognitionConfiguration PostRecognitionConfiguration { get; set; } [JsonProperty(PropertyName = "Processing", Required = Required.Always)] public ProcessRecognitionConfiguration ProcessRecognitionConfiguration { get; set; } } [JsonObject(MemberSerialization.OptIn)] public class PostRecognitionConfiguration { [JsonProperty(Required = Required.Always)] public ValidationHandlerConfiguration ValidationHandlerConfiguration { get; set; } [JsonProperty] public List<string> MatchingCharacterRemovals { get; set; } } [JsonObject(MemberSerialization.OptIn)] public class ProcessRecognitionConfiguration { [JsonProperty(PropertyName = "OrderSelection", Required = Required.Always)] public OrderSelectionConfiguration OrderSelectionConfiguration { get; set; } }
ou modifie le nom des propriétés dans le fichier json pour correspondre exactement aux noms de propriété dans les classes comme ceci:
{ "PostProcessing": { "ValidationHandlerConfiguration": { "MinimumTrustLevel": 80, "MinimumMatchingTrustLevel": 75 }, "MatchingCharacterRemovals": [ "-", "''", ":" ] }, "Processing": { "OrderSelection": { "SelectionDaysInterval": 30, "SelectionDaysMaximum": 365 } } }
cela fonctionne bien. Avez-vous une idée, pourquoi définir PropertyName sur JsonProperty ne semble pas avoir d'effet?
3 Réponses :
C'est par conception. La liaison à POCO via la configuration se fait par convention. Pas comme la liaison de modèle aux paramètres d'action du contrôleur.
Il fait correspondre les noms de propriété du POCO aux clés du JSON fourni.
Référence Configuration dans ASP.NET Core
Donc, soit vous modifiez les paramètres pour qu'ils correspondent à la classe comme vous l'avez montré dans la question d'origine, soit vous modifiez la classe pour correspondre aux paramètres clés dans le fichier de configuration basé sur Json.
[JsonObject(MemberSerialization.OptIn)] public class RecognitionConfiguration { [JsonProperty(PropertyName = "PostProcessing", Required = Required.Always)] public PostRecognitionConfiguration PostProcessing{ get; set; } [JsonProperty(PropertyName = "Processing", Required = Required.Always)] public ProcessRecognitionConfiguration Processing{ get; set; } } [JsonObject(MemberSerialization.OptIn)] public class PostRecognitionConfiguration { [JsonProperty(Required = Required.Always)] public ValidationHandlerConfiguration ValidationHandlerConfiguration { get; set; } [JsonProperty] public List<string> MatchingCharacterRemovals { get; set; } } [JsonObject(MemberSerialization.OptIn)] public class ProcessRecognitionConfiguration { [JsonProperty(PropertyName = "OrderSelection", Required = Required.Always)] public OrderSelectionConfiguration OrderSelection { get; set; } } public partial class ValidationHandlerConfiguration { [JsonProperty("MinimumTrustLevel")] public long MinimumTrustLevel { get; set; } [JsonProperty("MinimumMatchingTrustLevel")] public long MinimumMatchingTrustLevel { get; set; } } public partial class OrderSelectionConfiguration { [JsonProperty("SelectionDaysInterval")] public long SelectionDaysInterval { get; set; } [JsonProperty("SelectionDaysMaximum")] public long SelectionDaysMaximum { get; set; } }
Merci pour votre réponse. C'est vraiment utile! J'espérais une solution où il est possible d'attribuer des noms de propriété personnalisés comme dans newtonsoft
Bien que ma réponse puisse résoudre le problème d'OP, je ne pense (encore) à aucune situation nécessitant la complexité impliquée. Je recommande fortement d'utiliser celui-ci si possible.
Une question à ce sujet ... Les propriétés [JsonProperty] et [JsonObject] perdent maintenant leur sens?
La modification de PropertyName
sur JsonProperty
a un effet. Voici la même chose que j'ai essayé et cela a fonctionné pour moi:
mes données JSON:
RootObject obj = JsonConvert.DeserializeObject<RootObject>(json);
et le modèle:
public class RootObject { [JsonProperty(PropertyName ="name")] public string Apple { get; set; } public int age { get; set; } public List<string> cars { get; set; } }
Je ne pense pas que cela pose le problème de ma question. Ce n'est pas un problème avec la désérialisation avec Newtonsoft, mais avec l'extension Get<>
de IConfigurationSection
EDIT: J'ai trouvé que celle-ci est beaucoup plus agréable que mes solutions précédentes: liez tout dans un ExpandoObject
, écrivez-les en JSON et utilisez JSON.NET pour les relier. Utilisation du code de cet article :
public class MySettings { [JsonProperty("PostProcessing")] public SomeNameElseSettings SomenameElse { get; set; } public class SomeNameElseSettings { [JsonProperty("ValidationHandlerConfiguration")] public ValidationHandlerConfigurationSettings WhateverNameYouWant { get; set; } public class ValidationHandlerConfigurationSettings { [JsonProperty("MinimumTrustLevel")] public int MinimumTrustLevelFoo { get; set; } [JsonProperty("MinimumMatchingTrustLevel")] public int MinimumMatchingTrustLevelBar { get; set; } } } }
Insérez votre code source là-bas, ou copiez simplement ce fichier (dans ma tentative de tracer le code, je renomme toutes les méthodes en quelque chose comme Bind2
, BindInstance2
etc), et réécrivez le code en conséquence.
Celui-ci est très spécifique à l'implémentation actuelle, il n'est donc pas à l'épreuve du temps: le code actuel appelle config.GetSection (property.Name)
, vous pouvez donc écrire votre propre IConfiguration et indiquez votre propre nom pour la méthode GetSection
et appuyez dessus dans le processus d'amorçage au lieu d'utiliser celui par défaut.
Lorsque vous déboguez et que vous appelez
var serializedConfiguration = this.ConfigurationSection.Get ();
les valeurs existent-elles dans l'objet à ce moment-là avant d'essayer d'enregistrer les enfants?@KieranDevlin J'ai édité mon message pour vous le montrer.
Modifiez votre exemple minimal reproductible et supprimez-en Autofac. La partie intéressante est
ConfigurationSection.Get ()
ainsi que le json qui devrait être désérialisé. Le fait que les propriétés soientnulles
n'a rien à voir avec Autofac, laisser cela dans votre question ne fait qu'ajouter du bruit.@Igor Merci pour vos commentaires. J'ai remanié mon message.
@ rbr94 qui est par conception. La liaison à POCO via la configuration ne ressemble pas aux paramètres de liaison de modèle aux paramètres d'action. Il fait correspondre les noms de propriété sur le POCO aux clés dans le JSON fourni. Lisez ici docs.microsoft.com/en-us/aspnet/core/fundamentals/configurat ion /…