C#: "Cannot deserialize the current JSON array" - c#

I would like to start by saying that I am not a developer and this is my very first time writing a code to this extend of complication (at least to me). Any help/guidance would be much appreciated.
The idea of this program is to retrieve the employee user ID (or signature) from an API URL once the name has been entered.
I created a class that identifies the information that needs to be retrieved from the API (Below is the code):
namespace TimeSheet_Try11_Models
{
public class Employeename
{
public List<string> Signature { get; set; }
public List<string> FirstName { get; set; }
public List<string> FullName { get; set; }
public List<string> LastName { get; set; }
}
}
Next I created a folder called WebAPI which will access the API and retrieve the needed information. (please see the code)
namespace TimeSheets_Try_11.Controllers
{
class WebAPI
{
public string Getsignature(string name)
{
var cookies = FullWebBrowserCookie.GetCookieInternal(new Uri(StaticStrings.UrlIora), false);
WebClient wc = new WebClient();
wc.Encoding = System.Text.Encoding.UTF8;
wc.Headers.Add("Cookie:" + cookies);
wc.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
wc.UseDefaultCredentials = true;
string uri = "";
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
uri = StaticStrings.UrlIora + name;
var response = wc.DownloadString(uri);
string json = #"[{'signature':'JANDO','firstName':'Jane','fullName':'Deo, Jane','lastName':'Deo'}]";
Employeename status = JsonConvert.DeserializeObject<Employeename>(json);
string signature = status.Signature.ToString();
return signature;
}
}
}
Finally, the following code is my code for the forms that will retrieve and display information.
namespace TimeSheets_Try_11
{
public partial class Form1 : Form
{
WebAPI WA = new WebAPI();
public Form1()
{
InitializeComponent();
webBrowser1.Url = new Uri(StaticStrings.UrlIora);
}
private void label1_Click(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
string strurltest = string.Format("https://iora.UniversityofHouston.com/api/dictionary/employee/" + textBox1.Text);
System.Net.WebRequest requestObjGet = WebRequest.Create(strurltest);
requestObjGet.Credentials = CredentialCache.DefaultNetworkCredentials;
requestObjGet.Method = "Get";
HttpWebResponse reponsObjGet = null;
reponsObjGet = (HttpWebResponse)requestObjGet.GetResponse();
string[] usernames = new string[] { "Koehne, Craig", "Bergeron, Ronald" };
string[] userid = new string[] { "CKOEH", "RONBE" };
for (int i = 0; i < usernames.Length; i++)
{
if (textBox1.Text.Contains(usernames[i]))
{
textBox2.Text = userid[i];
}
}
string sgname; string projectstring;
projectstring = textBox1.Text.ToString();
sgname = WA.Getsignature(projectstring);
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
string StringConn = textBox1.Text;
}
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
}
}
}
Problem: The code does not seem to have any errors, however when I start debugging the code, it gives me an error that states:
"Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the
current JSON array (e.g. [1,2,3]) into type
'TimeSheet_Try11_Models.Employeename' because the type requires a JSON
object (e.g. {"name":"value"}) to deserialize correctly."

Your JSON string contains an array that contains one object. But you're trying to deserialize it into just a single object.
Either deserialize the JSON string into a C# array:
string json = #"[{'signature':'JANDO','firstName':'Jane','fullName':'Deo, Jane','lastName':'Deo'}]";
Employeename[] status = JsonConvert.DeserializeObject<Employeename[]>(json);
Or change the JSON string so it's no longer an array, just an object:
string json = #"{'signature':'JANDO','firstName':'Jane','fullName':'Deo, Jane','lastName':'Deo'}";
Employeename status = JsonConvert.DeserializeObject<Employeename>(json);
Also, your Employeename class makes no sense, the properties should be of type string:
public class Employeename
{
public string Signature { get; set; }
public string FirstName { get; set; }
public string FullName { get; set; }
public string LastName { get; set; }
}

Related

Getting custom object of a Json with Async function

