Getting json string programmatically C# - c#

I am trying to get json string from a url by using following line of code. When I enter the url in Google Chrome I get whole string and data. but when I use my code it returns only this line of string {"expand":"projects","projects":[]} it is exact what I get when I enter the url in IE 10. How can I get same data that I get when I enter the url in Chrome? here is my code to get the json data. var jsonStr = new WebClient().DownloadString("https_my_url");

You will need to authenticate the request via WebClient.
See this answer for how to do that if the site uses Forms Authentication.
WebClient accessing page with credentials

You need to use a JSON parser to turn it in to something useful. ServiceStack.Text (available via NuGet or download) has an excellent one that can turn json strings in to first-class POCOs.
using ServiceStack.Text;
public sealed class SomeObject
{
public string expand { get; set; }
public List<string> projects {get; set; }
}
And convert thusly:
SomeObject object = jsonString.FromJson<SomeObject>();
Note, I would make my POCOs a little more c# friendly and alias away the lower-case:
using ServiceStack.Text;
using ServiceStack.DataAnnotations;
public sealed class SomeObject
{
[Alias("expand")]
public string Expand { get; set; }
[Alias("projects")]
public List<string> Projects {get; set; }
}

Related

How do I use the #odata.nextlink parameter returned in the Reporting API response in .net C# application

I am retrieving data from an odata service. The response contains a link for loading more data i.e. odata.nextLink which I need to retrieve to load more data(odata.nextLink). How do I do this using C# code? The server's response is something like this:
{
"odata.metadata":"http://localhost:60497/odata/$metadata#tables","value":[
{"id":001,"name":"abc" }
.
.
],
"odata.nextLink":"http://localhost:60497/odata/tables?$skip=10"
}
The presence of the odata.nextLink element is used to indicate that there are more results available.
If you simply want to fetch all results then you would keep fetching additional results from each successive nextLink URI until you receive a response that does not contain a nextLink element.
In the most simple case you could simply have a while loop, however in most situations if a query is returning a large set of results you would want to retrieve some and then offer the user the means to request more rows.
In C# you might be using the OData Client library from Microsoft which allows you to perform LINQ queries on OData services.
Microsoft's documentation has a comprehensive example at https://learn.microsoft.com/en-gb/odata/client/pagination
Create a class for the Json Object which is returned, Like this
public class Value
{
public int id { get; set; }
public string name { get; set; }
}
public class Root
{
[JsonProperty("odata.metadata")]
public string OdataMetadata { get; set; }
public List<Value> value { get; set; }
[JsonProperty("odata.nextLink")]
public string OdataNextLink { get; set; }
}
Try to deserialize the Json object returned, here data is going to be the Json Object in String Format.
var RootObj = JsonConvert.DeserializeObject<Root>(data);
From this RootObj, you will be able to get the OdataNextLink value and other values you need, which you can store in your local variable.
Let me know if you have more questions on this.

JSON API query to get data using C#

