I am new to Tests in Visual Studio , normally I always used proper test tool in order to validate the json file and its data
I am stuck how to validate JSON objects , data inside in the JSON File
through following code I am Reading the JSON file , further i would like to validate the JSON objects
here is my readJSON method which reads the file but now I would like to either check if it contains any given specific value let say I would like to check if it contains the "Details" and its value "XYZG" or not
I tried to convert JSON into ToString() and then user .count method but it gives me the value 0 in output so I removed that ToString() block from the code
JSON Data
{
"Details":"XYZG",
"City":"Tokyo",
"Id":"ATOOO",
"Name":"Johny"
}
read json method
public string ReadMyJsonFile(String FilePath)
{
string storeValue = "";
using (StreamReader readerobject = new StreamReader(FilePath))
{
string jsonString = readerobject.ReadToEnd();
}
return storeValue;
}
TestMethod
public async TaskTest()
{
var json = ReadMyJsonFile(#"FilePath/Test.json");
var testobject = JsonConvert.DeserializeObject<JObject>(json);
Console.WriteLine(testobject);
try
{
if (testobject.SelectTokens("$..Id").Any(t => t.Value<string>() == "$..Id"))
{
Console.WriteLine("\n \n value exist");
}
}
catch (Exception ex)
{
Console.WriteLine("error keyword");
}
}
´´´
I am kinda stuck with the validation part of my json data
you better print a json string, not a JObject
try
{
var json = ReadMyJsonFile(#"FilePath/Test.json");
if (!string.IsNullOrEmpty(json))
{
Console.WriteLine("json file exists \n");
Console.WriteLine(json);
}
else
{
Console.WriteLine("json file not exists \n");
return;
}
var testObject = JObject.Parse(json);
if (!string.IsNullOrEmpty((string)testObject["Id"]))
{
Console.WriteLine("\n Id value exists");
Console.WriteLine((string)testObject["Id"]);
}
else
Console.WriteLine("\n Id value doesnt exist");
}
catch (Exception ex)
{
Console.WriteLine("error "+ex.Message);
}
I saw plenty of similar questions but I really could not work my way around this time. What I am having issues with, is populating a view with the content of a certain object in order to update it. When I press on "Edit", in theory, all the fields should be automatically inserted. What have I tried so far?
public ActionResult CreateOrEdit(int id = 0)
{
if (id==0)
return View(new Recipe());
else
{
HttpResponseMessage response = GlobalVariables.client.GetAsync(id.ToString()).Result;
//return ViewJsonConvert.DeserializeObject<IList<Recipe>>(response.ToString()));
return View(response.Content.ReadAsAsync<Recipe>().Result);
//return View(new Recipe());
}
}
return View(response.Content.ReadAsAsync<Recipe>().Result); - when using this as a return, I am getting this error:
Cannot deserialize the current JSON array (e.g. [1,2,3])
After looking the problem up, I tried the following:
return View(JsonConvert.DeserializeObject<IList<Recipe>>(response.ToString())); which got me this error:
{"Unexpected character encountered while parsing value: s. Path '', line 0, position 0."}
And at this point I am stuck. I would assume that it is trying to deserialize the following JSON:
{
"id": 5002,
"name": "Test Recipe",
"recipeLink": "testlink",
"category1Id": 7757,
"category2Id": 7758,
"category3Id": 7759,
"category4Id": 7760,
"recipeById": 1,
"totalTime": 30,
"totalTimeUnitId": 1,
"activeTime": 20,
"activeTimeUnitId": 1,
"instructions": "Test Instructions",
"sourceKey": "Test SK",
"recipeBy": "TestPerson",
"insertedAtUtc": "2019-09-04T12:18:48.0466667",
"isVerified": 1,
"numPersons": 5
}
If needed, here is the code from the API Controller that is handling the operations.
[Route("v1/recipe/{id}")]
[HttpPut()]
public IActionResult UpdateList(int id, [FromBody]Recipe recipe)
{
var category1Id = 7757;
var category2Id = 7758;
var category3Id = 7759;
var category4Id = 7760;
var isVerified = 0;
var recipeBy = "TestPerson";
var recipeById = 1;
try
{
if (recipe == null) throw new ArgumentException("No data specified");
//if (newData.Name == null) throw new ArgumentException("No name specified");
using (var con = _connFactory())
{
con.Execute(#"UPDATE dbo.Recipe SET Name=#name, RecipeLink=#recipeLink, Category1Id=#category1Id ,Category2Id=#category2Id,
Category3Id=#category3Id, Category4Id=#category4Id, RecipeById=#recipeById, TotalTime=#totalTime, TotalTimeUnitId=#totalTimeUnitId,
ActiveTime=#activeTime, ActiveTimeUnitId=#activeTimeUnitId, Instructions=#instructions, SourceKey=#sourceKey, RecipeBy=#recipeBy,
InsertedAtUtc=getutcdate(), IsVerified=#isVerified, NumPersons=#numPersons WHERE Id=#id",
new
{
id,
recipe.name,
recipe.recipeLink,
category1Id,
category2Id,
category3Id,
category4Id,
recipeById,
recipe.totalTime,
recipe.totalTimeUnitId,
recipe.activeTime,
recipe.activeTimeUnitId,
recipe.instructions,
recipe.sourceKey,
recipeBy,
isVerified,
recipe.numPersons
});
}
return Ok(recipe);
}
catch (Exception exc)
{
return BadRequest();
}
}
I believe your response string starts with the Unicode Byte Order Mark character.
For example...
using Newtonsoft.Json;
namespace StackOverflow
{
class MainClass
{
public static void Main(string[] args)
{
var json = #"{
'id': 5002,
'name': 'Test Recipe',
'recipeLink': 'testlink',
'category1Id': 7757,
'category2Id': 7758,
'category3Id': 7759,
'category4Id': 7760,
'recipeById': 1,
'totalTime': 30,
'totalTimeUnitId': 1,
'activeTime': 20,
'activeTimeUnitId': 1,
'instructions': 'Test Instructions',
'sourceKey': 'Test SK',
'recipeBy': 'TestPerson',
'insertedAtUtc': '2019-09-04T12:18:48.0466667',
'isVerified': 1,
'numPersons': 5
}".Replace("'", "\"");
//This works...
var deserialized1 = JsonConvert.DeserializeObject(json);
//Prepend a U+FEFF Byte Order Mark character...
json = "\uFEFF" + json;
//This fails with error:
//Newtonsoft.Json.JsonReaderException:
//Unexpected character encountered while parsing value: . Path '', line 0, position 0.
var deserialized2 = JsonConvert.DeserializeObject(json);
}
}
}
I wonder if you have a string value where it is expecting an integer, i.e. a character which is not wrapped in quotation marks.
Could you debug to the line JsonConvert.DeserializeObject<IList<Recipe>>(response.ToString())); in Visual Studio and then inspect the contents of "response" in the locals window and post a screenshot to help diagnose the issue?
Edit in response to comment:
Try adding these steps in before the return, then see what is contained in the temp variable:
string temp = response.Content.ReadAsAsync<string>().Result;
It will be interesting to see what this holds, maybe then it will show why the data cannot be parsed into a Recipe object.
Further edit
OK, instead of that line that won't execute try adding this code:
Stream receiveStream = response.GetResponseStream();
StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
var temporaryData = readStream.ReadToEnd();
See if that will execute and then inspect the contents of tempoararyData variable.
Edit 3
OK great we can see the data now. I believe the issue is it is coming through as a JSON array and you're trying to deserialize a singular version. I made this demo app to illustrate:
namespace ConsoleApp3
{
class Program
{
static void Main(string[] args)
{
string data = "[{\"Id\":5002,\"Name\":\"Test Recipe\"}]";
string data2 = "{\"Id\":5002,\"Name\":\"Test Recipe\"}";
//This throws an exception
//DataClass account = JsonConvert.DeserializeObject<DataClass>(data);
//This works
DataClass account2 = JsonConvert.DeserializeObject<DataClass>(data2);
//This also works
DataClass[] account3 = JsonConvert.DeserializeObject<DataClass[]>(data);
}
}
class DataClass
{
public int Id { get; set; }
public string Name { get; set; }
}
}
I believe if you change your code to deserialize an array i.e. DeserializeObject<IList<Recipe[]>> hopefully it will work
This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 4 years ago.
The following code is throwing an exception called "Object reference not set to an instance of an object." suggest required changes
public List<WorkspaceRootObject> wrObj=null;
public RootObject rtObj=new RootObject();
Hashtable ht = new Hashtable();
Dictionary<int, Object> d = new Dictionary<int, Object>();
string contextUrl = txtRegServerLocation.Text + "/servlet/rest/v1/contexts";
Console.WriteLine("Url is:\n" + contextUrl);
HttpWebRequest contextReq = (HttpWebRequest)WebRequest.Create(contextUrl);
NetworkCredential ncr = new NetworkCredential("testuser1", "testuser1");
CredentialCache creCache = new CredentialCache();
creCache.Add(new Uri(contextUrl), "Basic", ncr);
contextReq.Credentials = creCache;
HttpWebResponse contextRes = (HttpWebResponse)contextReq.GetResponse();
Stream str = contextRes.GetResponseStream();
StreamReader strReader = new StreamReader(str);
string finalContextRes = strReader.ReadToEnd();
Console.WriteLine("response is...\n" + finalContextRes);
//Deserialzing Json
rtObj = JsonConvert.DeserializeObject<RootObject>(finalContextRes);
foreach (Item i in rtObj.items)
{
// Console.WriteLine("{0}",i.id);
string curId = i.id;
showWorkSpace(curId);
}
insertRecordInTable();
//DataGridViewRow row = new DataGridViewRow();
//erverDetails.Rows.Add(imageList1.Images[0], txtRegServerName.Text,txtRegServerLocation.Text);
}
else
{
MessageBox.Show("Invalid Url please provide full url");
}
}
catch (WebException ex)
{
using (Stream stream = (Stream)ex.Response.GetResponseStream())
{
using (var reader = new StreamReader(stream))
{
Console.WriteLine(reader.ReadToEnd());
}
}
}
Catch block is throwing this exception System.NullReferenceException was unhandled ?
Thoughts
Looking at your code, although there are lots of improvements and error checking that can be done, and a few places that could lead to null exceptions, the most likely (especially if it is repeating) is the fact that JsonConvert.DeserializeObject<T>() will return null if the string does not match the object type T or is badly formatted.
Without more information such as the line of error this crashed on and the RootObject code and the string returned from string finalContextRes = strReader.ReadToEnd(); it is impossible to answer in any more detail or confidence.
Proposed Answer
Without further details, it is save to assume your issue is these lines:
rtObj = JsonConvert.DeserializeObject<RootObject>(finalContextRes);
foreach (Item i in rtObj.items)
Because rtObj is null (due to JSON string not matching the RootObject model, the rtObj.items is the position that throws the null exception.
To fix this you need to check the JSON string against your root object class and ensure they match. You can paste your JSON string here and see if your class matches up as expected.
I would also highly recommend adding error checking and exception catching where exceptions are known. So at least do if (rtObj == null) { Console.WriteLine("Failed to deserialiez root"); return; }, and then for places that could throw exceptions wrap them in try/catch blocks with specific error messages and handling
Alright, so having this issue when I try to run my application:
Invalid JSON primitive: .
public static void ReloadConfig()
{
if (!File.Exists("config.cfg"))
{
StringBuilder sb = new StringBuilder();
sb.Append("{\r\n");
sb.Append("\"Admins\":[76561198214617172],\r\n");
sb.Append("\"Chatty\":false,\r\n");
sb.Append("}");
File.WriteAllText("config.cfg", sb.ToString());
}
try
{
JavaScriptSerializer jss = new JavaScriptSerializer();
config = jss.Deserialize<Roles>(File.ReadAllText("config.cfg"));
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.ReadKey();
ReloadConfig();
}
}
And this is how the config looks like when it's generated:
{
"Admins":[76561198214617172],
"Chatty":false,
}
As from my error message I would assume it says I have a space in my config, but I do not have that.
And if that matters I use System.Web.Script.Serialization.
You have an errant comma in your output after false:
{
"Admins":[76561198214617172],
"Chatty":false,
}
Should be:
{
"Admins":[76561198214617172],
"Chatty":false
}
You need to remove the comma after false:
{
"Admins":[76561198214617172],
"Chatty":false
}
I used JSONLint to validate your JSON, there are many other online JSON validators.
I have a method parsing a file. However, this parsing could fail anytime, depending on various conditions (not-so-cautious user playing with the file, for example).
public string ParseDatFile(string datFile)
{
string[] deezLines = File.ReadAllLines(datFile);
// We're searching for an essential data inside the file.
bool daEssentialDataFound = false;
foreach (string datLine in deezLines)
{
if (datLine.Contains("daEssentialData"))
{
daEssentialDataFound = true;
break;
}
}
if (!daEssentialDataFound)
throw new WhatShouldIThrowException("yo dood where's da essential data in " + datFile + "?");
DoStuffWith(deezLines);
}
Is there an exception I could use in such a scenario? I thought about:
FormatException: not really clear about the issue,
Custom exception: I do not have any special treatment for the exception I'm throwing, so I'd rather avoid using a custom exception, even though that's always a way to settle things down.
FileFormatException should be fine :
The exception that is thrown when an input file or a data stream that
is supposed to conform to a certain file format specification is
malformed.
You can optionally provide the uri and a descriptive error message.
If you don't want to reference WindowsBase then you may create your own exception specific to your format. Based on the fact there is an XmlException thrown by XmlReader.Read.
I would throw a custom exception since that increases readability and allows to catch that specifc exception:
public class InvalidFileFormatException : System.FormatException
{
public InvalidFileFormatException(string exText) : base(exText) { }
}
// you could even provide an exception if a single line has an invalid format
public class SpecificLineErrorException : InvalidFileFormatException
{
public string Line { get; set; }
public SpecificLineErrorException(string exText, string line) : base(exText)
{
this.Line = line;
}
}
Now your method can look like(also linqified it a little bit:
public string ParseDatFile(string datFile)
{
string[] deezLines = File.ReadAllLines(datFile);
if(!deezLines.Any(l => l.Contains("daEssentialData")))
throw new InvalidFileFormatException("yo dood where's da essential data in " + datFile + "?");
DoStuffWith(deezLines);
}