I'm trying to use the HUE API, I was able to get the JSON with the list of the bulb but when i'm trying to make a custom object from it, its not working. No error and no exception, nothing is happening. Here's my attempt :
LightsPage.xaml.cs
public partial class LightsPage : Page
{
public LightsPage()
{
InitializeComponent();
}
private void Page_Loaded(object sender, RoutedEventArgs e)
{
var listLights = Light.GetLightAsync();
Console.WriteLine();
}
}
Light.cs
public class Light
{
private string name { get; set; }
private string productname { get; set; }
private string uniqueid { get; set; }
private StateLight state { get; set; }
public Light()
{
}
public Light(string Name, string Productname, string Uniqueid, StateLight State)
{
name = Name;
productname = Productname;
uniqueid = Uniqueid;
state = State;
}
static async public Task<List<Light>> GetLightAsync()
{
List<Light> lights = new List<Light>();
Uri baseUri = new Uri($"http://{ConfigurationManager.AppSettings["IpBridge"]}");
Uri apiUri = new Uri(baseUri, $"/api/{ConfigurationManager.AppSettings["userName"]}/lights");
HttpClient client = new HttpClient();
HttpResponseMessage response = await client.GetAsync(apiUri);
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
dynamic jsonResult = JsonConvert.DeserializeObject(responseBody);
foreach(var item in jsonResult)
{
Light light = new Light
{
name = (string)item["name"],
productname = (string)item["productname"],
uniqueid = (string)item["uniqueid"],
state = new StateLight
{
on = (bool)item["state"]["on"],
bri = (int)item["state"]["bri"]
}
};
lights.Add(light);
}
return lights;
}
}
The JSON looks like this :
{"1":{"state":{"on":true,"bri":254,"alert":"select","mode":"homeautomation","reachable":true},
"swupdate":{"state":"noupdates","lastinstall":"2020-02-22T14:21:56"},
"type":"Dimmable light",
"name":"Salon blanc",
"modelid":"LWA001",
"manufacturername":"Signify Netherlands B.V.",
"productname":"Hue white lamp",
"capabilities":{"certified":true,"control":{"mindimlevel":5000,"maxlumen":800},
"streaming":{"renderer":false,"proxy":false}}, etc....
There is multiple bulb but you get the point.
In debug, when i'm reaching the construction of the objects Light in the loop, it stops there.
I'm fairly new to Task and Async so maybe it's coming from here but I don't know what to do...
Thx for your answers :)

JsonProperty is being ignored when Serialized for Office Addin

When Serialized the jsonproperty is ignored. The same piece of code is working for a console application. But when I use the same piece of code for developing a Microsoft office add-in then I get this problem.
Expected Result :{"jql":"test ORDER BY UPDATED DESC","startAt":0,"maxResults":50,"fields":[]}
Actual Result: {"JQL":"test ORDER BY UPDATED DESC","StartAt":0,"MaxResults":50,"Fields":[]}
public class SearchRequest
{
[JsonProperty("jql")]
public string JQL { get; set; }
[JsonProperty("startAt")]
public int StartAt { get; set; }
[JsonProperty("maxResults")]
public int MaxResults { get; set; }
[JsonProperty("fields")]
public List<string> Fields { get; set; }
[JsonProperty("SearchRequest")]
public SearchRequest()
{
Fields = new List<string>();
}
}
public void ViewCases_Load(object sender, EventArgs e)
{
SearchRequest request = new SearchRequest();
request.JQL = "test ORDER BY UPDATED DESC";
request.MaxResults = 50;
request.StartAt = 0;
string data = JsonConvert.SerializeObject(request);
}

Image from Wikipedia main page is now showing in window form

I try to get the first image from wikipedia api. I wrote the following C# code to retrieve the source from Thumbnail. But whenever I run the code it shows exception
An unhandled exception of type 'Newtonsoft.Json.JsonReaderException'
occurred in Newtonsoft.Json.dll Additional information: Unexpected
character encountered while parsing value: <. Path '', line 0,
position 0.
My code is as follows
public class Thumbnail
{
public string source { get; set; }
public int width { get; set; }
public int height { get; set; }
}
public class Pageval
{
public int pageid { get; set; }
public int ns { get; set; }
public string title { get; set; }
public Thumbnail thumbnail { get; set; }
public string pageimage { get; set; }
}
public class Query
{
public Dictionary<string, Pageval> pages { get; set; }
}
public class RootObject
{
public string batchcomplete { get; set; }
public Query query { get; set; }
}
class Class1
{
public static PictureBox Image1 = new PictureBox();
public static Label Image1_title = new Label();
public static void Load_Image(string name1, string LocationName)
{
var startPath = Application.StartupPath;
string Imagefolder = Path.Combine(startPath, "Image");
string subImageFolder = Path.Combine(Imagefolder, LocationName);
System.IO.Directory.CreateDirectory(subImageFolder);
using (var wc = new System.Net.WebClient())
{
var uri = ("https://en.wikipedia.org/w/api.php?action=query&prop=pageimages&pithumbsize=400&titles="+name1);
var response = wc.DownloadString(new Uri(uri));
var responseJson = JsonConvert.DeserializeObject<RootObject>(response);
var firstKey = responseJson.query.pages.First().Key;
string image1 = responseJson.query.pages[firstKey].thumbnail.source;
string Image_title = responseJson.query.pages[firstKey].title;
Image1.SizeMode = PictureBoxSizeMode.StretchImage;
Image1.LoadAsync(image1);
Image1_title.Text = Image_title;
}
}
}
}
In form1.cs I call this class in the follwing way. and in Textbox I wrote the name such as Berlin.
private void button1_Click(object sender, EventArgs e)
{
Class1.Image1 = pictureBox1;
Class1.Load_Image(textBox1.Text, textBox1.Text);
}
I am not finding out what is the problem with this code
The json I got is
{
"batchcomplete": "",
"query": {
"pages": {
"3354": {
"pageid": 3354,
"ns": 0,
"title": "Berlin",
"thumbnail": {
"source": "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3b/Siegessaeule_Aussicht_10-13_img4_Tiergarten.jpg/400px-Siegessaeule_Aussicht_10-13_img4_Tiergarten.jpg",
"width": 400,
"height": 267
},
"pageimage": "Siegessaeule_Aussicht_10-13_img4_Tiergarten.jpg"
}
}
}
}
If you look at the output of your query, it says this:
This is the HTML representation of the JSON format. HTML is good for debugging, but is unsuitable for application use.
Specify the format parameter to change the output format. To see the non-HTML representation of the JSON format, set format=json.
If you follow that advice, it should fix your error.
To display image from URL you need to use WebClient to load image in local system.
ie.
string remoteUri = "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3b/Siegessaeule_Aussicht_10-13_img4_Tiergarten.jpg/400px-Siegessaeule_Aussicht_10-13_img4_Tiergarten.jpg";
string fileName = "MyImage.jpg",
WebClient myWebClient = new WebClient();
myWebClient.DownloadFile(remoteUri,fileName);

