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
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
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.
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.
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.
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?