Joshua Wieczorek
Joshua Wieczorek

Reputation: 735

C# .Net Newtonsoft JSON Not Serialize Property But Read It in Json Post

Using .Net and Newtonsoft Json, how can I hide a model property on serialization, however, be able to populate that property and utilize the value passed.

E.g.

[JsonIgnore]
public Int16 Value { get; set; }

This hides the property on output, however, I cannot set the value on model POST. How can I hide the property on output but allow the property to be set on a POST or PUT request?

POST Example:

{
    "Name": "King James Version",
    "Abbreviation" : "kjv",
    "Publisher": "Public Domain",
    "Copyright": "This is the copyright",
    "Notes": "This is the notes.",
    "TextDirection" : "LTR"
}

PUT example:

{
    "ID" : 1,
    "Name": "King James Version",
    "Abbreviation" : "kjv",
    "Publisher": "Public Domain",
    "Copyright": "This is the copyright",
    "Notes": "This is the notes.",
    "TextDirection" : "LTR"
}

Business Logic:

  1. ID should not be passed in POST request and will be ignored if passed.
  2. Abbreviation is required for POST request and will be validated against database using custom Validation Filter attribute.
  3. Abbreviation cannot be passed on PUT request because that field/property cannot be updated.
  4. ID must be passed in the PUT request to identity in the custom validator that it is a PUT request and not a POST request.

Model:

namespace Library.Models.Bible
{
    public class BibleModel : IPopulatable<BibleModel, DataTable>, IPopulatable<BibleModel, DataRow>
    {
        public Int32? ID { get; set; }
    [MinLength(4, ErrorMessage = "Bible name must be between 4-100 characters")]
    [MaxLength(100, ErrorMessage = "Bible name must be between 4-100 characters")]
    public String Name { get; set; }

    [MinLength(3, ErrorMessage = "Bible abbreviation must be between 3-9 characters")]
    [MaxLength(9, ErrorMessage = "Bible abbreviation must be between 3-9 characters")]
    [ValidateBibleAbbreviationExists]
    public String Abbreviation { get; set; }

    [MaxLength(250, ErrorMessage = "Publisher may not exceed 250 characters")]
    public String Publisher { get; set; }

    [MaxLength(3000, ErrorMessage = "Copyright may not exceed 3000 characters")]
    public String Copyright { get; set; }

    [MaxLength(3000, ErrorMessage = "Notes may not exceed 3000 characters")]
    public String Notes { get; set; }

    [EnumDataType(typeof(Enums.eTxtDir), ErrorMessage = "Text direction does not exist. Allowed values: LTR, RTL")]
    public String TextDirection { get; set; }

    [JsonIgnore]
    public Int16 Active { get; set; } = 1;

    public BibleModel Populate(DataTable dT)
    {
        if (dT != null && dT.Rows.Count > 0)
            return Populate(dT.Rows[0]);
        return null;
    }

    public BibleModel Populate(DataRow ro)
    {
        if(ro != null)
        {
            this.ID = Convert.ToInt32(ro["Bible_ID"]);
            this.Name = ro["Name"].ToString();
            this.Abbreviation = ro["Abbr"].ToString();
            this.Publisher = ro["Publisher"].ToString();
            this.Copyright = ro["Copyright"].ToString();
            this.Notes = ro["Notes"].ToString();
            this.TextDirection = ro["TxtDir"].ToString();
            return this;
        }
        return null;
    }        
}

Upvotes: 2

Views: 535

Answers (1)

derpirscher
derpirscher

Reputation: 17397

There are several possibilities (https://www.newtonsoft.com/json/help/html/ConditionalProperties.htm)

1) Write a Custom Contract Resolver

class MyContractResolver: DefaultContractResolver 
{


  protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
        {
            JsonProperty property = base.CreateProperty(member, memberSerialization);
            property.ShouldSerialize = String.Compare(property.PropertyName, "Value") != 0;
            return property;
        }
}

2) Add a ShouldSerialize... method to your class

 class MyClass {

     public Int16 Value {get;set;}
     public bool ShouldSerializeValue() {return false;}
 }

Upvotes: 1

Related Questions