How to validate JSON objects using Newton JSON and C# - c#

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);
}

Related

Can I get element value in selenium?

I want to get a value from one input in selenium. But I need this value in other project test in the same solution. Can I get this value in this case or I need run both test project at the same time to get it?
This is my variable (I have it in a class project)
public static string strNumeroCotizacion;
I get the value here in a test project called "Cotizacion":
Variables_RW.element = Variables_RW.driver.FindElement(By.XPath("//INPUT[#id='numeroCotizacion']"));
Variables_RW.strNumeroCotizacion = Variables_RW.element.GetAttribute("value").ToString();
And I need use it in this case in other project called "facturacion" in the same solution:
Variables_RW.driver.FindElement(By.XPath("//INPUT[#id='sCotizacion']")).SendKeys("strNumeroCotizacion");
Variables_RW.driver.FindElement(By.XPath("//INPUT[#id='sCotizacion']")).SendKeys(Keys.Enter);
Interesting question. I don't think you can use variable from the different projects.
But you can write the value of that variable in the file when running your project1 and after you can read it in project 2.
It depends on which language you are using in selenium.
This is the Java Solution
To write to the file:
#SuppressWarnings("unchecked")
public void customerDataWrite(String custID, String OrderNum, String Contact) {
// First OrderData
JSONObject createdOrderData = new JSONObject();
createdOrderData.put("customer", custID);
createdOrderData.put("orderName", OrderNum);
createdOrderData.put("contactName", Contact);
// Add order numbers to list
JSONArray OrderDataList = new JSONArray();
OrderDataList.add(createdOrderData);
// Write JSON file
try (FileWriter file = new FileWriter("orderdata.json")) {
file.write(OrderDataList.toJSONString());
file.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
To read from the file:
JSONParser parser = new JSONParser();
try {
Object obj = parser.parse(new FileReader("orderdata.json"));
// Get order object
JSONArray array = (JSONArray) obj;
JSONObject jsonObject = (JSONObject) array.get(0);
// Get order contact name
orderContactName = (String) jsonObject.get("contactName");
System.out.println(orderContactName);
// Get company name
orderCustomerName = (String) jsonObject.get("customer");
System.out.println(orderCustomerName);
// Get order Order name
orderOrderName = (String) jsonObject.get("orderName");
System.out.println(orderOrderName);
}

Cannot deserialize the current JSON array (e.g. [1,2,3]) & {"Unexpected character encountered while parsing value: e. Path '', line 0, position 0."}

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

System.JSON does not throw exception for malformed JSON input

I am new to using .NET System.JSON. Trying to learn, using this sample application.
[DataContract]
internal class Person
{
[DataMember]
internal string name;
[DataMember]
internal int age;
}
String strData = "{ \"Person\": [{\"name\":\"TSR\",\"age\": 4 },{\"name\":\"KV\",\"age\":10}]}";
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(strData));
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Person));
Person jsonArray = (Person)ser.ReadObject(ms) as Person;
I was testing the program by giving a sample input as this. Note the last curley bracket is missing in the input. I was expecting the program to throw some sort of exception but it's not. Is this an expected behavior with System.JSON?
"{ \"Person\": [{\"name\":\"TSR\",\"age\": 4 },{\"name\":\"KV\",\"age\":10}]";
The below input has an extra curley brace at the end. No exception is thrown for this input as well.
"{ \"Person\": [{\"name\":\"TSR\",\"age\": 4 },{\"name\":\"KV\",\"age\":10}]}}";
Tell System.Json to Parse your string to a JsonValue. If it's valid, it will pass - if not, it should throw an exception
try
{
var validJson = JsonValue.Parse(strData);
}
catch (FormatException e)
{
//Invalid Json Format
Console.WriteLine(e);
}
catch (Exception e)
{
//some other exception
}

Invalid JSON primitive when deserializing

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.

Parsing JSON from file takes a lot of time

I have the following piece of code that loads a file with JSON from local folder and then parses it:
async public static void TryLoad(Callback Ok, Action Fail, string key, int offset)
{
try
{
var now = DateTime.Now;
ItemsCache cacheItem;
var folder = ApplicationData.Current.LocalFolder;
var stream = await folder.OpenStreamForReadAsync(key);
using (stream)
{
var result = await new StreamReader(stream).ReadToEndAsync();
Debug.WriteLine("Raw data loaded: " + (DateTime.Now - now).TotalMilliseconds);
cacheItem = JsonConvert.DeserializeObject<ItemsCache>(result);
Debug.WriteLine("Json has been parsed: " + (DateTime.Now - now).TotalMilliseconds);
stream.Close();
}
bool isOK = cacheItem.IsValid(offset);
if (isOK) Ok(cacheItem.Data); else Fail();
}
catch (Exception)
{
Fail();
}
}
And ItemsCache itself:
public class ItemsCache
{
public string Stamp { get; set; }
public JToken Data { get; set; }
public bool IsValid(int ofs)
{
DateTime moment = DateTime.Parse(Stamp);
return (DateTime.Now - moment).TotalSeconds < ofs;
}
}
Output after loading the data twice in a row:
Raw data loaded: 356,7372
Json has been parsed: 855,588
Raw data loaded: 1269,6079
Json has been parsed: 1300,8621
JSON:
{"Stamp":"26.01.2013 20:49:26","Data":[{"id":188357911,"user":123145, ... a few more more key-value pairs}, ... the rest of the objects]}
Thing is, the whole process takes about 750 milliseconds, 150 of them to load a raw data and 600 to parse it using Newtonsoft JSON library. The amount of data itself is small and contains about 20 serialized objects that are essentially a small key-value pairs (Although I've found out I could add a lot more data and it will not affect parsing time much).
Question is if it's normal to take that much time to load data and even more time to parse it? What could I do if it's not normal?

Categories

Resources