System.Text.Json.Deserialize an array into C# class - json

First off, I am working with the Google recaptcha RESTful service trying to get the JSON object into a class. With WSDL's, Visual Studio will generate all this code for you so that it is easy to work with, but RESTful it seems you have to do everything yourself, am I missing something? I am working with VS2019 and would have thought there is some way to import this stuff to make life easy. I have yet to find anything, so...
Google is returning:
{
"success": false,
"error-codes": [
"invalid-input-response",
"invalid-input-secret"
]
}
I would like to deserialize it into this:
[DataContract]
public class GoogleReCaptchaResponse
{
[DataMember(Name = "success")]
public bool Success { get; set; }
[DataMember(Name = "error-codes")]
public List<string> ErrorCodes { get; set; }
[JsonExtensionData]
public Dictionary<string, object> ExtensionData { get; set; }
}
I see the error-codes in the ExtensionData, but ErrorCodes is always null. What do I have wrong?
https://dotnetfiddle.net/RtjbwR

You should use JsonPropertyName attribute from System.Text.Json.Serialization namespace
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
public class GoogleReCaptchaResponse
{
[JsonPropertyName("success")]
public bool Success { get; set; }
[JsonPropertyName("error-codes")]
public List<string> ErrorCodes { get; set; }
}
public class Program
{
public static void Main()
{
GoogleReCaptchaResponse json = System.Text.Json.JsonSerializer.Deserialize<GoogleReCaptchaResponse>("{ \"success\": false, \"error-codes\": [\"invalid-input-response\",\"invalid-input-secret\"]}");
if (json.ErrorCodes == null)
{
Console.WriteLine("no Error Codes");
}
else
{
Console.WriteLine("Error Codes!");
}
}
}

Related

Using JsonUtility FromJson to deserialize JSON in Unity

I'm having an issue while trying to read a Json string in unity.
I created Classes based on the json response im receiving
but im not able to deserialize this json
Where I did wrong, can anybody help?
{
"status": 200,
"isSuccess": true,
"message": "Suggestion Found",
"response": {
"result": [
{
"OriginalWord": "goodboy",
"suggests": [
{
"suggestWords": "good boy"
},
{
"suggestWords": "Cordoba"
},
{
"suggestWords": "Catawba"
},
{
"suggestWords": "Catawba's"
}
]
}
]
}
}
My Classes
[Serializable]
public class Suggest
{
[SerializeField]
public string suggestWords { get; set; }
}
[Serializable]
public class Result
{
[SerializeField]
public string OriginalWord { get; set; }
[SerializeField]
public List<Suggest> suggests { get; set; }
}
[Serializable]
public class Response
{
[SerializeField]
public int status { get; set; }
[SerializeField]
public bool isSuccess { get; set; }
[SerializeField]
public string message { get; set; }
[SerializeField]
public List<Result> result { get; set; }
}
Im Deserializing like this
Response response = JsonUtility.FromJson<Response>(jsonString);
Above every class there got to be [System.Serializable] this is because UnityEngine has its own implementation of Serializable so you got to indicate its the System's that you want to use rather then Unity's. You also dont need to have [SerializeField] since this is if you want to show the property in Unity's inspection window and since this will not go onto any gameobject you dont need this. You just got to make it public.
Also in the class public class Response if you want json to map correctly you wouldnt use public List<Result> result { get; set; }, it would have to be named response and it will have to be 1 object not a list. So you can create a class called Results and have it have a list variable called result and it will be a list of type Result (no s). and in the result it would have the OriginalWord and a list of Suggest called suggests
Moreover, you must have a constructor for each class for it to work. So it would look like this:
[System.Serializable]
public class Suggest
{
public string suggestWords;
public Suggest(string suggestWords)
{
this.suggestWords = suggestWords;
}
}
[System.Serializable]
public class Result
{
public string OriginalWord;
public List<Suggest> suggests;
public Result(string OriginalWord, List<Suggest> suggests)
{
this.OriginalWord = OriginalWord;
this.suggests = suggests;
}
}
[System.Serializable]
public class Results
{
public List<Result> result;
public Results(List<Result> result)
{
this.result = result;
}
}
[System.Serializable]
public class Response
{
public int status;
public bool isSuccess;
public string message;
public Results response;
public Response (int status, bool isSuccess, string message, Result response)
{
this.status = status;
this.isSuccess = isSuccess;
this.message = message;
this.response = response;
}
}

Need a help to deserialized nested json response

with the web api getting following response, want help to deserialize following json response in vb.net.
{
"data": {
"getReport": {
"report_date": "April 20, 2020",
"report_date_iso": "2020-04-20",
"links": {
"__typename": "Links",
"proportions_diagram": null
},
"results": {
"shape_and_cutting_style": "Emerald Cut",
"data": {
"shape": {
"shape_category": "F"
},
"girdle": null,
"inscription_graphics": []
}
},
"quota": {
"remaining": 4971
}
}
}
}
Thanks in advance
This worked perfect for me on .NET Core 3.1.
To test it:
In Visual Studio 2019, create a winform in .NET Core 3.1. Be sure it has the NuGet package for Newtonsoft.JSON.
Add a button called btnJsonConvTest, and a textbox called txtJSONinput.
Add a new class file to the project - name doesn't matter. Delete standard content from the file.
Select and copy your JSON. In Visual Studio, click Edit > Paste Special > Paste JSON as Classes. This will create the class structure you see below.
Add the bits of code from below. Note that I gave my class the name JSONTestObject.
Run your program, paste your JSON test string into the text box, and click the button.
Code:
using Newtonsoft.Json;
Button click event:
private void btnJsonConvTest_Click(object sender, EventArgs e)
{
JSONTestObject testobj = JsonConvert.DeserializeObject<JSONTestObject>(txtJSONinput.Text);
String res = JsonConvert.SerializeObject(testobj);
MessageBox.Show(res);
}
And the class that VS created for us:
public class JSONTestObject
{
public Data data { get; set; }
}
public class Data
{
public Getreport getReport { get; set; }
}
public class Getreport
{
public string report_date { get; set; }
public string report_date_iso { get; set; }
public Links links { get; set; }
public Results results { get; set; }
public Quota quota { get; set; }
}
public class Links
{
public string __typename { get; set; }
public object proportions_diagram { get; set; }
}
public class Results
{
public string shape_and_cutting_style { get; set; }
public Data1 data { get; set; }
}
public class Data1
{
public Shape shape { get; set; }
public object girdle { get; set; }
public object[] inscription_graphics { get; set; }
}
public class Shape
{
public string shape_category { get; set; }
}
public class Quota
{
public int remaining { get; set; }
}
When I test it, I get the same JSON string back out as went into it, thus proving that both the serialization and deserialization methods correctly move data in and out of the class properties.

