Part of the json read from Mailchimp looks like this.
"interests": {
"5e0344ae18": true,
"545e5bdb01": true,
"33aa542ea0": true,
"f51a5f9716": true,
"31109a4d58": true,
"bf5f946fd4": true,
"563320981e": false
}
So the properties used for deserialize should be this I believe.
public Interests interests { get; set; }
public class Interests
{
public bool 5e0344ae18 { get; set; }
public bool 545e5bdb01 { get; set; }
public bool 33aa542ea0 { get; set; }
public bool f51a5f9716 { get; set; }
public bool 31109a4d58 { get; set; }
public bool bf5f946fd4 { get; set; }
public bool 563320981e { get; set; }
}
However the property names consisting of numbers and letters aren't valid with compile error for each like 'Invalid token '5e0344' in class, struct, or interface member declaration'.
How can the property name match the name in the json data?
While I don't believe you will be able to use property names beginning with numbers, you could possibly prefix these with a character or string and do some manual parsing.
Assuming you're working with C#, http://www.newtonsoft.com/json/help/html/t_newtonsoft_json_linq_jobject.htm may allow you to handle the JSON response and parse properties without using the automatic deserialize I'm guessing you're currently using.
Here's another post I found describing a similar problem and some potential solutions: Parse jsonObject when field names are unknowm
You can use Data Annotations to map your JSON properties to your Model properties
This works both ways (incoming/outgoing):
using Newtonsoft.Json; // or Json.Net (built-in)
[JsonProperty(PropertyName = "5e0344ae18")]
public bool YourPropertyName { get; set; }
Related
I am sending a Json Array from the client web application to asp.net webapi.
For example,
{
"SurveyId":3423,
"CreatorId":4235,
"GlobalAppId":34,
"AssociateList":[
{"AssociateId":4234},
{"AssociateId":43},
{"AssociateId":23423},
{"AssociateId":432}
],
"IsModelDirty":false,
"SaveMode":null
}
Here Associate List is a JSON Array,
Usually it will automatically serialize to a List<> object.
Using the below code ,i am posting the response to the WebApi
public IEnumerable<Associate> Post(ResponseStatus responseStatus)
{
return this.responsestatusrepository.ResponseStatusCheck(responseStatus);
}
The ResponseStatus class is shown below.
public class ResponseStatus : AppBaseModel
{
public int SurveyId { get; set; }
public int CreatorId { get; set; }
public int GlobalAppId { get; set; }
public List<Associate> AssociateList { get; set; }
}
I have changed the List<> to Collection<> as a part of my code analysis correction.
ie, public Collection<Associate> AssociateList { get; set; }
But it is always getting a null value when we are using collection instead of List. Is there any specific reason for this?
Ok, I think I will have to answer this in an indirect way.
What you are passing on to the server is an array of objects (in JSON format), but once you start processing this in C# the array of objects is now treated as a single c# object. Inside this object, your model expects one of the fields to be a Collection of Associate.
Right, when I work with JSON data similar to whats mentioned in this case - I prefer to use Newtonsofts' JOject.
So here is how I made the C# object with the JSON data you provided:
Used your model:
public class ResponseStatus
{
public int SurveyId { get; set; }
public int CreatorId { get; set; }
public int GlobalAppId { get; set; }
public Collection<Associate> AssociateList { get; set; }
}
public class Associate
{
public int AssociateId { get; set; }
}
Made a routine which takes string (the JSON data), and returns an object of type ResponseStatus:
using System;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
---------------------------------------------------------------------
public static ResponseStatus GetResponseStatusObject(string jsonData)
{
JObject jObject = JObject.Parse(jsonData);
return jObject.ToObject<ResponseStatus>();
}
Now when I call this method and pass on the exact same JSON data which you provided, I get this:
This might not directly solve your problem, but hopefully guide you in the right direction in understanding array/object serialization when working with JavaScript/C#.
Best of luck!
I have an object which I am de-serializing using ToJson<>() method from ServiceStack.Text namespace.
How to omit all the GET only propeties during serialization? Is there any attribute like [Ignore] or something that I can decorate my properties with, so that they can be omitted?
Thanks
ServiceStack's Text serializers follows .NET's DataContract serializer behavior, which means you can ignore data members by using the opt-out [IgnoreDataMember] attribute
public class Poco
{
public int Id { get; set; }
public string Name { get; set; }
[IgnoreDataMember]
public string IsIgnored { get; set; }
}
An opt-in alternative is to decorate every property you want serialized with [DataMember]. The remaining properties aren't serialized, e.g:
[DataContract]
public class Poco
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string Name { get; set; }
public string IsIgnored { get; set; }
}
Finally there's also a non-intrusive option that doesn't require attributes, e.g:
JsConfig<Poco>.ExcludePropertyNames = new [] { "IsIgnored" };
Dynamically specifying properties that should be serialized
ServiceStack's Serializers also supports dynamically controlling serialization by providing conventionally named ShouldSerialize({PropertyName}) methods to indicate whether a property should be serialized or not, e.g:
public class Poco
{
public int Id { get; set; }
public string Name { get; set; }
public string IsIgnored { get; set; }
public bool? ShouldSerialize(string fieldName)
{
return fieldName == "IsIgnored";
}
}
More examples in ConditionalSerializationTests.cs
For nullable members, you also have the ability to set it to null before serializing.
This is particularly useful if you want to create a single view/api model that is re-used for several API calls. The service can touch it up before setting it on the response object.
Example:
public SignInPostResponse Post(SignInPost request)
{
UserAuthentication auth = _userService.SignIn(request.Domain, true, request.Username, request.Password);
// Map domain model ojbect to API model object. These classes are used with several API calls.
var webAuth = Map<WebUserAuthentication>(auth);
// Exmaple: Clear a property that I don't want to return for this API call... for whatever reason.
webAuth.AuthenticationType = null;
var response = new SignInPostResponse { Results = webAuth };
return response;
}
I do wish there was a way to dynamically control the serialization of all members (including non-nullable) on a per endpoint fashion.
When I'm converting Json objects to c#, I got an issue In which my Json has fields with $ symbol(ex: $t).But c# doesn't accept fields with special characters. If i try to replace $ with any other letters in my c# code, I'm unable to get data from 3rd party because of the change in naming.
How can I solve this issue?
Json string:
"author": [(1)
{
"name": {
"$t": "theabctv"
},-
"uri": {
$t": "http://gdata.abc.com/feeds/api/users/theabctv"
},-
"yt$userId": {
"$t": "tCUABCCT7wYG1PMCpw"
}-
}-
],-
C# code:-
public class Author2
{
public Name2 name { get; set; }
public Uri2 uri { get; set; }
public YtUserId __invalid_name__yt$userId { get; set; }
}
public class Name2
{
public string __invalid_name__$t { get; set; }
}
public class Uri2
{
public string __invalid_name__$t { get; set; }
}
public class YtUserId
{
public string __invalid_name__$t { get; set; }
}
There is no way to declare property names with symbols in NET framework, meaning that you cant have isomorphism between the JSON objects and the C# objects without parsing the JSON data. You could replace all $ symbol with any given string (carefully chosen), manage the data in the code behind and when you need to send JSON data of the object apply the inverse replacement.
I am trying to filter Kendo UI grid server side filter. The developer tools show this in query string
/Home/GetUsmMessage?{"filter":{"logic":"and","filters" [{"field":"MessageId","operator":"eq","value":1}]},"group":[]} GET 200 application/json
I created a object structure so that I read the structure to object
public ActionResult GetUsmMessage(FilterContainer filter)
{
//Code to read the filter container
return Json(jsonData, JsonRequestBehavior.AllowGet);
}
Object structure for filter container:
public class FilterContainer
{
public List<FilterDescription> filters { get; set; }
public string logic { get; set; }
}
public class FilterDescription
{
public string #operator { get; set; }
public string field { get; set; }
public string value { get; set; }
public List<FilterDescription> filters { get; set; }
public string logic { get; set; }
}
It still gives me a null object when I debug controller function. Please help
Got the answer...I forgot to add type of request as Http post ....
In case of WebApi controller, you could use [FromUri] attributes and GET verb:
public HttpResponseMessage Get(
[FromUri]IEnumerable<SortParameter> sort,
[FromUri]FilterContainer filter,
int take = 10, int skip = 0)
Is it possible to return nested classes in json with OpenRasta?
I'm using EF4.1 with code first (which in theory shouldn't make a difference, as they are just POCO classes).
Here is an example:
public class AppUser
{
[Key]
public int AppUserId { get; set; }
public string WinLogin { get; set; }
public string ScreenName { get; set; }
public string AgencyId { get; set; }
public virtual ICollection<UserAppVersion> UserAppVersion { get; set; }
}
public class UserAppVersion
{
[Key]
public int UaVersionId { get; set; }
public int AppUserId { get; set; }
public int AppVersionId { get; set; }
public DateTime DateCreated { get; set; }
public DateTime DateUpdated { get; set; }
public virtual AppUser User { get; set; }
public virtual AppVersion Version { get; set; }
}
I try and return an AppUser record in json using this:
ResourceSpace.Has.ResourcesOfType<AppUser>()
.AtUri("/user").HandledBy<UserHandler>().AsJsonDataContract();
But I get an error:
System.Runtime.Serialization.SerializationException: Type 'System.Data.Entity.DynamicProxies.UserAppVersion_FD8D86F0A3AE39A0C370918637C1A90AD8D3ACA3E149677EA82C0A8D10ED0F8D' with data contract name 'UserAppVersion_FD8D86F0A3AE39A0C370918637C1A90AD8D3ACA3E149677EA82C0A8D10ED0F8D:http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.
Unfortunately I don't know how to resolve this. Any suggestions?
That's a data contract issue, not an openrast one.
The DataContract serialzier is seeing a dynamic proxy probably generated by EF code first, and when seeing that cannot render the object.
I'd recommend either swapping for another serialziation codec, or disabling transparent lazy loading, or alternatively marking your property as an ignore for serialziation and have another property typed to a List so the serializer can function.
See DataContractSerializer Error using Entity Framework 4.0 with WCF 4.0