Verwendung NewtonSoft:
var vm = new CreateProjectViewModel();
string serialized = JsonConvert.SerializeObject(vm);
EDIT
Können Sie Ihre Antwort auf umfassen die Serialisierung der View-Modell Anmerkungen erweitern wie [ Anzeige (Name = "Projektname")] und [MaxLength (128)]?
Mit anderen Worten: "Kann ich die an Eigenschaften angelegten Attribute serialisieren?"
Dies ist nicht etwas, das in den meisten Bibliotheken out-of-the-box verfügbar ist. Wir müssen dafür einen eigenen benutzerdefinierten Konverter erstellen. Zum Glück gibt uns NewtonSoft die Möglichkeit, unsere eigenen Konverter zu schreiben. Dieser ist nicht trivial, aber machbar. Hier ist ein benutzerdefinierter Konverter, der die Attribute serialisiert.
Individuelle Converter
public class KeysJsonConverter<T> : JsonConverter {
private readonly Type[] _types;
public KeysJsonConverter(params Type[] types) {
_types = types;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
JToken t = JToken.FromObject(value);
if(t.Type != JTokenType.Object) {
t.WriteTo(writer);
}
else {
JObject o = (JObject) t;
IList<JProperty> jProperties = o.Properties().ToList();
PropertyInfo[] viewModelProperties = typeof(T).GetProperties();
foreach(var thisVmProperty in viewModelProperties) {
object[] thisVmPropertyAttributes = thisVmProperty.GetCustomAttributes(true);
var jObjectForVmProperty = new JObject();
var thisProperty = jProperties.Single(x => x.Name == thisVmProperty.Name);
jObjectForVmProperty.Add("ActualValue", thisProperty.Value);
foreach(var thisVmPropertyAttribute in thisVmPropertyAttributes) {
if (thisVmPropertyAttribute is MaxLengthAttribute) {
CreateObjectForProperty(thisVmPropertyAttribute as MaxLengthAttribute,
jObjectForVmProperty);
}
else if (thisVmPropertyAttribute is RequiredAttribute) {
CreateObjectForProperty(thisVmPropertyAttribute as RequiredAttribute,
jObjectForVmProperty);
}
else if (thisVmPropertyAttribute is DisplayAttribute) {
CreateObjectForProperty(thisVmPropertyAttribute as DisplayAttribute,
jObjectForVmProperty);
}
else {
continue; // Put more else if conditions like above if you want other types
}
}
thisProperty.Value = jObjectForVmProperty;
}
o.WriteTo(writer);
}
}
private void CreateObjectForProperty<TAttribute>(TAttribute attribute, JObject jObjectForVmProperty)
where TAttribute : Attribute
{
var jObjectForAttriubte = new JObject();
var max = attribute as TAttribute;
var maxPropeties = typeof(TAttribute).GetProperties();
foreach(var thisProp in maxPropeties) {
try {
jObjectForAttriubte.Add(new JProperty(thisProp.Name, thisProp.GetValue(max)));
}
catch(Exception ex) {
// No need to worry. Fails on complex attribute properties and some other property types. You do not need this.
// If you do, then you need to take care of it.
}
}
jObjectForVmProperty.Add(typeof(TAttribute).Name, jObjectForAttriubte);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter.");
}
public override bool CanRead
{
get { return false; }
}
public override bool CanConvert(Type objectType) {
return _types.Any(t => t == objectType);
}
}
Der Konverter oben ist generisch, so dass es für jede Art zu arbeiten. Im Moment wird es diese Attribute serialisieren: MaxLengthAttribute
, RequiredAttribute
, DisplayAttribute
. Aber andere zu tun ist super einfach: Erstelle einfach eine andere Bedingung, wie ich im Abschnitt continue
kommentiert habe. Der Wert für die Eigenschaft wird in einer Eigenschaft mit der Bezeichnung ActualValue
gespeichert.
Nutzungs
var vm = new CreateProjectViewModel() { Description = "My long description",
Name = "StackOverflow" };
string json = JsonConvert.SerializeObject(vm, Formatting.Indented,
new KeysJsonConverter<CreateProjectViewModel>
(typeof(CreateProjectViewModel)));
Ausgabe
Hier ist der Ausgang, wenn ich Ihre CreateProjectViewModel
verwendet:
{
"Categories": null,
"Locations": null,
"Name": {
"ActualValue": "StackOverflow",
"RequiredAttribute": {
"AllowEmptyStrings": false,
"RequiresValidationContext": false,
"ErrorMessage": "You must provide a unique name for your project.",
"ErrorMessageResourceName": null,
"ErrorMessageResourceType": null
},
"DisplayAttribute": {
"ShortName": null,
"Name": "Project name",
"Description": null,
"Prompt": null,
"GroupName": null,
"ResourceType": null
},
"MaxLengthAttribute": {
"Length": 128,
"RequiresValidationContext": false,
"ErrorMessage": null,
"ErrorMessageResourceName": null,
"ErrorMessageResourceType": null
}
},
"Description": {
"ActualValue": "My long description",
"RequiredAttribute": {
"ErrorMessage": "Give a succinct description of the issues your project is designed to address",
"AllowEmptyStrings": false,
"RequiresValidationContext": false,
"ErrorMessageResourceName": null,
"ErrorMessageResourceType": null
},
"DisplayAttribute": {
"Name": null,
"ShortName": null,
"Description": null,
"Prompt": "E.g Reduce plastic waste and save our oceans!",
"GroupName": null,
"ResourceType": null
}
}
}
Dies ist etwas, das Sie selbst implementieren müssen. Entscheiden Sie zuerst, welche Eigenschaften und Attribute Sie serialisieren möchten und wie der JSON aussehen soll. Verwenden Sie dann die Reflektion, um die Eigenschaften und Attribute zu untersuchen, die Sie interessieren, und generieren Sie Ihr benutzerdefiniertes JSON-Format. – Joe