WCF and ResponseFormat = WebMessageFormat.Json with inherited classes - json

I have run into another issue that apparently deals with inherited classes:
I have for instance this super class.
public class Person
{
public string Firstname { get; set; }
public string Lastname { get; set; }
public string Email { get; set; }
}
And then a sub class:
public class Member : Person
{
public int MembershipId { get; set; }
public string Password { get; set; }
public List<Foo> Foos { get; set; }
}
When I return a Member with the following code, I get nothing useful:
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
public Member GetMember()
{
return new Member
{
Firstname = "Jane",
Lastname = "Doe",
Email = "jane.doe#doe.com",
MembershipId = 10,
Password = "*****",
Foos = new List<Foo> { };
};
}
Classes / objects that are not inherited are serialized and returned in json format without any problems.
Is there anyway to get my Member object returned correctly, please? I have been messing with this issue and my conclusion was that it must have something to do with inherited classes and json.

try this fix
[DataContract]
public class Person
{
[DataMember]
public string Firstname { get; set; }
[DataMember]
public string Lastname { get; set; }
[DataMember]
public string Email { get; set; }
}
[DataContract]
public class Member : Person
{
[DataMember]
public string MembershipId { get; set; }
[DataMember]
public string Password { get; set; }
[DataMember]
public List<Foo> Foos { get; set; }
}

Actually my theory about inherited classes and JSON serialization was flawed.
It works and I do not need the [Datacontrac] and [Datamember] decorators. Something else is wrong. Perhaps my structure is too deep and too lenghty.
I wonder whether JSON has some limits regarding size.

I ended using JSON.net from Newtonsoft. I would recommend to use that instead of wasting time on the native json feature in .net.
http://json.codeplex.com/

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

Web API Json Serialization Exception & Dynamic Entities

I have a web API controller method that is returning an object which is giving the client a 500 internal server error. On the server, the output windows says "Newtonsoft.Json.JsonSerializationException". But I cannot see anything wrong with the class I am returning.. and I am sure this has historically been working. Any help would be greatly appreciated!
EDIT: Is this a problem with the web API not being able to serialize a 'dynamic entity'? The code that generates the class is here:
var id = User.Identity.GetUserId();
var user = db.Users
.Where(u => u.Id == id)
.Include(u => u.Friends)
.FirstOrDefault();
return user;
I am returning the following class;
public class User : IdentityUser
{
public User()
{
this.Friends = new List<UserFriend>();
}
public string PhoneNumber { get; set; }
public string Email { get; set; }
public List<UserFriend> Friends { get; set; }
public bool HasRegistered { get; set; }
public string LoginProvider { get; set; }
}
The 'UserFriend' class looks like this;
public class UserFriend
{
public int UserFriendId { get; set; }
public string Id { get; set; }
public string FriendUserId { get; set; }
public string FriendUserName { get; set; }
public string FriendPhoneNumber { get; set; }
}
Strangely, when I hover over the returned object on the server, the type is: {System.Data.Entity.DynamicProxies.User_7283E76A736B4DD47E89120E932CD5C04B62F84C316961F02CDAE3EEF4786504}. I am not sure what this is.. :-O
I used AutoMapper to create a DTO instead of just returning the User class. The DynamicProxies class is because the query uses lazy loading and it has not got the object yet.
After installing automapper (Install-Package AutoMapper);
Mapper.CreateMap<User, UserDto>();
UserDto dto = Mapper.DynamicMap<UserDto>(user);
Then return the dto.

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.

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?