Object reference not set to an instance of an object - c#

I get an object reference not set to an instance of an object error in this program. Beginner in selenium so wanted to try opening a browser through xmlreader. I have the xmlreader code and openurl(simply open a google page) in the local library. I want to call these methods in the [setup] and [test] by creating an instance. Any help appreciated.
namespace ClassLibrary1
{
[TestFixture]
public class Class1
{
IWebDriver driver = null;
LocalLib localLib;
[SetUp]
public void openBrowser()
{
localLib = new LocalLib(driver);
localLib.StartDriverUsingXMLReader();
}
[Test]
public void url()
{
localLib.openUrl();
}
}
public class LocalLib
{
private IWebDriver driver = null;
public LocalLib(IWebDriver _driver)
{
this.driver = _driver;
}
public IWebDriver StartDriverUsingXMLReader()
{
try
{
XmlReader reader = XmlReader.Create(#"C:\Users\XXXXX\Desktop\XML.xml");
while (reader.Read())
{
if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "settings"))
{
if (reader.HasAttributes)
{
string parentBrowser = reader.GetAttribute("browser");
if (parentBrowser.ToLower().Equals("Firefox".ToLower()))
{
driver = new FirefoxDriver();
}
else if (parentBrowser.ToLower().Equals("googlechrome".ToLower()))
{
driver = new ChromeDriver(#"C:\chromedriver2_win32_0.8");
}
else if (parentBrowser.ToLower().Equals("Iexplore".ToLower()))
{
driver = new InternetExplorerDriver(#"C:\IEDriverServer_x64_2.32.3");
}
}
}
} return driver;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
throw;
}
}
public void openUrl()
{
driver.Navigate().GoToUrl("www.google.com");
}
}
}
Error:
Object reference not set to an instance of an object.
at ClassLibrary1.LocalLib.StartDriverUsingXMLReader() in C:\Users\XXXX\XML test project\Class1.cs:line 52
Line 52:
string parentBrowser = reader.GetAttribute("browser");
Xml file info
<?xml version="1.0" encoding="utf-8" ?>
<settings>
<!--browser info-->
<settings browser="firefox"/>
</settings>

Double check the contents of the XML file with a working example.
Try using this as the contents of the XML.
<?xml version="1.0" encoding="utf-8" ?>
<!--browser info-->
<settings browser="firefox"/>
If you want to add more information you shoud add more attributes to the settings node, like this:
<?xml version="1.0" encoding="utf-8" ?>
<settings browser="firefox" username="abcd#yahoo.com" password="abcd" implicitWait="3" explicitWait="3"/>
Here you have a settings node, with the browser, username, password, implicitWait and explicitWait attributes.
Then from the C# code you can then read each attribute in the same way that you a already reading the browser attribute:
string parentBrowser = reader.GetAttribute("browser");
string username = reader.GetAttribute("username");
string password = reader.GetAttribute("password");
string implicitWait = reader.GetAttribute("implicitWait");
string explicitWait = reader.GetAttribute("explicitWait");
Notice that the attributes will be read as strings and if you need them to be integers you will need to convert them with something like this:
int implicitWait = int.Parse(reader.GetAttribute("implicitWait"));

Confirm whether or not your XML file has a browser attribute. If it does not, or it's an empty string, GetAttribute will return null and you'll get a NullReferenceException on the next line when you attempt to call ToLower on parentBrowser. The other potential problem would be that reader is null but I think it would have thrown earlier on if that were the case.
By the way, NullReferenceExceptions are among the most common runtime errors in C# code. You should have a look at other similar questions because the problem is always the same, you have some reference type that you try to use the . operator on when it is null. Figuring out why it is null and preventing that or adding checks prior to using the . operator always solves the problem.

Related

How to make serialized data compact?

i wrote an application which is a custom console that allows execution of various commands. One of the commands allows serialization of data. The input data is a string, which is a list of comma separated values.
My question is - how to make the serialized data compact as much as possible?
The serialization format is not important for me.
Here is the command's code:
using CustomConsole.Common;
using System.IO;
using System.Xml.Serialization;
using System;
namespace Shell_Commander.Commands
{
public class SerializeCommand : ICommand
{
private string _serializeCommandName = "serialize";
public string Name { get { return this._serializeCommandName; } set { _serializeCommandName = value; } }
public string Execute(string parameters)
{
try
{
var splittedParameters = parameters.Split(" ");
var dataToSerialize = splittedParameters[0].Split(",");
var pathTofile = splittedParameters[1].Replace(#"\", #"\\");
XmlSerializer serializer = new XmlSerializer(dataToSerialize.GetType());
using (StreamWriter writer = new StreamWriter(pathTofile))
{
serializer.Serialize(writer, dataToSerialize);
var length = new FileInfo(pathTofile).Length;
Console.WriteLine($"Wrote file to: {pathTofile}");
return length.ToString();
}
}
catch (Exception e)
{
Console.WriteLine(e);
return "0";
}
}
}
}
The command accepts 2 parameters:
Data to serialize
File path (in order to save the serialized data).
Example - for the "1,2,4" input, the following file will be saved:
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<string>1</string>
<string>2</string>
<string>4</string>
</ArrayOfString>
EDIT:
I want my command to be able to serialize also complex objects in the future, so writing the string as is to the file is not a solution.
I want to use only standard serialization methods and formats.

Using Same browser type from a single file for multiple projects in Selenium C#

I am trying to pass the Browser Type for 45 projects from a single place using Parallel.RunSettings file and adding this file under Test Settings in Visual Studio.
But the value is not being read with NullReferenceException.
Am I missing any step?
Currently we are passing browser type for each project in their respective app.config file but I want to do it from one single place.
Here is my code:
Parallel.runsettings
<?xml version="1.0" encoding="utf-8"?>
<RunSettings>
<RunConfiguration>
<MaxCpuCount>4</MaxCpuCount>
</RunConfiguration>
<TestRunParameters>
<Parameter name="browsertype" value="Firefox" />
</TestRunParameters>
</RunSettings>
Code to Fetch the value:
public string GetBrowser
{
get
{
var value =Convert.ToString(testContext.Properties["browsertype"]);
return value;
}
}
//Code To Launch the browser:
if (config.GetBrowser == "Firefox")
{
this.WebDriver = new FirefoxDriver();
}
else if (config.GetBrowser == "Chrome")
{
var chromeOptions = new ChromeOptions();
chromeOptions.AddAdditionalCapability("useAutomationExtension", false);
this.WebDriver = new ChromeDriver(chromeOptions);
}
else if (config.GetBrowser == "IE")
{
this.WebDriver = new InternetExplorerDriver();
}

C# Rotate Images From Url's Stored in XML File

Im trying to monetize a free winform app, basically I want to have 10 images rotate every 5 min in a picture box. I dont want to hard code these into the app, but store the image url's on my server in a xml file.
this is the xml on my server
<?xml version="1.0" encoding="utf-8"?>
<Advertisements>
<Ad>
<ImageUrl1>http://example.com/example.jpg</ImageUrl1>
<url1>http://example.com</url1>
</Ad>
<Ad>
<ImageUrl2>http://example.com/example2.jpg</ImageUrl2>
<url2>http://example.com</url2>
</Ad>
</Advertisements>
Im stuck on how to rotate through each node and display the image for 5 min
Tried to find a decent example, but most are for ASP.net
This is the code in my app:
XmlTextReader reader = null;
try {
string xmlURL = "http://example.com/ads.xml";
reader = new XmlTextReader(xmlURL);
reader.MoveToContent();
string elementName = "";
if ((reader.NodeType == XmlNodeType.Element) &&
(reader.Name == "Advertisements")) {
while (reader.Read()) {
if (reader.NodeType == XmlNodeType.Element)
elementName = reader.Name;
else {
if ((reader.NodeType == XmlNodeType.Text) &&
(reader.HasValue)) {
switch (elementName)
{
case "ImageUrl1":
picturebox.ImageLocation=reader.Value);
break;
}
}
}
}
}
}
catch (Exception) {
}
finally {
if (reader != null) reader.Close();
}
Your current code uses the older XmlReader approach to parsing XML manually. This is usually complex and tricky to get right. If you are using .NET version 3.5 or higher, you can use LINQ to XML for a cleaner interface to working with XML.
The approach I would take to solving your problem is this:
On app start-up, load the list of Advertisements from the server and cache the result in a static variable
Shuffle the list once (after loading it), so you can just keep iterating over the list when picking a new Ad to show (no need to randomize)
Use a Timer instance to rotate the image every 5 minutes
Here is some sample C# code using LINQ to XML for loading your XML data:
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace StackOverflowQ21588436
{
public class Example
{
private const string XML =
#"<?xml version=""1.0"" encoding=""utf-8""?>
<Advertisements>
<Ad>
<ImageUrl>http://example.com/example.jpg</ImageUrl>
<url>http://example.com</url>
</Ad>
<Ad>
<ImageUrl>http://example.com/example2.jpg</ImageUrl>
<url>http://example.com/2.html</url>
</Ad>
</Advertisements>";
public static IList<Advertisement> GetAdvertisements()
{
var xmlDocument = XDocument.Parse(XML); // or XDocument.Load(url)
var adXmlNodes = xmlDocument.Element("Advertisements").Elements("Ad");
var adList = adXmlNodes.Select(xmlNode => new Advertisement {
ImageUrl = xmlNode.Element("ImageUrl").Value,
Href = xmlNode.Element("url").Value
}).ToList();
return adList;
}
}
public class Advertisement
{
public string ImageUrl { get; set; }
public string Href { get; set; } // named 'Href' to show property names don't have to match XML
}
}

C# Web Service XmlSerializer issue

I have a C# Web Service that is serializing my simple class:
[Serializable]
[XmlInclude(typeof(Bitmap))]
[XmlTypeAttribute(Namespace = "http://tempuri.org/")]
public class Class1
{
private static Bitmap _myImage = new Bitmap(#"C:\WebApplication1\ClassLibrary1\Untitled.png");
public Bitmap MyImage
{
get { return _myImage; }
set
{
_myImage = value;
}
}
}
Here's the asmx.cs code that does the serialization:
[WebMethod]
public string HelloWorld()
{
var c = new Class1();
XmlSerializer serializer = new XmlSerializer(typeof(Class1));
return XMLSerializer(c);
}
public string XMLSerializer(object pObject)
{
try
{
XmlSerializer xs = new XmlSerializer(pObject.GetType());
using (StringWriter stream = new StringWriter())
{
xs.Serialize(stream, pObject);
stream.Flush();
return stream.ToString();
}
}
catch (Exception ex)
{
return ex.ToString();
}
}
Looks prety straight forward. However, the XML generated by the XmlSerializer is producing and error when I try to DeSerialize it.
{"There is an error in XML document (5, 5)."}
{"Parameter is not valid."}
When I try to load the generated XML into IE I get this error.
Switch from current encoding to specified encoding not supported. Error processing resource 'file:///C:/Users/mhall15/Deskt...
<?xml version="1.0" encoding="utf-16"?>
Here's the generated XML:
<?xml version="1.0" encoding="utf-16"?>
<Class1 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<MyImage xmlns="http://tempuri.org/">
<Palette />
</MyImage>
</Class1>
Any ideas what's going on?
During the serialization, replace "encoding="utf-16" with "encoding="utf-8"" and that will cut it. The source of the problem - I'm not sure, but I've ran into it numerous times, and that's how I dealt with it.
That's how to deal with the IE issue.
The deserialization should be amongst these lines. I'm posting the kind of arbitrary code I normally use:
public static object DeserializeFromXML<T>(string _input)
{
object _temp = Activator.CreateInstance<T>();
Type expected_type = _temp.GetType();
_temp = null;
XmlSerializer serializer = new XmlSerializer(expected_type);
StringReader stringWriter = new StringReader(_input);
object _copy = serializer.Deserialize(stringWriter);
return _copy;
}
In the above example, I'm using templating for reusability sake. You should be able to call the method by saying DeserializeFromXML < Class1 >(_xml_input) where xml input is the string. That will force the compiler to use the definition of the given class to deserialize the XML input. That way you wouldn't even have to change the encoding in the serialization. If it's also a case where you may or may not know the data type to deserialize with, you can use a strategy design pattern where you register the root type of the XML with it's associated generic type. Later on you can reference that registry and arbitrarily deserialize any XML input as long as the root type is registered. It's a trick i normally use as well. If more is needed on this, let me know, and I'll explain in detail.
In addition,if you are running IE 9, the new update to IE 9 makes it difficult to view XML. Press F12 - go to developer tools and change your browser mode to run as IE 8 instead of IE 9.

XML Serialization of HTML

Okay this one DID it! Thanks to all of you!
public class Result
{
public String htmlEscaped
{
set;
get;
}
[XmlIgnore]
public String htmlValue
{ set; get; }
[XmlElement("htmlValue")]
public XmlCDataSection htmlValueCData
{
get
{
XmlDocument _dummyDoc = new XmlDocument();
return _dummyDoc.CreateCDataSection(htmlValue);
}
set { htmlValue = (value != null) ? value.Data : null; }
}
}
Result r = new Result();
r.htmlValue = ("<b>Hello</b>");
r.htmlEscaped = ("<b>Hello</b>");
XmlSerializer xml = new XmlSerializer(r.GetType());
TextWriter file = new StreamWriter(Environment.CurrentDirectory + "\\results\\result.xml", false, System.Text.Encoding.Default);
xml.Serialize(file, r);
file.Close();
RESULT:
<?xml version="1.0" encoding="Windows-1252"?>
<Result xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<htmlEscaped><b>Hello</b></htmlEscaped>
<htmlValue><![CDATA[<b>Hello</b>]]></htmlValue>
</Result>
As you can see, after CDATA is return type, no more escaped html in XML file on filesystem.
The JSON Serialization isn't working anymore, but this can be fixed with a little type extention.
QUESTION WAS:
Maybe someone knows how to make do it...
I have this Class:
public class Result
{
public String htmlValue
{
get;
set;
}
}
I use this to serialize it to XML
Result res = new Result();
res.htmlValue = "<p>Hello World</p>";
XmlSerializer s = new XmlSerializer(res.GetType());
TextWriter w = new StreamWriter(Environment.CurrentDirectory + "\\result.xml", false, System.Text.Encoding.Default);
s.Serialize(w, res);
w.Close();
Works fine i get this:
<?xml version="1.0" encoding="Windows-1252"?>
<Result xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<htmlValue><b>Hello World</b></htmlValue>
</Result>
What can do i have to change to get this:
<?xml version="1.0" encoding="Windows-1252"?>
<Result xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<htmlValue><![CDATA[<b>Hello World</b>]]></htmlValue>
</Result>
I've already searched but I can't find anything. The type of htmlValue
have to stay String, because of other Serialisations JSON, etc.
Tricky one... Thanks in advance for suggestions
HTML is correct in String within C#. Why decode or encode?
XmlSerializer saved the HTML escaped to XML file.
Don't use C# for consuming.
Is external tool which accept this:
<htmlValue><![CDATA[<b>Hello World</b>]]></htmlValue>
but not
<htmlValue><b>Hello World</b></htmlValue>
I do the same with JSON Serializer, in file on hard drive the HTML is saved correct.
Why and where to use HTTP Utility to prevent that? And how to get <![CDATA[ ]]> around it.
Can you give a code sample?
Are there any other Serializer than the C# own one?
I've found this Link .NET XML Serialization of CDATA ATTRIBUTE from Marco André Silva, which does I need to do, but it's different, how to include this without changing Types?
Here's a simple trick to do achieve what you want. You just need to serialize a XmlCDataSection property instead of the string property :
(it's almost the same as John's suggestion, but a bit simpler...)
public class Result
{
[XmlIgnore]
public String htmlValue
{
get;
set;
}
private static XmlDocument _dummyDoc;
[XmlElement("htmlValue")]
public XmlCDataSection htmlValueCData
{
get { return _dummyDoc.CreateCDataSection(htmlValue); }
set { htmlValue = (value != null) ? value.Data : null; }
}
}
See "CDATA serialization with XMLSerializer" for the same problem, and for the solution.
BTW, it seems to me that if the vendor no longer exists, it's time to use a different product. Possibly one that understands the XML specifications which have only existed for over a decade.
It is my understanding that you need the XML to feed it to some utility. Do you also plan to use it to de-serialize the object?
If not then why do not do it yourself - serialize your object that is? Roundtrip object -> XML -> object is somewhat tricky, but the first part is not.

Categories

Resources