WebRequest 400 bad request to api

I am making webrequest to instagram api, and recieving 400 bad request, but i guess this is not something specific to instagram and is a generic error in my code.
here is my code."code" paramter in this request is obtained from previous request.Code breaks at "GetResponse" method
string clientID = "myclientid";
string clientsecret="myclientsecret";
string redirectURL = "http://localhost:64341/";
string webrequestUri = "https://api.instagram.com/oauth/
access_token? client_id=" + clientID + "&client_secret=
" + clientsecret + "&grant_type=authorization_code" + "&redirect_uri="redirectURL+"&code="
+Request.QueryString["code"].ToString();
WebRequest request = WebRequest.Create(webrequestUri);
request.Method = "POST";
WebResponse response = request.GetResponse();
C#/asp.net Working example:
namespace InstagramLogin.Code
{
public class InstagramAuth
{
private InstagramClient myApp = new InstagramClient();
public string genUserAutorizationUrl()
{
return String.Format(myApp.OAuthAutorizeURL, myApp.ClientId, myApp.RedirectUri);
}
public AuthUserApiToken getTokenId(string CODE)
{
//curl \-F 'client_id=CLIENT-ID' \
//-F 'client_secret=CLIENT-SECRET' \
//-F 'grant_type=authorization_code' \
//-F 'redirect_uri=YOUR-REDIRECT-URI' \
//-F 'code=CODE' \https://api.instagram.com/oauth/access_token
var wc = new WebClient();
var wcResponse = wc.UploadValues(myApp.AuthAccessTokenUrl,
new System.Collections.Specialized.NameValueCollection() {
{ "client_id", myApp.ClientId },
{ "client_secret", myApp.ClientSecret },
{ "grant_type", "authorization_code"},
{ "redirect_uri", myApp.RedirectUri},
{ "code", CODE}
});
var decodedResponse = wc.Encoding.GetString(wcResponse);
AuthUserApiToken UserApiToken = JsonConvert.DeserializeObject<AuthUserApiToken>(decodedResponse);
return UserApiToken;
}
}
}
your object:
namespace InstagramLogin.Code
{
public class InstagramClient
{
private const string ApiUriDefault = "https://api.instagram.com/v1/";
private const string OAuthUriDefault = "https://api.instagram.com/oauth/";
private const string RealTimeApiDefault = "https://api.instagram.com/v1/subscriptions/";
private const string OAuthAutorizeURLDefault = "https://api.instagram.com/oauth/authorize/?client_id={0}&redirect_uri={1}&response_type=code";
private const string AuthAccessTokenUrlDefault = "https://api.instagram.com/oauth/access_token";
private const string clientId = "clientid";
private const string clientSecretId = "clientsecretid";
private const string redirectUri = "http://localhost/InstagramLogin/InstaAuth.aspx";
private const string websiteUri = "http://localhost/InstagramLogin/InstaAuth.aspx";
public string ApiUri { get; set; }
public string OAuthUri { get; set; }
public string RealTimeApi { get; set; }
public string OAuthAutorizeURL { get { return OAuthAutorizeURLDefault; } }
public string ClientId { get { return clientId; } }
public string ClientSecret { get { return clientSecretId; } }
public string RedirectUri { get { return redirectUri; } }
public string AuthAccessTokenUrl { get { return AuthAccessTokenUrlDefault; } }
//removed props
}
}
instagram loged user:
namespace InstagramLogin.Code
{
public class SessionInstaAuthUser
{
public bool isInSession()
{
return HttpContext.Current.Session["AuthUserApiToken"] != null;
}
public AuthUserApiToken get()
{
if (isInSession())
{
return HttpContext.Current.Session["AuthUserApiToken"] as AuthUserApiToken;
}
return null;
}
public void set(AuthUserApiToken value)
{
HttpContext.Current.Session["AuthUserApiToken"] = value;
}
public void clear()
{
if (isInSession())
{
HttpContext.Current.Session["AuthUserApiToken"] = null;
}
}
}
}
markup:
<asp:Button ID="btnInstaAuth"
Text="Click here to get instagram auth"
runat="server" />
Code behind:
//objects
private InstagramClient InstagramApiCLient = new InstagramClient();
private InstagramAuth AuthManager = new InstagramAuth();
private SessionInstaAuthUser SesssionInstaUser = new SessionInstaAuthUser();
//click login with tests - user is logged (in session)
void btnInstaAuth_Click(Object sender,
EventArgs e)
{
btnGetInstaPosts.Visible = false;
if (SesssionInstaUser.isInSession())
{
SesssionInstaUser.clear();
Button clickedButton = (Button)sender;
clickedButton.Text = "Click here to get instagram auth";
btnInstaAuth.Visible = true;
}
else
{
Response.Redirect(AuthManager.genUserAutorizationUrl());
}
}
You can find what you need in this class InstagramAuth sorry if I did forgot to remove some of extra methods or properties, please strip it out.
This button can be used on all page, still don't forget to add on page load at the page set in instagram as login page, query string parse:
//here you read the token instagram generated and append it to the session, or get the error :)
if (!IsPostBack)
{
if (!SesssionInstaUser.isInSession())
{
if (Request.QueryString["code"] != null)
{
var token = AuthManager.getTokenId(Request.QueryString["code"]);
SesssionInstaUser.set(token);
//set login button to have option to log out
btnInstaAuth.Text = token.user.username + " leave instagtam oAuth";
Response.Redirect(Request.Url.ToString().Split('?')[0]);
}
else
if (Request.QueryString["error"] != null)
{
btnInstaAuth.Text = Request.QueryString["error_description"];
}
}
}
Sorry If I'd missed something, php curl in to c# is implemented in first class.
Update (I did forget something), insta user obj :)
namespace InstagramLogin.Code
{
public class UserLogged
{
public string id { get; set; }
public string username { get; set; }
public string full_name { get; set; }
public string profile_picture { get; set; }
}
public class AuthUserApiToken
{
public string access_token { get; set; }
public UserLogged user { get; set; }
}
}

