Ignoring fields without JsonProperty attribute [duplicate] - json

The JsonIgnore attribute can be used to ignore certain properties in serialization. I was wondering if it is possible to do the opposite of that? So a JsonSerializer would ignore every property EXCEPT when there is a special attribute on it?

Yes there is. When you mark your class with [JsonObjectAttribute] and pass the MemberSerialization.OptIn parameter, member serialization is opt-in. Then mark your members with [JsonProperty] to include them for serialization.
[JsonObject(MemberSerialization.OptIn)]
public class Person
{
[JsonProperty]
public string Name { get; set; }
// not serialized because mode is opt-in
public string Department { get; set; }
}

An alternative to MemberSerialization.OptIn is using DataContract/DataMember attributes:
[DataContract]
public class Computer
{
// included in JSON
[DataMember]
public string Name { get; set; }
[DataMember]
public decimal SalePrice { get; set; }
// ignored
public string Manufacture { get; set; }
public int StockCount { get; set; }
public decimal WholeSalePrice { get; set; }
public DateTime NextShipmentDate { get; set; }
}
Source: http://james.newtonking.com/archive/2009/10/23/efficient-json-with-json-net-reducing-serialized-json-size

Related

NewtonSoft.Json is returning null for all

I am using Microsoft.aspnetcore.mvc.newtonsoftjson(5.0.2) for JSON, I opted for this instead of System.Text.Json, because in latter one I could not find an option to ignore the loop.
When I try to de-serialize to an Object, it returns null for all properties...
[DataContract]
public class UserDefinition
{
public UserDefinition();
public string Id { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public string EmailId { get; set; }
public string Token { get; set; }
public string RefreshToken { get; set; }
public List<string> AuthKey { get; set; }
public IList<SiteDefinition> AuthBranches { get; set; }
}
Data that needs to be Deserialize
Code used for deserialization...
ud = JsonConvert.DeserializeObject<UserDefinition>(erpResponse);
result
The reason is because of the attribute you've applied to your class:
[DataContract]
When this is present, Json.net will only consider properties that are attributed with [DataMember]. Since you didn't add this attribute to any of the properties, they're all ignored.
You have two solutions:
Remove [DataContract] from your class
Add [DataMember] to all relevant properties

Parsing JSON in C# 4.0

Can anyone help me to parse this JSON into an object IN C# 4.0. I have spent the last two days trying.
I have JSON.NET and several other peoples suggestions to no avail.
I thought it would be best just to give the JSON sample and to ask for your suggestions.
{
"message-count":"1",
"messages":[
{"to":"441234567890",
"messageprice":"0.02900000",
"status":"0",
"messageid":"030000001DFE2CB1",
"remainingbalance":"1.56500000",
"network":"23433"}
]
}
Many thanks,
Adrian
p.s Their is some nice code here, if you want to use github. https://github.com/lukesampson/HastyAPI.Nexmo
I will cheat and create C# classes quickly using this tool: http://json2csharp.com/ (or just discovered http://jsonclassgenerator.codeplex.com/)
Then I change C# classes to my liking
public class MessagesJSON
{
public int MessageCount { get; set; }
public List<Message> Messages { get; set; }
}
public class Message
{
public string To { get; set; }
public double MessagePrice { get; set; }
public int Status { get; set; }
public string MessageId { get; set; }
public double RemainingBalance { get; set; }
public string Network { get; set; }
}
MessagesJSON is just a name I made that represents the JSON object that you are passing to C#.
I pass the JSON string from the client, e.g.
{\"MessageCount\":1,\"Messages\":[{\"To\":\"441234567890\",\"MessagePrice\":0.029,\"Status\":0,\"MessageId\":\"030000001DFE2CB1\",\"RemainingBalance\":1.565,\"Network\":\"23433\"}]
Then I can use JSON.NET to convert JSON to C# objects:
public void YourMethod(MessagesJSON json) {
var result = JsonConvert.DeserializeObject<MessagesJSON>(json);
}
Here's the result:
Watch out for capitalisation.
If you want to use lower-case JSON keys only, change the C# classes to lower-case, e.g. public double messageprice { get; set; }
C# classes:
public class MessagesJSON
{
public int message_count { get; set; }
public List<Message> messages { get; set; }
}
public class Message
{
public string to { get; set; }
public string messageprice { get; set; }
public string status { get; set; }
public string messageid { get; set; }
public string remainingbalance { get; set; }
public string network { get; set; }
}
This is as close to your JSON as you want:
{\"message_count\":1,\"messages\":[{\"to\":\"441234567890\",\"messageprice\":\"0.02900000\",\"status\":\"0\",\"messageid\":\"030000001DFE2CB1\",\"remainingbalance\":\"1.56500000\",\"network\":\"23433\"}]}
or use one of these solutions if you really like CamelCasing:
CamelCase only if PropertyName not explicitly set in Json.Net?
JObject & CamelCase conversion with JSON.Net
I myself prefer attributes
public class Message
{
[JsonProperty("to")]
public string To { get; set; }
[JsonProperty("messageprice")]
public string MessagePrice { get; set; }
[JsonProperty("status")]
public string Status { get; set; }
[JsonProperty("messageid")]
public string MessageId { get; set; }
[JsonProperty("remainingbalance")]
public string RemainingBalance { get; set; }
[JsonProperty("network")]
public string Network { get; set; }
}
Pass your string:
"{\"message_count\":1,\"messages\":[{\"to\":\"441234567890\",\"messageprice\":\"0.02900000\",\"status\":\"0\",\"messageid\":\"030000001DFE2CB1\",\"remainingbalance\":\"1.56500000\",\"network\":\"23433\"}]}"
but get the pretty C# property names:
Create objects with the same structure as the json and call.
JsonConvert.DeserializeObject<Entity>(json);
Edit. You have to use JSON.NET if u wanna do it this way.

Omitting null/default values in wcf rest template 40

I have a web service that uses the WCF REST Template 40. The way my data is set up, there are no [DataContract] or [DataMember] attributes on anything, it is just the class and its public properties. Example:
public class Permission : ServiceClass
{
public int PermissionID { get; set; }
public string PermissionName { get; set; }
public string PermissionCode { get; set; }
public string PermissionDescription { get; set; }
public bool IsActive { get; set; }
public DateTime? StartDate { get; set; }
public DateTime? EndDate { get; set; }
public int SystemID { get; set; }
}
This works fine except that if a property is null, e.g the two DateTime objects, the json still contains those values. I would like for them to be omitted. I have tried to add the [DataMember(EmitDefaultValue=false)] and [DataMember(IsRequired=true)] (i'm not using the default serializer when reading in, so I don't think I need that anyway) and it doesn't seem to work. Has anyone had any experience with this and know some kind of workaround?
[DataMember] attributes are only enforced if the class is also decorated with [DataContract]. You can do that, but once you go to the data contract route, then the serialization becomes an "opt-in" model: you'll need to declare the other members with [DataMember] as well:
[DataContract]
public class Permission : ServiceClass
{
[DataMember]
public int PermissionID { get; set; }
[DataMember]
public string PermissionName { get; set; }
[DataMember]
public string PermissionCode { get; set; }
[DataMember]
public string PermissionDescription { get; set; }
[DataMember]
public bool IsActive { get; set; }
[DataMember(EmitDefaultValue = false)]
public DateTime? StartDate { get; set; }
[DataMember(EmitDefaultValue = false)]
public DateTime? EndDate { get; set; }
[DataMember]
public int SystemID { get; set; }
}
Also, since this contract is now part of the data contract model, your base type (ServiceClass) will likely have to be changed to use the data contract as well.

what is dataAnnotation attribute use to make column have single character

what is DataAnnotation attribute i can use to make gander column only have one character in my table
public class Student
{
public int ID { get; set; }
[Required, MaxLength(50)]
public string Name { get; set; }
[DataType(DataType.Date)]
public DateTime Birthday { get; set; }
public char Gander { get; set; }
}
Use the Column attribute.
public class Student
{
public int ID { get; set; }
[Required, MaxLength(50)]
public string Name { get; set; }
[DataType(DataType.Date)]
public DateTime Birthday { get; set; }
[Column(TypeName = "NVARCHAR(1)")]
public char Gander { get; set; }
}
This should work:
[MaxLength(1)]
public string Gender { get; set; }
The problem is that char is not supported type in mapping and without change in EF core to support the type directly or introducing some simple type mapping or mapped conversions you are not able to map such property.

How to make ICollection<Child Entities> Required. How

Here is my Master Entity who will contains a list of Language
public partial class WebSite
{
public WebSite()
{
this.WebSiteLanguages = new HashSet<WebSiteLanguage>();
}
public int Id { get; set; }
public Nullable<int> WLUserID { get; set; }
public string DomainName { get; set; }
public Nullable<bool> IsActive { get; set; }
//[Required]
public virtual ICollection<WebSiteLanguage> WebSiteLanguages { get; set; }
}
My WebSiteLanguage Child class is
public partial class WebSiteLanguage
{
public int Id { get; set; }
public string LanguageName { get; set; }
public Nullable<int> WebSiteID { get; set; }
public bool IsDefault { get; set; }
public virtual WebSite WebSite { get; set; }
}
In my View, I can Add many language as I want within an ajax call.
My Question is :
Is it possible to make the
public virtual ICollection WebSiteLanguages { get;
set; }
Required. The Website Entity is not valid if there is no WebSiteLanguage created.
Thanks a lot.
As per post http://blogs.msdn.com/b/adonet/archive/2011/05/27/ef-4-1-validation.aspx navigation properties are excluded from facet validation "as you could set the associated FK value and the navigation property would be set on SaveChanges()". To validate that a navigation property is not null you can:
create a custom attribute that validates it (be it on the type or on the property)
implement IValidatableObject interface that does the above
override DbContext.ValidateEntity protected method so that it validates that the property is not null and if this is the case calls base.ValidateEntity() to validate other properties (see this for more details: http://blogs.msdn.com/b/adonet/archive/2010/12/15/ef-feature-ctp5-validation.aspx)
The 3rd solution seems to be the cleanest.