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.
Related
I built a login/register system, and I want that when you create a username it checks if email exists, it works fine and it shows the message box "Email exists", but when it is a new user and there is no email that exists, it crashes.
Here is the exception message:
(System.NullReferenceException) Message=The object reference was not set to an object instance
Code:
FirebaseResponse response = await client.GetTaskAsync("Information/" + Emailtextbox.TextName);
Data result = response.ResultAs<Data>();
if (Emailtextbox.TextName == result.Email)
{
MessageBox.Show("Email exists");
} else
{
var data = new Data
{
Email = Emailtextbox.TextName,
Fullname = Fullnametextbox.TextName,
Password = EncryptSHA.GetShaData(PasswordTextbox.TextName)
}
};
Updating this based on the screenshot of the error as well as the information provided in the following comments.
It looks like your error has to do with what's being returned from your client.GetTaskAsync("Information/" + Emailtextbox.Textname); call.
My recommendation would be to try and understand what it is you're receiving from that call (what's stored in your response object). With the latest screenshot I see that the Body is null, and that might be part of the problem. Try expanding what you see in the Response object in your response and see if you're even receiving any kind of data you can use and go from there.
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?
ITestCaseResult has a property "ErrorMessage"
The ErrorMessage property has a max size of 527bytes, which is not enough to store weighty Exception structures and unfortunately does not seem to have an appropriate Exception property to store one in.
My question is, when a test fails, how do you get the StackTrace? I know its available because the GUI can pull it up in Visual Studio
And as you can see the ErrorMessage associated with a ITestCaseResult is cut short. (If you zoom with your browser the image regains its clarity.)
I found a possible lead in the RunInfo object :
http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.common.runinfo.aspx.
It has an proper exception structure, and seems to be associated with a run, but I can't connect the dots between a ITestCaseResult and a RunInfo Object. I might be barking up the wrong tree.
I think Visual Studio gets this info from the TRX file which it stores as an attachment to the test run.
I got the attachment as follows:
TfsTeamProjectCollection tfsCollection = new TfsTeamProjectCollection(new Uri("http://tfsserver:8080/tfs/CTS"));
ITestManagementService tfsStore = tfsCollection.GetService<ITestManagementService>();
ITestManagementTeamProject tcmProject = tfsStore.GetTeamProject("MyProject");
// Get Test Run Data by Build
ITestRun thisTestRun = tcmProject.TestRuns.ByBuild(new Uri("vstfs:///Build/Build/" + buildnum)).First();
foreach (ITestAttachment attachment in thisTestRun.Attachments)
{
if (attachment.AttachmentType == AttachmentTypes.TrxTmiTestRunSummary)
{
WebRequest request = HttpWebRequest.Create(attachment.Uri);
request.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
WebResponse response = request.GetResponse();
using (System.IO.Stream responseStream = response.GetResponseStream())
{
System.IO.StreamReader reader = new System.IO.StreamReader(responseStream);
trxFile.Load(reader);
}
break;
}
}
And then to get the stack trace for a named test I did the following:
XmlNamespaceManager nsmgr = new XmlNamespaceManager(trxFile.NameTable);
nsmgr.AddNamespace("vstt", "http://microsoft.com/schemas/VisualStudio/TeamTest/2010");
// get result node for this testcase from trx file
XmlNode node =
trxFile.SelectSingleNode(
"//vstt:UnitTestResult[#testName=\"SourceWorkflowAsSvcWhenErrorConvertingFile\"]/vstt:Output/vstt:ErrorInfo",
nsmgr);
if (node != null)
{
Console.WriteLine("Stack Trace: " + node.InnerText);
}
I used this reference to get the code for getting attachment: http://social.msdn.microsoft.com/Forums/vstudio/en-US/7fecbac7-7c42-485f-9dd2-5bcb4e71fc39/retrieving-trx-file-stored-in-tfs-for-a-test
Using: Drive v2: 1.5.0.99 Beta, .NET Framework: 4.5
The authentication takes place properly (using impersonation) - via service account (AssertionFlowClient).
Access token is obtained. Service account has been granted domain wide privileges
I am able to get the parent folder - ID (strRootFolder) via Service.Files.List();
byte[] byteArray = System.IO.File.ReadAllBytes(FileName);
Google.Apis.Drive.v2.Data.File flUpload = new Google.Apis.Drive.v2.Data.File();
flUpload.Title = Title;
flUpload.Description = Description;
flUpload.MimeType = MimeType;
flUpload.Parents = new List<ParentReference>() { new ParentReference() { Id = strRootFolder } };
Google.Apis.Drive.v2.FilesResource.InsertMediaUpload drvRequest = drvService.Files.Insert(flUpload, new System.IO.MemoryStream(byteArray), "text/plain");
drvRequest.Upload();
However Upload method does not send any request. No exception is thrown. Fiddler trace shows no request has been sent and hence request.responsebody is always null.
Am I missing something ?
If some exception occur during the upload, the return object (IUploadProgress) should contain the exception (take a look at the Exception property).
Please check what is the exception.
You should also consider using UploadAsync which doesn't block your code (but first you should understand what is the exception)
You should look into Exception from your upload, that will give you a better idea of the actual problem.
Sample code:
var progress = request.Upload();
if (progress.Exception != null)
{
//Log execption, or break here to debug
YourLoggingProvider.Log(progress.Exception.Message.ToString());
}
I'm trying to add an attachment to a list item I just created on a sharepoint server using CAML. The code below is simplified (for example the path is normally a variable and the 2nd field (the item id, here 16847) is normally the id I get back from my insert statement in CAML).
This is my code:
String desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
String savePath = desktopPath + #"\" + "tutorials.txt";
byte[] data = GetData(savePath);
lists.AddAttachment("Tasks", "16847", "tutorials.txt", data);
I'm getting this error:
Unable to update the security according your changes. The following exception occurred during ItemUpdating: Object reference not set to an instance of an object.
See Event Viewer for more information.0x81020089
getdata is a method which converts the file on my desktop to a byte[]. data is not empty and it looks okay.
Other than that Tasks is the List needed and 16847 is the task id in which to add the attachment.
Most of the info I can find is about a different error: the index out of range exception (like on the msdn page: http://msdn.microsoft.com/en-us/library/lists.lists.addattachment(v=office.12).aspx).
I've also tried a http put (unauthorized access, obviously) and the copy service (I can post this code if we can't find the solution to the simpler way above).
Can anyone tell me what is wrong?
EDIT 1:
private dcp.Lists lists = new dcp.Lists();
lists.Credentials = System.Net.CredentialCache.DefaultCredentials;
lists.Url = Values.SERVERADDRESS + "/_vti_bin/lists.asmx";
This initializes the connection to our web service. It works perfectly fine for updates, inserts...
GetData code:
private byte[] GetData(String savePath)
{
byte[] contents;
using (FileStream fStream = File.OpenRead(savePath))
{
contents = new byte[fStream.Length];
sFileName = fStream.Name;
fStream.Read(contents, 0, Convert.ToInt32(fStream.Length));
}
return contents;
}
EDIT 2:
Note that the following does work (I get a correct list of existing attachments from the task):
XmlNode ndAttach = lists.GetAttachmentCollection("Tasks", "16847");
MessageBox.Show(ndAttach.OuterXml);
And the following doesn't (same error as for the AddAttachment method):
lists.DeleteAttachment("Tasks", "16847", ndAttach.ChildNodes[0].InnerText);
Whereas I'm quite certain this should work since it does exactly the same as the example code on msdn: http://msdn.microsoft.com/en-us/library/lists.lists.deleteattachment(v=office.12).aspx
The code above is fine, the error occured on our server. When adding an attachment, no contenttype is given in the xml. This was programmed to throw an error because we've always used this method to update and add new items. So we removed the contenttype out of the underlying code and it works like a charm.