C# to XML serialization [duplicate] - c#

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

Related

Saving Binary Data FHIR DB

I am trying to save Binary data to FHIR DB.
This is my method:
public static Patient SavePdfForms(string resource, HttpClientEventHandler messageHandler, string[] pdfForms, Patient patient, FhirClient BinaryBundleClient)
{
Bundle BinaryBundle = new Bundle();
BinaryBundle.Type = Bundle.BundleType.Collection;
try
{
foreach (var item in pdfForms)
{
Binary BinaryData = new Binary();
var bytearray = Encoding.ASCII.GetBytes(item);
BinaryData.Data = bytearray;
BinaryData.ContentType = "application/fhir+json";
var binaryResource = BinaryBundleClient.Create(BinaryData);
BinaryBundle.AddResourceEntry(BinaryData, resource + "/BundleResource/" + binaryResource.Id);
}
}
catch (Exception ex)
{
throw;
}
var bundleId = BinaryBundleClient.Create(BinaryBundle);
patient.Identifier.Add(new Identifier("BinaryBundle", bundleId.Id));
return BinaryBundleClient.Update(patient);
}
The string[] of pdfForms is base64 and for each form I am creating a new binary and adding data and content type. But the line var binaryResource = BinaryBundleClient.Create(BinaryData); throws an error and data is not a valid json. I tried with different content type but that is not working. Any ideas why?
Assuming you are creating a new resource instance in BinaryBundleClient.Create(BinaryData) and the server to store it.
In your case, you directly pass the binary information in Fhirclient.Create(your data)
binaryResource = BinaryBundleClient.Create(BinaryData);
You must mention the type of the resource instance which follows:
Create Fhir client
var client = new FhirClient("http://server.fire.ly");
After Creating FhirClient You have to create a new resource instance. It will be like
var pat = new Patient() { /* set up data */ };
var created_pat = client.Create<Patient>(pat);
this interaction will throw an Exception when things go wrong, in most cases a FhirOperationException. This exception has an Outcome property that contains an OperationOutcome resource, and which you may inspect to find out more information about why the interaction failed. Most FHIR servers will return a human-readable error description in the OperationOutcome to help you out.
Refer here

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
}

project.Models.tableName:The field pvid must be a string or array type with a maximum length of '20'

I encounter exception error below when i try to add a new entry in the database with :
db.patient_visit.Add(pv);
db.SaveChanges();
An exception of type 'System.InvalidOperationException' occurred in project.dll but was not handled in user code
Additional information: project.Models.tableName:The field pvid must be a string or array type with a maximum length of '20'.
Before this, my model is automatically and originally set like below because i did Code-First migration with existing database.
[Key]
[StringLength(20)]
public string pvid { get; set; }
Logically, it looks like it is already in the range. But for the sake of trying, i tried changing it to code below, and did add-migration. Then, in the Up() method, its empty. Does it mean that the modification is not recognized? Because when i tried running the project again, i encountered the same error as above.
[Key]
[MaxLength(20), MinLength(12)]
public string pvid { get; set; }
Then when i put breakpoints at my query, i see that:
InnerException: null
Message: The data reader is incompatible with the specified 'project.Models.tableName'. A member of the type 'columnName', does not have a corresponding column in the data reader with the same name.
Is there something wrong with my query?
ChargeVM objDetails = new ChargeVM();
var query3 = db.Database.SqlQuery<patient_visit>("SELECT MAX(CAST(SUBSTRING(pvid, 3, 10) AS int)) FROM patient_visit");
if (query3 != null)
{
objDetails.pvid = query3.ToString();
objDetails.pvid += 1;
objDetails.pvid = "PV" + objDetails.pvid;
}
patient_visit pv = new patient_visit()
{
pvid = objDetails.pvid,
paid = paid
};
db.patient_visit.Add(pv);
I put a try catch for the db.SaveChanges() to catch any exceptions, and at line "throw raise", the exception error that i mentioned in the first paragraph pops up.
try
{
db.SaveChanges();
}
catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
{
Exception raise = dbEx;
foreach (DbEntityValidationResult validationErrors in dbEx.EntityValidationErrors)
{
foreach (DbValidationError validationError in validationErrors.ValidationErrors)
{
string message = string.Format("{0}:{1}", validationErrors.Entry.Entity.ToString(), validationError.ErrorMessage);
// raise a new exception nesting
// the current instance as InnerException
raise = new InvalidOperationException(message, raise);
}
}
throw raise;
}
Actually i just switched to C# recently and i simply converted my codes from vb.net to C#. I am wondering if it was a problem with the syntax or anything because it was running smoothly previously with vb.net. Could anyone help point it out to me please? I'm new to this.

How to handle variables that is null in JSON