Unity3D, creating a Json post request

I have to create a post request in Json in this format.
{
"request": {
"application": "APPLICATION_CODE",
"auth": "API_ACCESS_TOKEN",
"notifications": [{
"send_date": "now", // YYYY-MM-DD HH:mm OR 'now'
"ignore_user_timezone": true, // or false
"content": "Hello world!"
}]
}
}
This is my first time serializing Json String and I have no idea how to do this, I have tried a few different things but could never get the exact format.
Would really appreciate any kind of help.
Thanks!
First, you cannot put comment on a json file, but I guess it was just there for now.
Then you can paste your json in converters like this one http://json2csharp.com/
And you get the following:
public class Notification
{
public string send_date { get; set; }
public bool ignore_user_timezone { get; set; }
public string content { get; set; }
}
public class Request
{
public string application { get; set; }
public string auth { get; set; }
public List<Notification> notifications { get; set; }
}
public class RootObject
{
public Request request { get; set; }
}
Now you need to fix a few issues that are required for JsonUtility:
[Serializable]
public class Notification
{
public string send_date;
public bool ignore_user_timezone;
public string content;
}
[Serializable]
public class Request
{
public string application;
public string auth;
public List<Notification> notifications;
}
[Serializable]
public class RootObject
{
public Request request;
}
Finally:
RootObject root = JsonUtility.FromJson<RootObject>(jsonStringFile);
You can also use SimpleJSON like this ;
string GetRequest () {
JSONNode root = JSONNode.Parse("{}");
JSONNode request = root ["request"].AsObject;
request["application"] = "APPLICATION_CODE";
request["auth"] = "API_ACCESS_TOKEN";
JSONNode notification = request ["notifications"].AsArray;
notification[0]["send_date"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm");
notification[0]["ignore_user_timezone"] = "true";
notification[0]["content"] = "Hello world!";
return root.ToString ();
}

Return self referencing model in JSON format using Web Api 2 controller

I have a self referencing model called Folder and also an Entity called Content which contains the Folder Entity.
public class Folder : BaseEntity
{
public int Id { get; set; }
public string Name { get; set; }
public int? ParentId { get; set; }
public virtual Folder Parent { get; set; }
public virtual ICollection<Folder> Children { get; set; }
}
public class Content : BaseEntity
{
[Key]
public int Id { get; set; }
public string Title { get; set; }
public string HTML { get; set; }
public string Summary { get; set; }
public int XmlConfigId { get; set; }
public int FolderId { get; set; }
public virtual Folder Folder { get; set; }
}
Here is my Application Db context
public class ApplicationDbContext: DbContext
{
public DbSet<Folder> Folders { get; set; }
public DbSet<Content> Contents { get; set; }
public ApplicationDbContext() : base("ProjectDB") {
Database.SetInitializer<ApplicationDbContext>(null);
}
}
Everything works fine if i am using a razor view to display the data and also i am able to access the The Folder property that is inside the Content Entity.
The problem is when i try to display the data using Web API.
My web API
public class ContentApiController : ApiController
{
[HttpGet]
public IEnumerable<Content> GetAllContents()
{
return _unitofwork.Contents.GetAllContents();
}
}
On the Web API, the GetAllContents() function just returns the Entity models coming directly from the Folders DBSet. It is not calling the ToList() function since i want to do lazy loading. Here is the code for the GetAllContents() function.
public IEnumerable<Content> GetAllContents()
{
return ApplicationDbContext.Contents.Include(c=>c.Folder);
}
So in order for this to work i have to add.
Configuration.LazyLoadingEnabled = false;
to my applicationDbContext constructor which i really don't want.
and also
Global.asax
GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
WebApiConfig
JsonMediaTypeFormatter jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().Single();
jsonFormatter.UseDataContractJsonSerializer = false;
jsonFormatter.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;
jsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
jsonFormatter.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.None;
Is there any way to expose the json data without out turning off Lazy loading. Thanks.
Just call ToList on your query, or, even better, ToListAsync:
[HttpGet]
public async Task<IEnumerable<Content>> GetAllContents()
{
return await _unitofwork.Contents.GetAllContents().ToListAsync;
}
Even if you enable LazyLoading, you cannot avoid to materialize your data before returning it to the client (and let the Serializer do its work).
In your MVC example, the framework itself enumerates the result in your View (I suppose), and thus you are not directly calling ToList, but in your scenario you have to materialize your Entities explicitly.
Please note that there is no performance issue in calling ToList/ToListAsync in your controller.

How to read this Json to controller object? Kendo UI grid server filtering

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)