I am a beginner in programming and have recently learnt and used http uri to get data and then parse json string from the stream using C# in SSIS and was able to load the data into sql server database.
Below is the sample code I used..
System.Uri uri = new Uri("API URL");
WebRequest webRequest = HttpWebRequest.Create(uri);
HttpWebRequest httpWebRequest = (HttpWebRequest)webRequest;
NetworkCredential networkCredential = new NetworkCredential("LOGIN","Password");
credentialCache.Add(uri,"Basic",networkCredential);
WebResponse webResponse = webRequest.GetResponse();
...
However I am trying to setup the same type of connection for another api which uses POST method.
The query looks something like.. URL + JSON API query which is similar to..
{"JSON" : {
"name": "Dataset",
"ColumnSelect": ["Name","Age","Email"],
"sort":["Name"],
"filterList": [
{
"Attribute": "Age",
"Operator": ">",
"Value": ["25"]
}],"returnObject"
I am not sure how this can be used to query the data and load data to sql like the http request. Can someone please advise me on the right direction to achieve this. Thank you for all your help.
I'm not %100 sure what your scenario is, but as far as I understand you are trying to get data from some server, and store the data in your database.
You have achieved it using HTTP GET, but this time you need to do it with POST.
The basic difference with GET and POST is, GET is used to query the existing data, but in POST, you are delivering something to the server. (of course there are more differences, check this link: https://www.w3schools.com/tags/ref_httpmethods.asp)
This can be done easily:
Prepare your POST request, you need to have a content for your parameters.
Create classes for your incoming response string, from your JSON posted:
public class JSON
{
public string name { get; set; }
public string[] ColumnSelect { get; set; }
public string[] sort { get; set; }
public filterList filterList { get; set; }
}
public class filterList
{
public string Attribute { get; set; }
public string Operator { get; set; }
public string[] Value { get; set; }
}
When you have the response string (stringified JSON), deserialize it via JSON.NET.
Now you have them as .NET objects. You can use Entity Framework to commit them to the database.
I can edit my answer if you need advice on any steps.

AWS Lambda C# - Accessing custom context

I have a simple Lambda function written in .NET Core (C#) that uses the APIGatewayProxyRequest object to go through all the request properties.
If I test this lambda function (from AWS Lambda), and pass it a sample event config that contains basic information:
I can get this information like so:
public string FunctionHandler(APIGatewayProxyRequest request, ILambdaContext context)
logger.Logger.Log($"Body: {request.Body} \n");
logger.Logger.Log($"Path: {request.Path} \n");
logger.Logger.Log($"Resource: {request.Resource} \n");
How is it that I can access custom context or authorizer values from the same data:
I have tried:
logger.Logger.Log($"RequestContext Authorizor: {request.RequestContext.Authorizer} \n");
Including it's different properties (StringKey, PrincipleId etc.)
It seems from Node.js, this would be simply achieved by using this:
event.requestContext.authorizer.customKey
There is no such thing in C#?
So, after spending 3 days troubleshooting this and with the help of the AWS engineers, this is what I've found;
There is a limitation with accessing the $context, $authorizer or any other custom variables from a Lambda function, written through .Net Core in C#
A new service request is being created for the AWS team for this.
To explain:
Currently, in node.js you have access to the entire payload of data being passed through to the Lambda function (within the event parameter), which includes all custom variables (you could access it directly - for the question example, like this: event.requestContext.authorizer.customKey.
This is not the same for the C# equivalent - which uses the APIGatewayProxyRequest request object within a Lambda function. So although you have access to the entire payload (including all the custom variables) within node, within C#, you only have access to the APIGatewayProxyRequest object. Properties of which can be found here:
Or in short:
public string Body { get; set; }
public IDictionary<string, string> Headers { get; set; }
public string HttpMethod { get; set; }
public bool IsBase64Encoded { get; set; }
public string Path { get; set; }
public IDictionary<string, string> PathParameters { get; set; }
public IDictionary<string, string> QueryStringParameters { get; set; }
public ProxyRequestContext RequestContext { get; set; }
public string Resource { get; set; }
public IDictionary<string, string> StageVariables { get; set; }
Being based off an object, this will not allow access to custom or "unknown" properties, even though they are part of the payload.
Long story short, as of right now: if you wish you work with custom variables of any sort, you would either need to code it through node(event) / python, or possibly overwrite an existing property within the APIGatewayProxyRequest object.
UPDATE:
There is a work around to accessing the entire payload of the data coming in:
A work around till then is have your Lambda function take in a System.IO.Stream instead of APIGatewayProxyRequest. Then you have access to the original JSON which you can parse yourself. You can grab the information you need from that JSON and then deserialize JSON to APIGatewayProxyRequest as well.
I don't know if people are wondering about this even today (after almost 3 years - I was), I have figured out a way. Could be helpful.
Note: This is only for a lambda built using the DotNet SDK.
In the AWS API G/W mapping template, you need to create a JSON template which matches the ApiGatewayProxyRequest class so that it can be deserialized. In the example below, I am trying to extract the body from the request and the source ip and user agent from the context of the request.
{
"Body": "$util.escapeJavaScript($input.body)",
"RequestContext" : {
"Identity" : {
"SourceIp" : "$context.identity.sourceIp",
"UserAgent" : "$context.identity.userAgent"
},
"RequestId" : "$context.requestId"
}
}
Now, for accessing these values in your lambda, you can do the following:
public async Task<SomeResponse> FunctionHandler(APIGatewayProxyRequest gatewayProxyRequest, ILambdaContext context)
{
var requestContext = gatewayProxyRequest.RequestContext;
var sourceIP = requestContext?.Identity?.SourceIp;
var body = gatewayProxyRequest.Body;
.
.
.
}

ServiceStack Json deserializing incorrectely

I've got a RequestDto, let's say Class A Dto, it contains a self defined type property:
// C# code
public Class MyObject
{
public string A { get; set; }
public string B { get; set; }
}
public Class ADto
{
public List<MyObject> MO { get; set;}
}
When I am trying to send the Dto using Json, the Json object looks like this:
{"MO":[{"A":"String","B":"a"},{"A":"String","B":"b"}]}
but the object I am receiving will be null.
However if I change the Json string into:
{MO:[{A:"String",B:"a"},{A:"String",B:"b"}]}
I lose the quotation marks on the objects' names and it works.
The correct format of Json should include those quotation marks right?
Why is this happening?
ServiceStack does serializes and deserializes valid JSON which requires every property name to be quoted however you're saying that the text below works:
{MO:[{A:"String",B:"a"},{A:"String",B:"b"}]}
However this isn't valid JSON, it instead looks like ServiceStack's JSV Format
You haven't mentioned where you're sending the JSV Format or have provided the Raw HTTP Request (for us to work it out), but I'm assuming if you're using Postman (mentioned in your comments) than you're trying to send JSON in the ?QueryString which isn't allowed.
But ServiceStack does support sending complex object graphs on the QueryString using JSV.
Since you're sending a complex type you'd either POST the request as either JSON or www-form-urlencoded Form Data or if you want to pass it in the QueryString you need to convert it to JSV.
In future please include the Raw HTTP Request as this question lacks any context on where you're changing the JSON string, how you're trying to use it or what's actually being sent, where you're sending it to, etc - making it impossible to guess what the issue is.
Change your class to
public Class MyObject
{
public string Mobile { get; set; }
public string Name { get; set; }
}
public Class ADto
{
public List<MyObject> MO { get; set;}
}
Then your json should be
{MO:[{Mobile:"0556604",Name:"Peter"},{Mobile:"4565466",Name:"John"}]}

Converting JSON data into an object

I am very new to this.Pardon me if I make any mistakes.
I have data in JSON form.Can I read this data directly and use it in C# code ?
From what I understood from reading up on the internet,I think I have to convert it into an object form to use the data.Am I right ?
If yes,Then I saw this method to convert as below :
string data = JsonConvert.DeserializeObject<string>(getmyissue());
getmyissue is the function which returns a string which has data in json format.
This gives me an exception saying
"Error reading string.Unexpected Token."
Can someone guide me where am I going wrong ?
EDIT
MyIssue.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Example
{
public class MyIssue
{
public string name{get;set;}
public string description { get; set; }
public string created { get;set; }
public string updated{get;set;}
public string displayName { get; set; }
}
}
Program.cs
MyIssue obj=null;
try
{
obj = JsonConvert.DeserializeObject<MyIssue>(manager.getmyissue());
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
Console.WriteLine("Name: "+obj.name);
The easiest way to de-serialize Json in a C#/.NET program is to use the brilliant NewtonSoft JSON library.
There are numerous ways to do it, but I have to admit that the NS libs just get on with the task (and no I'm not a member of the team etc, just an Avid User :-) ).
To do what you want for example, if you had:
{'Name': 'A person', 'AllowAccess': true,'Areas': ['Sales','Admin']}
You would first build an object to represent it as follows:
public MyObject
{
public string Name { get; set; }
public bool AllowAccess { get; set; }
public List<string> Areas { get; set; }
}
Once you've done this, it's a simple case of just doing the following:
string jsonString = "// Your json formated string data goes here";
MyObject myObject = JsonConvert.DeserializeObject<MyObject>(jsonString);
The properties in your object should at that point, reflect the properties in the JSON data you sent to it.
You will of course need to add the NS JSON Libs to your project, either via NuGet or Manually, which ever is easier for you, everything you need to know about that is here:
How to install JSON.NET using NuGet?
The really good thing about NS JSON however is not the ease of use, but the fact that it can also do dynamic de-serialization.
This comes in handy if you've no idea what to expect in the JSON you receive, and so don't know ahead of time how to construct an object to hold the results.
Rather than repeat what others have said however, you can find more information of doing things dynamically in this stack overflow post:
Deserializing JSON using JSon.NET with dynamic data
Update
Looking at your JSON data you have way more fields/properties in there than your trying to parse, and none of the libraries in common use (To the best of my knowledge) will pick and choose the fields to copy, you either have an object that represents them all, or not at all, the later of which I believe is the problem your facing.
I have a rather neat "JSON" plug in for chrome, than when given a chunk of JSON data formats the output for me nicely and makes it easy to read, it also helps massively when defining objects, allowing you to see the full nested structure of your data, here are a series of images showing your JSON data formatted using this plugin:
I'm not going to paste anymore images in, but that goes on for another 4 pages!!
Now, some extra information that may help you.
I know from experience (I had to write a parser in PHP for these Jira webhooks) that within the Jira control panel, you can configure your webhooks to ONLY return the information your interested in.
Right now, it looks like you've just told the system to dump everything, for every event that you've hooked too (Which looks like - all of them), it's been a while since I did any work with these, but as well as a global webhook, you also have individual webhooks, which only fire on specific events and produce JSON data that's very much smaller than what your dealing with here.
I'd therefore advise you, to take a look in your Jira control panel (Or ask your Admin/Lead Dev/etc to take a look) and seriously trim down as much of that data as you can.
Further more, if memory serves me right, you can also make various web API calls to the Jira service to get this info too, and in that case you can tell the API exactly what your interested in, meaning it will only return the fields you need.
Right now, your main problem is the sheer volume of data your trying to deal with, if you tackle that problem, you'll find the issues surrounding the code your trying to get working will be very much easier to deal with.
Update 2
Just to make it clearer what I mean by using a "dynamic" type to get at your data, you would use something like the following code:
string jsonString = "// Your json formated string data goes here";
var result = JsonConvert.DeserializeObject<dynamic>(jsonString);
The difference here is that your using the C# dynamic type rather than a strongly typed object of your own design.
"dynamic" is useful, because it's kind of like having an empty object, and then having the properties added for you, without you having to define it.
What this essentially means is that, if you pass in the following JSON:
{'Name': 'A person', 'AllowAccess': true,'Areas': ['Sales','Admin']}
You'll end up with a dynamic object that looks like:
result = dynamic
{
public string Name { get; set; }
public bool AllowAccess { get; set; }
public List<string> Areas { get; set; }
}
thus:
result.Name
will get you access to the contents of the Name field and so on.
If your JSON was then changed to become:
{'Name': 'A person', 'AllowAccess': true,'Areas': ['Sales','Admin'], 'Location': 'The World' }
Your object would magically have a property called 'Location' containing the value 'The World' which you could access using:
result.Location
In your case, this would allow you to define your concrete object EG:
public MyObject
{
public string Name { get; set; }
public string Email { get; set; }
}
and then do something like the following (Assuming that your inbound JSON had properties in called Name & Email):
string jsonString = "// Your json formated string data goes here";
var result = JsonConvert.DeserializeObject<dynamic>(jsonString);
MyObject myObject = new MyObject
{
Name = result.Name,
Email = result.Email
}
You'd then discard the dynamic object as you'd not need it anymore.
The BIG problem your going to have with this approach is maintaining your models. Manual property assignment is all fine and dandy for a small handful of properties and objects, but it soon becomes a huge maintenance nightmare as your software grows.
I'm sure it doesn't take much to imagine what kind of task you'd be facing if you had to do this for 100 different JSON requests and 50 different types of objects.
For this reason, using this approach you should really consider using some kind of mapping technology such as "AutoMapper", however for now I'm going to advise you leave that until later before you start researching it, as it'll not help you to be clear about dealing with this dynamic approach.
The JSON you get is already a string, so converting it to string doesn't make much sense. You need to create classes that reflect the structure represented by the JSON string.
For example to convert the following JSON into objects, you'd have to create a class for the users:
{"user":{"name":"asdf","teamname":"b","email":"c","players":["1","2"]}}
public class User
{
public string name { get; set; }
public string teamname { get; set; }
public string email { get; set; }
public Array players { get; set; }
}
Then you should be able to use this:
JavaScriptSerializer jss= new JavaScriptSerializer();
List<User> users = jss.Deserialize<List<User>>(jsonResponse);

Categories

Resources