In my JSON file there is an array (rents). In this array there is a varible, serial, which can be null or a string. I loop throug my array (rents) if the serial variable is null i want to continue the loop, but when is it not null i want to save it. But somehow it does not behave like that. The array stop looping when it comes to get "serial".
Here is my code:
public static string sendRequest(string url, string method) {
try
{
// Set reqiued information for api
var httpWebRequest = (HttpWebRequest)WebRequest.Create(main_url + url);
httpWebRequest.ContentType = "application/x-www-form-urlencoded";
httpWebRequest.Headers.Add("Authorization", "Bearer " + Current_Access_Token);
httpWebRequest.Accept = "application/json;v=1";
httpWebRequest.Method = method;
// Get adn return responses
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
string respStr = new StreamReader(httpResponse.GetResponseStream()).ReadToEnd();
return respStr;
}
catch (Exception e)
{
MessageBox.Show("No responses");
}
return "";
}
public static void GetRentGames()
{
string resp = sendRequest("api.php/currentCustomer/rents", "GET");
JObject jObject = JObject.Parse(resp);
JArray Juser = (JArray)jObject["response"]["data"]["rents"];
//Console.WriteLine(resp);
foreach(var i in Juser)
{
var matchGame = ApiConnector.rentGame.Find(x => x.name == i["item"]["name"].ToString());
if(matchGame == null)
{
//name and id works just fine. it is the serial i can't get, and I think because the serial is null?
Console.WriteLine(i["serial"].ToString());
var Game = new RentGame(i["item"]["name"].ToString(), i["id"].ToString(), i["serial"].ToString());
rentGame.Add(Game);
Console.WriteLine("Add rent game " + Game.name);
}
}
}
JSON file- first index:
"response":{
"code":200,
"status":"success",
"data":{
"rents":[
{
"id":"34414",
"start_date":"2015-12-08",
"download_url":null,
"serial":null, ...
To determine if the value is null, do this:
if(matchGame == null)
{
// Only do this if the serial is not null
if (i["serial"].Type != JTokenType.Null)
{
Console.WriteLine(i["serial"].ToString());
var Game = new RentGame(i["item"]["name"].ToString(), i["id"].ToString(), i["serial"].ToString());
rentGame.Add(Game);
Console.WriteLine("Add rent game " + Game.name);
}
The difficulty is that the JSON parser does not convert null objects in JSON to null objects in C#. (why??!?) Instead, it makes it a JToken object, with a "Type" of "Null".
You can see this in the debugger window like this:
The "Value" column shows as {} which doesn't mean much to me. The "Type" column shows that it is a JToken object. So what is a JToken? Well, if you expand, you see it has lots of properties: Next, Last, Parent, Path, ... Okay, so that explains why they didn't make it a real null. They want to track all these other things. It looks like you could use the "HasValues" property or the "Type" property to see if the thing is null.
Well,
i["serial"].ToString()
will probably throw exception if i["serial"] == null.
The simplest solution would be to just check if it's not null and process it somehow afterwards.

user defined Error collection in Visual C#

I want to write an user defined error collection class which should collect all the Error's. When we validate an entity object if there is no error it should go and save to the Database. if Error there it should display it.
now i have wrote the class it collects the error and displays it successfully but when there is two identical error the class throws an exception.
(i use error-code for the error. the value for the error-code is in resx file from where the display method will take the value and display it. Display works perfectly)
//The code where it collects Error
if (objdepartment.Departmentname == null)
{
ErrorCollection.AddErrors("A1001","Department Name");
}
if (objdepartment.Departmentcode == null)
{
ErrorCollection.AddErrors("A1001","Department code");
}
//In the Errorcollection
public class ErrorCollection
{
static Dictionary<string,List<string>> ErrorCodes;
private ErrorCollection() { }
public static void AddErrors(string eCode,params string[] dataItem)
{
if (ErrorCodes == null)
{
ErrorCodes = new Dictionary<string, List<string>>();
}
List<String> lsDataItem = new List<String>();
foreach (string strD in dataItem)
lsDataItem.Add(strD);
ErrorCodes.Add(eCode, lsDataItem);
}
public static string DisplayErrors()
{
string ErrorMessage;
//string Key;
ErrorMessage = String.Empty;
if (ErrorCodes != null)
{
string Filepath= "D:\\Services\\ErrorCollection\\";
//Read Errors- Language Specsific message from resx file.
ResourceManager rm = ResourceManager.CreateFileBasedResourceManager("ErrorMessages", Filepath, null);
StringBuilder sb = new StringBuilder();
foreach (string error in ErrorCodes.Keys)
{
List<string> list = ErrorCodes[error];
if (error == "A0000")
{
sb.Append("System Exception : " + list[0]);
}
else
{
sb.Append(rm.GetString(error) + "\nBreak\n");
}
for (int counter = 0; counter < list.Count; counter++)
{
sb.Replace("{A}", list[counter]);
}
}
ErrorMessage = sb.ToString();
}
return ErrorMessage;
}
}
now when there is two common error. then the code shows an exception like "datakey already exist" in the line " ErrorCodes.Add(eCode, lsDataItem);" (the italic part where the exception throwed)
Well for one thing, having this statically is a terrible idea. You should create an instance of ErrorCollection to add the errors to IMO, and make the variable an instance variable instead of static.
Then you need to take a different approach within AddErrors, presumably adding all the new items if the key already exists. Something like this:
List<string> currentItems;
if (!ErrorCodes.TryGetValue(eCode, out currentItems))
{
currentItems = new List<string>);
ErrorCodes[eCode] = currentItems;
}
currentItems.AddRange(dataItem);
You are adding "A1001" twice as a key in a dictionary. That simply isn't allowed. However, more urgently - why is that dictionary static? That means that everything, anywhere, shares that error collection.
Suggestions:
make that not static (that is a bad idea - also, it isn't synchronized)
check for existence of the key, and react accordingly:
if(ErrorCodes.ContainsKey(eCode)) ErrorCodes[eCode].AddRange(lsDataItem);
else ErrorCodes.Add(eCode, lsDataItem);
As an aside, you might also consider implementing IDataErrorInfo, which is a built-in standard wrapper for this type of functionality, and will provide support for your error collection to work with a few standard APIs. But don't rush into this until you need it ;p

Categories

Resources