.Net Core: controlling Json generated by Controller.Json method - json

By default, Controller.Json generates JSON for each public member of a class. How can I change this so that some members are ignored. Please note that I am using .Net Core.
Example:
[HttpGet("/api/episodes")]
public IActionResult GetEpisodes()
{
var episodes = _podcastProvider.Get();
return Json(episodes);
}
Thanks.

You can use [JsonIgnore] attribute that available in Newtonsoft.Json namespace like below:
public class Model
{
public int Id { get; set; }
public string Name { get; set; }
[JsonIgnore]
public int Age { get; set; }
}

How can I change this so that some members are ignored?
Under the covers this uses Newtonsoft.Json. There are two ways you can do this.
Use the JsonIgnore attribute and mark the properties you want omitted.
Have your episodes class define itself as "opt-in", meaning only properties marked with JsonProperty are serialized. [JsonObject(MemberSerialization.OptIn)]
It depends on the number of properties you need omitted versus serialized.
public class Episode
{
public int Id { get; }
[JsonIgnore] public string Name { get; }
[JsonIgnore] public Uri Uri { get; }
[JsonIgnore] public long Length { get; }
}
The above will yield the same JSON as this:
[JsonObject(MemberSerialization.OptIn)]
public class Episode
{
[JsonProperty]
public int Id { get; }
public string Name { get; }
public Uri Uri { get; }
public long Length { get; }
}

Related

C# JSON deserialization returns null

I'm trying to deserialize some statistics in JSON format from valve's API. The code below doesn't throw any exceptions when deserializing, only when trying to use the statistics afterwards. None of the statistics have a value after deserialization. Valve's response looks like this:
"playerstats":{
"steamID":"",
"gameName":"",
"stats":[
{
"name":"deaths",
"value":5062
}, etc etc..
This is my Rust class (Rust being the game I'm getting statistics from.):
public class Rust
{
public int steamID { get; set; }
public string gameName { get; set; }
public Array stats { get; set; }
}
And this is the deserialization code:
Rust getStats = JsonConvert.DeserializeObject<Rust>(str);
foreach (var stat in getStats.stats) //< ----- Exception: Object reference not set to an instance of an object.
{
parsed += stat.ToString();
}
'parsed' is then returned and used to print out all statistics and 'str' is the json response from Valve. I pasted the entire JSON response on pastebin in-case the above data isn't enough: https://pastebin.com/uJZSTF3G
I've tried naming some of the statistics individually in the Rust class instead of using an Array.
I expect the output to show all of the deserialized statistics for example in a console.
As #Bagus Tesa suggested, try something like...
public class Rust
{
public int steamID { get; set; }
public string gameName { get; set; }
public List<RustStat> stats { get; set; }
}
public class RustStat
{
public string name { get; set; }
public string value { get; set; }
}
Edit
I changed the steamID property to string and added the full code below. This compiled for me successfully. Hope this helps!
public class Valve
{
public Rust playerstats { get; set; }
}
public class Rust
{
public string steamID { get; set; }
public string gameName { get; set; }
public List<RustStat> stats { get; set; }
}
public class RustStat
{
public string name { get; set; }
public string value { get; set; }
}
Valve valve = JsonConvert.DeserializeObject<Valve>(str);
foreach (RustStat stat in valve.playerstats.stats)
{
}

Ignoring fields without JsonProperty attribute [duplicate]

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

How to add to a collection in Entity Framework 4.1

I'm trying to add an object to an IList entity but the runtime throws a 'Object reference not set to an instance of an object.' exception.
Here is my model:
public class Discussion
{
[Key]
public int DiscussionId { get; set; }
public string Title { get; set; }
public virtual List<Message> Messages { get; set; }
public virtual List<Tag> Tags { get; set; }
public Guid Guid { get; set; }
public string UrlTitle { get; set; }
}
and here is the problematic line:
newDiscussion.Messages.Add(newMessage);
Apparently newDiscussion.Messages is null. What am I doing wrong?
Mark
You should initialize any collections inside of the class's constructor.
public class Discussion
{
public Discussion()
{
Messages = new List<Message>();
Tags = new List<Tag>();
}
// ...
}

Code First Object not properly instantiating

I have a class department inheriting from activeentity
public class ActiveEntity : Entity, IActive
{
public ActiveEntity()
{
IsActive = true;
}
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public Guid Id { get; set; }
public bool IsActive { get; set; }
[Timestamp, ScaffoldColumn(false), DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.Computed)]
public Byte[] Timestamp { get; set; }
[ScaffoldColumn(false)]
public string CreationUserId { get; set; }
[ScaffoldColumn(false)]
public string LastModifiedUserId { get; set; }
}
public class Department:ActiveEntity
{
public Department()
{
this.Address = new DepartmentAddress();
}
[StringLength(9),MinLength(9),MaxLength(9)]
public string Name { get; set; }
public Guid ManagerId { get; set; }
[UIHint("AjaxDropdown")]
public User Manager { get; set; }
public Guid? AddressId { get; set; }
public DepartmentAddress Address { get; set; }
public ICollection<OverheadRate> OverheadRates { get; set; }
}
I am just using annotations no Fluent API. The data saves to the data Sql Server 2008 just fine however the address object never gets instantiated, even though I have the context use the include
return c.Set<Department>().Include(d => d.Address).Include(d => d.Manager).Where(predicate);
The data is returned I run sql profiler and then run the query it returns the correct data.
Any thoughts or suggestions?
Remove instantiating the address (this.Address = new DepartmentAddress();) in the Department constructor. Instantiating navigation references in the default constructor is evil and has nasty side effects like these:
What would cause the Entity Framework to save an unloaded (but lazy loadable) reference over existing data?
EF 4.1 Code First: Why is EF not setting this navigation property?

EF Code First Custom Collections

When creating code first collections can you implement a custom class that implements ICollection. The code below is conceptual not actual
public class Product
{
public int ProductId { get; set; }
public string Name { get; set; }
public Category Category { get; set; }
}
public class Category
{
public int CategoryId { get; set; }
public string Name { get; set; }
//Want to Avoid This
public ICollection<Product> Products { get; set; }
//Use his instead of above
public ProductList ProductsInCategory {get;set;}
}
public class ProductsList :ICollection<Product>
{
public int DiscontinuedProductsCount
{
return internalList.Count();
}
//Icollection Methods Excluded
}
EF can indeed support any collection which inherits from ICollection. We create a deletable collection to support auto deletions and also create collections for child objects to keep the size of our main object smaller.