How to read this JSON on Windows Phone?

I have to read this JSON :
[
{"id":"2","code":"jne","name":"JNE"},
{"id":"5","code":"pcp","name":"PCP"},
{"id":"1","code":"pos","name":"Pos Indonesia"},
{"id":"6","code":"wahana","name":"Wahana"}
]
I have tried this :
[DataContract]
public class Ekspedisi
{
[DataMember]
public int id { get; set; }
[DataMember]
public String code { get; set; }
[DataMember]
public String name { get; set; }
}
and this:
public static Ekspedisi[] res;
string link5 = "http://www.ongkoskirim.com/api/0.2/?id=OAL66afd139a386fee6dc5a5597abd7daba&q=expedition"
WebClient client = new WebClient();
client.OpenReadCompleted += new OpenReadCompletedEventHandler(client_OpenReadCompleted);
client.OpenReadAsync(new Uri(link5), UriKind.Absolute);
and this :
void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
try
{
var ser = new DataContractJsonSerializer(typeof(Ekspedisi));
res = (Ekspedisi[])ser.ReadObject(e.Result);
for (int i = 0; i < length; i++)
{
Debug.WriteLine(res[i].id+","+res[i].name);
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
Debug.WriteLine(ex.StackTrace);
}
}
But it always showing invalidCastException. Can anyone help me?
When you are deserialising the JSON, you are using the type of Ekspedisi even though you are returning a collection. If you change this line of code:
var ser = new DataContractJsonSerializer(typeof(Ekspedisi));
to
var ser = new DataContractJsonSerializer(typeof(IEnumerable<Ekspedisi>));
which is a collection of your type; you will find you no longer receive the exception.

Categories

Resources