I'm storing customer position data using the following class:
public class CustomerData
{
public string CustomerName { get; set; }
public int CustomerNumber { get; set; }
public string CustomerAddress { get; set; }
public string CustomerCity { get; set; }
public string CustomerZip { get; set; }
public string CustomerState { get; set; }
public Geopoint CustomerGeopoint { get; set; }
}
inside a JSON file...and retrieving the data using a service like so:
public static async Task<ObservableCollection<CustomerData>> GetCustomerData()
{
var folder = ApplicationData.Current.LocalFolder;
var dataFile = await folder.TryGetItemAsync("CustomerData.json") as IStorageFile;
var stringResult = await FileIO.ReadTextAsync(dataFile);
ObservableCollection<CustomerData> CustomersRetrievedData = JsonConvert.DeserializeObject<ObservableCollection<CustomerData>>(stringResult, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All
});
Customers = CustomersRetrievedData;
return await Task.FromResult(CustomersRetrievedData);
}
as well as saving the data like this:
public static async void SaveCustomerData()
{
var folder = ApplicationData.Current.LocalFolder;
StorageFile newFile = await folder.CreateFileAsync("CustomerData.json", CreationCollisionOption.ReplaceExisting);
var stringData = JsonConvert.SerializeObject(Customers);
await FileIO.WriteTextAsync(newFile, stringData);
}
My problem is, after all the geopoint data is in there, when I try to read the data by deserializing it in the GetCustomerData() method, I get the following error:
Unable to find a constructor to use for type Windows.Devices.Geolocation.Geopoint. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute
I don't understand how to fix this, and I can't find anything on the newtonsoft documentation, anyone know how this is done?
Looking at the documentation for Geopoint we can see that it has 3 .ctors, none of which are parameterless. JSON.NET requires a parameterless .ctor for deserialization, as you can see from the error message you get.
So one thing you can do is change your class to include a property with a type (that you make) that mirrors the Geopoint structure (includes all its properties), but also includes a parameterless .ctor. You could even implement IGeoshape so that it could be used anywhere an IGeoshape was required.
Something along the lines of:
public class GeopointProxy : IGeoshape {
public GeopointProxy() { }
private AltitudeReferenceSystem _altitudeReferenceSystem;
// This is part of the IGeoshape interface, you can't change it's signature, and it's readonly. Fun.
[JsonIgnore]
public AltitudeReferenceSystem AltitudeReferenceSystem { get { return _altitudeReferenceSystem; } }
public AltitudeReferenceSystem SettableAltitudeReferenceSystem {
get {
return AltitudeReferenceSystem;
}
set {
_altitudeReferenceSystem = value;
}
}
// rinse and repeat as appropriate for the other interface members and class properties
// Then include a conversion function, or get fancy and add type conversion operators:
public Geopoint ToGeopoint() {
return new Geopoint(Position, AltitudeReferenceSystem, SpatialReferenceId);
}
}
Related
I would like to do something like below where I should be able to store and retrieve data though class properties or method,
//set the value
var someObject = {... };
var newMessage = new Message(JsonConvert.SerializeObject(someObject))
{
ContentType = "application/json"
};
//get the value
Message message;
var x = message.GetBody<string>()
I tried creating class like below, but have to supply body for method. How to design this class?
public class Message
{
public Message(object serializableObject);
public string SessionId { get; set; }
public string ContentType { get; set; }
public T GetBody<T>();
}
I think I understand your question, but you've missed out on the constructor
new Message(JsonConvert.SerializeObject(someObject)) //<-- string is passed
I think you have misinterpreted the JsonConvert.SerializeObject(someObject) statement, it will return a string not an object. Whereas you have used the incorrect type as an argument for your constructor.
public Message(object serializableObject); // should be a string
To correct your class, you need to design it the following way...
public class Message
{
private readonly string _json;
public Message(string json)
{
_json = json;
}
public string GetBody() // not generic, but you get the idea now.
{
return json;
}
}
I have an API call as listed below:
JsonValue result = api.GET("/chart/" + problemList.PatientMRN.ToString() + "/problems", problemInfo);
string resultString = result.ToString();
Note: I am referring to System.Json.JsonValue
Alternative Approach (using JavaScriptSerializer )
Rootobject_Labresult objGResponse = new JavaScriptSerializer().Deserialize<Rootobject_Labresult>(resultString);
From the string in Json, I created corresponding classes (using Paste Special in Visual Studio edit menu).
public class Rootobject_Labresult
{
public Labresult[] labresults { get; set; }
public int totalcount { get; set; }
}
public class Labresult
{
public string createddate { get; set; }
public DateTime createddatetime { get; set; }
public string departmentid { get; set; }
public string description { get; set; }
}
But when I create an array, I am getting following error.
Labresult[] labresults = result[0];
////Error: cannot implicitly convert type System.Json.JsonValue to Labresult
What is the best way to convert JsonValue to the domain object (Labresult) ?
This could have also been done simpler using Json.Net
JsonConvert.DeserializeObject<T> Method (String)
//...code removed for brevity
string json = result.ToString();
Rootobject_Labresult rootObject = JsonConvert.DeserializeObject<Rootobject_Labresult>(json);
Labresult[] labresults = rootObject.labresults;
From there you should be able to extract the desired domain values.
And as simple as that was you could have created an extension
public static class JsonValueExtensions {
public static T ToObject<T>(this JsonValue value) {
return JsonConvert.DeserializeObject<T>(value.ToString());
}
}
which reduces the original code even further
//...code removed for brevity
Rootobject_Labresult rootObject = result.ToObject<Rootobject_Labresult>();
Labresult[] labresults = rootObject.labresults;
The assumption being that result in the above snippet example is an instance of JsonValue
I believe the best way to convert from string/System.Json.JsonValue to DotNet Object using Json.NET
All you need is the Newtonsoft.Json.Linq namespace and you can do all the conversation with single line of code
using Newtonsoft.Json.Linq;
var result = JToken.Parse(jsonVal.ToString()).ToObject<Rootobject_Labresult>();
I have created a example here.
https://dotnetfiddle.net/N2VfKl
Here is another example for object conversation using Json.NET
https://dotnetfiddle.net/rAkx7m
Json.Net also allow you to work with the json object without declare the class.
https://dotnetfiddle.net/ZIA8BV
I know this has been answered a lot of places on stack and the best possible answer is Here. I've tried it and a lot of other answers too. I have a library that returns me a collection of an Interface (IMasterAutoSuggestOutlet)
public interface IMasterAutoSuggestOutlet : IBaseAutoSuggestOutlet
{
IAddressData AddressData { get; }
IPlaceActivity PlaceActivity { get; }
string ELoc { get; }
Geopoint ExactLocation { get; }
Geopoint EntranceLocation { get; }
LocationType TypeOfLocation { get; }
}
Now, I want to transfer this interface data from one page to another in my application. Since Interfaces cannot be serialized, I created a concrete class that implements this interface:
My Concrete Class,
public class MasterAutoSuggestModel : IMasterAutoSuggestOutlet
{
public IAddressData AddressData { get; set; }
public IPlaceActivity PlaceActivity { get; set; }
public string ELoc { get; set; }
public Geopoint ExactLocation { get; set; }
public Geopoint EntranceLocation { get; set; }
public LocationType TypeOfLocation { get; set; }
}
What I want to do is, convert the ICollection to ICollection. My code below shows my implementation of such an operation:
var collection = mainPageViewModel?.SearchPageVM?.searchManager?.AutoSuggestResponse;
var ob = collection.First();
if (ob is IMasterAutoSuggestOutlet)
{
var ToBeTransfered = collection.OfType<MasterAutoSuggestModel>(); //Simply returns the collection with a count 0
var serializedData = JsonConvert.SerializeObject(ToBeTransfered);
ScenarioFrame.Navigate(typeof(MasterSearchResultPage), serializedData);
}
The issue is with var ToBeTransfered = col.OfType<MasterAutoSuggestModel>(); it returns me a collection with count 0 even though the collection has 10 items in it.
Can someone please tell me where am I going wrong? Please note I need to use this Converted collection to serialize and send as the navigation parameter to send to the next page
The ofType method filters the connection by the type specified. If you are retrieving the objects from some other library, they would not be that specific type.
https://msdn.microsoft.com/en-us/library/bb360913(v=vs.110).aspx
What you would probably want to do is convert the items retrieved from the library into your dto for serialisation. You can use something like automapper for the conversion
if (ob is IMasterAutoSuggestOutlet) {
var transferObject = new MasterAutoSuggestModel(){
//Set Properties
}
// var ToBeTransfered = collection.OfType<MasterAutoSuggestModel>(); //Simply returns the collection with a count 0
var serializedData = JsonConvert.SerializeObject(transferObject);
ScenarioFrame.Navigate(typeof(MasterSearchResultPage), serializedData); }
By default, objects are passed by reference to methods. I know a way to make a clone of the object and pass it to the method like a deep copy.
Here's one implementation for above approach (serialize it and deserialize to a new object):
private static APIRateLimit DeepCopy(APIRateLimit source)
{
var DeserializeSettings = new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Replace };
return JsonConvert.DeserializeObject<APIRateLimit>(JsonConvert.SerializeObject(source), DeserializeSettings);
}
But, Is it the only way to do this? Is there any better approach for a scenario like this?
Note: I'm specific about the objects which contain primitives only without any readonly/constant modifiers.
Object is like this:
public class APIRateLimit
{
public int MaxAllowed { get; set; }
public int APICallDurationInSec { get; set; }
public string APIRateLimitInfo { get; set; }
public string ConnectionType { get; set; }
}
I am using RESTSharp to receive and deserialize result from an API call. Response is JSON. I've created a class for the repsonse that looks like this:
public class JsonResponseClass
{
public class Selector
{
public static string verb { get; set; }
}
public class Points
{
public int definition { get; set; }
}
}
I do following to get the response:
var response = client.Execute<JsonResponseClass>(request);
var resData = response.Data;
How do I read/print values received from above? For example how do I print values verb and definition from the above deserialized response?
You're not supposed to nest the classes. Instead, add a property of each type to the root object's class.
public class JsonResponseClass
{
public Selector selector { get; set; }
public Points points { get; set; }
}
public class Selector
{
public static string verb { get; set; }
}
public class Points
{
public int definition { get; set; }
}
With that in place, the code works as expected:
var response = client.Execute<JsonResponseClass>(request);
var resData = response.Data;
var verb = resData.selector.verb;
var definition = resData.points.definition;
It's not clear what are you asking.
resData variable contains data from request stored in JsonResponseClass so you need to access it's fields like:
string verb = resData.verb;
Console.WriteLine(verb);