Accessed JArray values with invalid key value in different json - c#

I've this json:
{
"status": true,
"Text": "Example"
}
But sometimes this could change, so I need to check if the index Text is available in the response passed, code:
var container = (JContainer)JsonConvert.DeserializeObject(response);
var message = container["Text"];
the problem is that I get this exception on message (if the json doesn't contain the key text):
{"Accessed JArray values with invalid key value: \"Text\". Int32 array index expected."}
How can I avoid this problem?

What version of NewtonSoft are you using?
The following results in message being null and no exception is thrown.
var res = #"{""status"": true }";
var container = (JContainer)JsonConvert.DeserializeObject(res);
var message = container["Text"];
// message = null
Update:
Following your response, even this doesn't throw the exception you're seeing:
var res = #"{}";
var container = (JContainer)JsonConvert.DeserializeObject(res);
var message = container["Text"];
Having updated my code to reflect yours with the same version I'm still not getting the exception you're seeing. This is what I'm doing:
var res = #"{""trace"":{""details"":{""[date]"":""[29-02-2016 17:07:29.773750]"",""[level]"":""[info]"",""[message]"":""[System Done.]""},""context"":[[{""ID"":""John Dillinger""}]]}}";
var container = (JContainer)JsonConvert.DeserializeObject(res);
var message = container["Text"];
The message variable is still null.
In light of this perhaps try create a simple console application with the above code and see if you get the same exception?

Related

RavenDB: How to prevent $type being saved to a dynamic typed property?

Is there a way to prevent a $type property being added when I save my dynamic type values?
When I save this:
new Activity {
Name = "FormFieldDeleted",
Body = new {
MyDeletedFormField(),
MyCompleteForm()
}
}
I get this
<>f__AnonymousType1`2[[MyProject.Domains.Forms.Models.FormField, MyProject.Domains.Forms],[MyProject.Domains.Forms.Entities.FormRegistration, MyProject.Domains.Forms]], MyProject.Api.Forms
But when I try to fetch this saved entity, it crashes with the exception below. I know it's missing a project reference, but I really don't want to add that reference (I don't want to reference an API from a console app). It's better for me to just prevent the $type property.
/usr/local/share/dotnet/dotnet path/MyProject/MyProject/src/MyProject.Tasks.MapActivities/bin/Debug/netcoreapp3.1/MyProject.Tasks.MapActivities.dll
Unhandled exception. System.InvalidOperationException: Could not convert document 31317d58-db9e-4f60-8dee-b8593f3e06c0 to entity of type MyProject.Domains.Core.Entities.Activity
---> Newtonsoft.Json.JsonSerializationException: Error resolving type specified in JSON '<>f__AnonymousType1`2[[MyProject.Domains.Forms.Models.FormField, MyProject.Domains.Forms],[MyProject.Domains.Forms.Entities.FormRegistration, MyProject.Domains.Forms]], MyProject.Api.Forms'. Path 'Body.$type'.
---> Newtonsoft.Json.JsonSerializationException: Could not load assembly 'MyProject.Api.Forms'
....
Yes, there is a way.
You can customize the way serialization works using the following code:
store.Conventions.CustomizeJsonSerializer = serializer =>
{
serializer.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.None;
};
As an example, take a look at the code here : https://dotnetfiddle.net/voJ7US
If you execute the code at the dotnetfiddle, you can see the results here: http://live-test.ravendb.net/studio/index.html#databases/documents?collection=Activities&database=UniqueTestDB
For RavenDB 5 and higher it changed a bit.
var store = DocumentStore
{
Urls = new[] { "your-endpoint" },
Conventions = new DocumentConventions
{
Serialization = new NewtonsoftJsonSerializationConventions
{
CustomizeJsonSerializer = serializer =>
{
serializer.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.None;
}
}
}
}.Initialize();
See https://ravendb.net/docs/article-page/5.0/file-header/migration/client-api/conventions for more information.

Why do I get the "reference not set to an instance of an object?

I am working with the new CosmosDB SDK v3 https://learn.microsoft.com/en-us/azure/cosmos-db/sql-api-sdk-dotnet-standard and a very simple insert, I have verified all the objects are indeed not null and have reasonable values but I still get the error message:
[1/12/2019 10:35:04] System.Private.CoreLib: Exception while executing function: HAPI_HM_Seasons. Microsoft.Azure.Cosmos.Direct: Object reference not set to an instance of an object.
I dont see why this is I must be missing something really basic here but I cant put my finger on it.
The code is as below:
List<SeasonInformation> seasonInformationList = new List<SeasonInformation>();
foreach(JObject document in listOfSeasons)
{
SeasonInformation seasonInformation = new SeasonInformation
{
id = Guid.NewGuid().ToString(),
Brand = brand,
IntegrationSource = source,
DocumentType = Enums.DocumentType.Season,
UpdatedBy = "HAPI_HM_Seasons",
UpdatedDate = DateTime.Now.ToString(),
UpdatedDateUtc = string.Format("{0:yyyy-MM-ddTHH:mm:ss.FFFZ}", DateTime.UtcNow),
OriginalData = document
};
seasonInformationList.Add(seasonInformation);
}
database = cosmosClient.GetDatabase(cosmosDBName);
container = database.GetContainer(cosmosDBCollectionNameRawData);
log.LogInformation(string.Format("HAPI_HM_Seasons BASIC setup done at {0:yyyy-MM-ddTHH:mm:ss.FFFZ}", DateTime.UtcNow));
log.LogInformation(string.Format("HAPI_HM_Seasons import {1} items BEGIN at {0:yyyy-MM-ddTHH:mm:ss.FFFZ}", DateTime.UtcNow, seasonInformationList.Count));
foreach(var season in seasonInformationList)
{
ItemResponse<SeasonInformation> response = await container.CreateItemAsync(season);
}
I have verified that the List is populated and that the season variable in the loop contains the correct data so I am a bit stuck here.
The exception happens in the last foreach loop where I try CreateItemAsync into CosmosDB
As a best practice, you need to use Async method with await in all the Cosmosdb methods just to make sure that they are getting executed and you get the response,
and modify your CreateItemAsync as follows,
ItemResponse<SeasonInformation> response = await container.CreateItemAsync(season, new PartitionKey(season.whatever));
Here is the Sample Repository

Fiddler access nested json to modify

i somehow can´t reach the objects in a nested json. I easily can reach the element test, but how to reach this_month inside "stats"? this is my json:
{"test":"OK","stats":{"this_month":"1653","this_week":"1653"}}
this is my code inside the customrules.cs
var oResponseBody = oSession.GetResponseBodyAsString();
JSON.JSONParseResult oJSON = JSON.JsonDecode(oResponseBody) as JSON.JSONParseResult;
Hashtable oObj = oJSON.JSONObject as Hashtable;
oObj["test"] = "changed";
var modBytes = Fiddler.WebFormats.JSON.JsonEncode(oObj);
// Convert json to bytes, storing the bytes in request body
var mod = System.Text.Encoding.UTF8.GetBytes(modBytes);
oSession.ResponseBody = mod;
As soon as I want to acces this_month in "stats" with this: oObj["stats"]["this_month"] = "changed"; my fiddler get´s errors and crashes.

Calling a web api error in json response object [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 5 years ago.
I am trying to convert a piece of code from a github that was designed for winforms however I am having the following error.
//Retrieve and set a post code value to a variable.
var mPostCode = txtPostCode.Text;
mApiKey = "";
string url =
String.Format("http://pcls1.craftyclicks.co.uk/json/basicaddress?postcode={0}&response=data_formatted&key={1}",
mPostCode, mApiKey);
//Complete XML HTTP Request
WebRequest request = WebRequest.Create(url);
//Complete XML HTTP Response
WebResponse response = request.GetResponse();
//Declare and set a stream reader to read the returned XML
StreamReader reader = new StreamReader(response.GetResponseStream());
// Get the requests json object and convert it to in memory dynamic
// Note: that you are able to convert to a specific object if required.
var jsonResponseObject = JsonConvert.DeserializeObject<dynamic>(reader.ReadToEnd());
// check that there are delivery points
if (jsonResponseObject.thoroughfare_count > 0)
{
//If the node list contains address nodes then move on.
int i = 0;
foreach (var node in jsonResponseObject.delivery_points)
{
ClsAddress address = new ClsAddress()
{
AddressID = i,
AddressLine1 = node.line_1,
AddressLine2 = node.line_2,
County = jsonResponseObject.postal_county,
PostCode = jsonResponseObject.postcode,
Town = jsonResponseObject.town
};
addressList.Add(address);
i++;
}
this.LoadAddressListIntoDropDown();
}
The error is hapening on this line
// check that there are delivery points
if (jsonResponseObject.thoroughfare_count > 0)
Error is
Object reference not set to an instance of an object.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
Source Error:
Line 148: //If the node list contains address nodes then move on.
Line 149: int i = 0;
Line 150: foreach (var node in jsonResponseObject.delivery_points)
Line 151: {
Line 152: ClsAddress address = new ClsAddress()
Now I know this is normally when an object is not intitiated but is that not what the var node does?
Any help be greatly appreciated. I obv edit out my api key for security but it does get past sucesfully.
The var keyword tells the compiler to infer the type of the variable from the rest of the statement. In this case, the inferred type will be dynamic because you are trying to deserialize the stream using JsonConvert.DeserializeObject<dynamic>. But that does not guarantee that the value of the variable will not be null! In fact, if your response stream has no data, then JsonConvert.DeserializeObject will definitely return null. So, if you then try to reference a property on an object that is null, it will throw an exception, which seems to be exactly what is happening here.
My guess is you are getting some kind of error back from the server instead of the response you are expecting. Your code doesn't do any checking for HTTP errors that I can see; it just blindly tries to process the response, assuming it is successful. You should use a web debugging proxy like Fiddler to find out what you are actually getting from the server. Then, you should enhance your code with appropriate error handling and null checks. See What is a NullReferenceException, and how do I fix it? for more information.

WSDL generated service reference returning null

Im have some issues with a service reference to an external source (added it using the supplied wsdl in Visual Studio 2015).
The situation is that the request i run seems to reach the server fine. I also seems to get a response of the expected xml format (added TextWriterTraceListener). But the OutType class i get back in the code (in this case the GetBankCertificateOutType) is always null.
The console application ive built to illustrate is very simple, utilizing the public test account. It looks as follows:
static void Main(string[] args)
{
//instantiates client from the service reference
var client = new PkiServicePortTypeClient();
var time = DateTime.UtcNow;
Random r = new Random();
string reqId = r.Next(100, 999).ToString();
var outType = client.GetBankCertificate(*full params on github*);
//This line will throw nullexception since outType is always null
//BUT a valid response is actually received (although returning aa application statusCode that represents error at this stage)
var response = outType.GetBankCertificateResponse;
}
Ive tried to locate the problem but have been unsuccessful sofar. So wanted to see if someone has some good tip on how to debug this or perhaps has a solution.
I built a complete, minimal, console sample project (including the source wsdl) to illustrtate the issue which is located here.
I've downloaded and inspected your solution, and I found this in trace.log
GetBankCertificateRequest at tribute {http://www.w3.org/XML/1998/namespace}id had invalid value '360817' of type '{http://www .w3.org/2001/XML Schema}ID'
After I played with id value of GetBankCertificateRequest I got back the right value (instead of null).
var outType = client.GetBankCertificate(new GetBankCertificateInType {
RequestHeader = new RequestHeaderType {
SenderId = "360817",
CustomerId = "360817",
RequestId = reqId,
Environment = EnvironmentType.test,
EnvironmentSpecified = true,
InterfaceVersion = "1",
Timestamp = time
},
GetBankCertificateRequest = new GetBankCertificateRequest {
BankRootCertificateSerialNo = "1111110002",
//id = "",
RequestId = reqId,
Timestamp = time
}
});
There is no description for this property according to documentation (PKI service description v2.3.pdf) except some xml type annotation (xml:id). The concrete schema description is missing.

Categories