[英]How can I serialise a ViewModel in to a JSON object
我有一個視圖模型。 該視圖模型具有實現。 實現是ac#類。 c#類具有屬性和屬性。 我想將屬性和屬性序列化為JSON對象。 我不需要任何數據,這是我在JSON對象中所需的驗證詳細信息。 以下是我的視圖模型:
public class CreateProjectViewModel
{
public SelectList Categories;
public SelectList Locations;
public CreateProjectViewModel() { }
public CreateProjectViewModel(SelectList categories, SelectList locations)
{
this.Categories = categories;
this.Locations = locations;
}
[Required(ErrorMessage = "You must provide a unique name for your project.")]
[Display(Name = "Project name")]
[MaxLength(128)]
public string Name { get; set; }
[Required(ErrorMessage = "Give a succinct description of the issues your project is designed to address")]
[Display(Prompt = "E.g Reduce plastic waste and save our oceans!")]
public string Description { get; set; }
}
使用NewtonSoft :
var vm = new CreateProjectViewModel();
string serialized = JsonConvert.SerializeObject(vm);
編輯
您能否擴展答案以包括視圖模型注釋的序列化,例如[Display(Name =“ Project name”)]和[MaxLength(128)]?
換句話說:“我可以序列化應用於屬性的屬性嗎?”
大多數庫中沒有開箱即用的功能。 為此,我們將需要創建自己的自定義轉換器。 幸運的是,NewtonSoft使我們能夠編寫自己的轉換器。 這不是一件小事,但可行。 這是一個自定義轉換器,它將對屬性進行序列化。
定制轉換器
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 );
}
}
上面的轉換器是通用的,因此它適用於任何類型。 現在,它將序列化以下屬性: MaxLengthAttribute
, RequiredAttribute
和DisplayAttribute
。 但是要做其他事情是非常容易的:只需創建一個條件,就像我在continue
部分中提到的那樣。
該屬性的值存儲在名為ActualValue
的屬性中。
用法
var vm = new CreateProjectViewModel() { Description = "My long description",
Name = "StackOverflow" };
string json = JsonConvert.SerializeObject( vm, Formatting.Indented,
new KeysJsonConverter<CreateProjectViewModel>
( typeof( CreateProjectViewModel ) ) );
輸出量
這是當我使用CreateProjectViewModel
時的輸出:
{
"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
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.