I am using an xml deserializer to read the contents of an xml file. This is using a resume parsing service. It has been working great for the past year or so but today threw an error pointing to the line
FullAddress = EmployerCity + ", " + EmployerState;
I have the following code in the controller
[ValidateAntiForgeryToken]
[HttpPost]
public ActionResult Index(int JobID, string FirstName, string MiddleName, string LastName, string Email, string ReferringSite, HttpPostedFileBase Resume)
{
string product_code = myProduct Code;
string FileName = Resume.FileName;
string encoded = FileName;
string UserID = "";
if(Resume.ContentLength > 0)
{
string Address = "";
string City = "";
string State = "";
string Zip = "";
string AreaCode = "";
string LineNumber = "";
string Telephone = "";
string PhoneType = "";
int x = 1;
string Qualifications = "";
string Licenses = "";
string Achievements = "";
try
{
Applicant applicant = new Applicant();
//Try to save the data. If it does not return a userid then the Application for this position has been started or completed.
UserID = applicant.StartApplication(FirstName, MiddleName, LastName, JobID, Email, Request.UserHostAddress, Request.UserAgent, "VA", ReferringSite);
UserID = UserID.Trim();
if (UserID.Equals("Completed", StringComparison.CurrentCultureIgnoreCase))
{
ViewBag.Message = "We have a completed application for this position on file.";
ViewBag.Status = "";
ViewBag.Started = true;
ViewBag.Completed = true;
ViewBag.Active = true;
return View();
}
if (UserID.Equals("XXXXXX", StringComparison.CurrentCultureIgnoreCase))
{
string Status = applicant.GetStatus(FirstName, MiddleName, LastName, JobID, Email).Trim();
UserID = applicant.GetUserID(FirstName, MiddleName, LastName, JobID, Email);
if (Status == "B")
{
TempData["UserID"] = UserID;
return RedirectToAction("AppInfo");
}
ViewBag.Message = "We have an incomplete application for this position on file. Your ID is " + UserID;
ViewBag.Started = true;
ViewBag.Completed = false;
ViewBag.Active = true;
return View();
}
//convert resume to base 64 string
using (BinaryReader br = new BinaryReader(Resume.InputStream))
{
int fileSize = Resume.ContentLength;
byte[] binaryStream = br.ReadBytes((int)Resume.ContentLength);
encoded = Convert.ToBase64String(binaryStream);
br.Close();
}
//Instantiate the web service object
com.resumeparser.processing.ParsingToolsService hireability = new com.resumeparser.processing.ParsingToolsService();
//the first empty element in the next two methods is where we would put our unique identifier. it is not needed though.
//Send resume over for parsing and get the results
string results = hireability.ParseDocNew(product_code, FileName, encoded, "", "", "", "");
Configuration config = WebConfigurationManager.OpenWebConfiguration("~");
string NotificationEmail = ConfigurationManager.AppSettings["NotificationEmail"].ToString();
//Sending me an email
bool SendXML = Convert.ToBoolean(ConfigurationManager.AppSettings["SendXML"].ToString());
if(SendXML)
{
SendTheEmail(NotificationEmail, UserID + " parsed resume results", results);
}
//remove all line breaks from the xml
results = results.Replace("\n", "");
int startpos;
int endpos;
int remove;
if (results.Contains("<NonXMLResume>"))
{
//Remove the text version of resume
startpos = results.IndexOf("<NonXMLResume>");
endpos = results.IndexOf("</NonXMLResume>");
remove = (endpos + 15) - startpos;
if (startpos != 0)
{
results = results.Remove(startpos, remove);
}
}
//Remove the comment inside the xml document
startpos = results.IndexOf("<!--");
endpos = results.IndexOf("<Results>");
remove = endpos - startpos;
if (startpos != 0)
{
results = results.Remove(startpos, remove);
}
var mySerializer = new XmlSerializer(typeof(Results));
Stream myFileStream = GenerateStreamFromString(results);
var obj = (Results)mySerializer.Deserialize(myFileStream);
int remaining = obj.HireAbilityXMLResults.remainingUsage;
// has Miranda been notified of
bool notified = Convert.ToBoolean(ConfigurationManager.AppSettings["Notified"].ToString());
/*
* The expiration will change when more credits are added. We have 1 year from date credits are added to bump up and add more,
* otherwise they will expire. Credits left over will roll over when new ones are added.
*/
DateTime Expiration = Convert.ToDateTime(obj.HireAbilityXMLResults.accountValidThrough);
DateTime ExpirationDate = Convert.ToDateTime(ConfigurationManager.AppSettings["ExpirationDate"].ToString());
//if expiration is greater than what we have stored then more credits have been added so update the config to show new date.
if(Expiration > ExpirationDate)
{
config.AppSettings.Settings["ExpirationDate"].Value = Expiration.ToString();
}
//update the web.config setting so that we can easily look up how many credits are remaining.
config.AppSettings.Settings["RemainingUsage"].Value = remaining.ToString();
if (remaining < 100)
{
if (!notified)
{
//send an email
SendTheEmail(NotificationEmail, "Hireability.com resume parsing service is getting low on credits.", "The resume parsing service is down to " + remaining.ToString() + " resumes that can be parsed.");
//Mark as true so we don't get an email each time
config.AppSettings.Settings["Notified"].Value = "true";
}
else
{
if (remaining == 50 | remaining == 25)
{
//send an email, this time add Eric to the emails!
SendTheEmail(NotificationEmail +";"+EricEmail, "Hireability.com resume parsing service is getting low on credits.", "The resume parsing service is down to " + remaining.ToString() + " resumes that can be parsed.");
}
}
}
else
{
if (!notified)
{
//Reset so that it will notify again when it hits 100
config.AppSettings.Settings["Notified"].Value = "false";
}
}
DateTime now = DateTime.Now;
int remainingDays = Expiration.Subtract(now).Days;
if (remainingDays < 30)
{
bool ExpirationNotification = Convert.ToBoolean(ConfigurationManager.AppSettings["ExpirationNotification"].ToString());
if (!ExpirationNotification)
{
//Send an email about pending expiration.
SendTheEmail(NotificationEmail, "The hireability.com resume parsing service account expires soon.", "The resume parsing service is set to expire on " + Expiration.ToShortDateString() + ". We will need to purchase more credits before that date to keep it active.");
//Mark as true so we don't get an email each time
config.AppSettings.Settings["ExpirationNotification"].Value = "true";
}
}
if (obj.HireAbilityXMLResults.Resume != null)
{
if (obj.HireAbilityXMLResults.Resume.StructuredXMLResume != null)
{
string name = obj.HireAbilityXMLResults.Resume.StructuredXMLResume.ContactInfo.PersonName.GivenName.ToString();
var contactMethod = obj.HireAbilityXMLResults.Resume.StructuredXMLResume.ContactInfo.ContactMethod;
foreach (var cm in contactMethod)
{
if (cm.PostalAddress != null)
{
Address = cm.PostalAddress.DeliveryAddress.AddressLine.ToString();
City = cm.PostalAddress.Municipality.ToString();
State = cm.PostalAddress.Region.ToString();
Zip = cm.PostalAddress.PostalCode.ToString();
applicant.AddAddress(UserID, Address.LimitLength(100), City.LimitLength(35), State, Zip);
}
if (cm.Telephone != null)
{
AreaCode = cm.Telephone.AreaCityCode.ToString();
LineNumber = cm.Telephone.SubscriberNumber.ToString();
string pType = cm.Location.ToString();
switch (pType)
{
case "home":
PhoneType = "Home";
break;
case "onPerson":
PhoneType = "Cell";
break;
default:
PhoneType = "Home";
break;
}
Telephone = AreaCode + "-" + LineNumber;
//We have a phone number save it.
applicant.AddTelephone(UserID, Telephone, PhoneType);
}
if (cm.Mobile != null)
{
AreaCode = cm.Mobile.AreaCityCode.ToString();
LineNumber = cm.Mobile.SubscriberNumber.ToString();
Telephone = AreaCode + "-" + LineNumber;
applicant.AddTelephone(UserID, Telephone, "Cell");
}
}
var empHistory = obj.HireAbilityXMLResults.Resume.StructuredXMLResume.EmploymentHistory;
foreach (var emp in empHistory)
{
string EmployerName = "";
string Title = "";
string EmployerAddress = "";
string EmployerCity = "";
string EmployerState = "";
string StartDate = "";
string EndDate = "";
string Duties = "";
string FullAddress = "";
bool Current = false;
EmployerName = emp.EmployerOrgName.ToString();
if (emp.PositionHistory != null)
{
if (emp.PositionHistory.OrgInfo != null)
{
if (emp.PositionHistory.OrgInfo.PositionLocation != null)
{
if (emp.PositionHistory.OrgInfo.PositionLocation.DeliveryAddress != null)
{
EmployerAddress = emp.PositionHistory.OrgInfo.PositionLocation.DeliveryAddress.ToString();
}
if (emp.PositionHistory.OrgInfo.PositionLocation.Municipality != null)
{
EmployerCity = emp.PositionHistory.OrgInfo.PositionLocation.Municipality.ToString();
}
if (emp.PositionHistory.OrgInfo.PositionLocation.Region != null)
{
EmployerState = emp.PositionHistory.OrgInfo.PositionLocation.Region.ToString();
}
FullAddress = EmployerAddress + " " + EmployerCity + ", " + EmployerState;
if (FullAddress.Length > 50)
{
FullAddress = EmployerCity + ", " + EmployerState;
}
}
}
if (emp.PositionHistory.Title != null)
{
Title = emp.PositionHistory.Title.ToString();
}
if (emp.PositionHistory.Description != null)
{
Duties = emp.PositionHistory.Description.ToString();
}
StartDate = emp.PositionHistory.StartDate.AnyDate.ToString();
EndDate = emp.PositionHistory.EndDate.AnyDate.ToString();
if (EndDate == "current")
{
Current = true;
}
}
//We have some employer information. Now save the info to database
Employer employer = new Employer();
employer.Add(UserID, EmployerName, Title.LimitLength(50), Duties.LimitLength(200), FullAddress.LimitLength(50), StartDate + " - " + EndDate, Current, x);
x++;
}
x = 1;
//The information was saved, so rename resume and save to server.
string fileName = UserID + "_Resume" + Path.GetExtension(Resume.FileName);
string _path = Path.Combine(@"E:\WebPages\Non CRIW\OhmartVega\Application\resumes", fileName);
//string _path = Path.Combine(@"X:\Non CRIW\OhmartVega\Application\resumes", fileName); //For development when on my desktop
Resume.SaveAs(_path);
//Save renamed resume name to database
applicant.AddResume(UserID, fileName);
TempData["UserID"] = UserID;
TempData["Email"] = Email;
return RedirectToAction("AppInfo");
}
}
else
{
//Send an email
SendTheEmail(NotificationEmail, "Hireability.com resume parsing service error thrown", results);
//Since there was an error delete the record
applicant.Delete(UserID);
string err = obj.HireAbilityXMLResults.processingErrors.Error.ErrorCode.ToString();
//snipped for brevity
ViewBag.Started = false;
ViewBag.Completed = false;
ViewBag.Active = false;
return View();
}
}
catch (Exception ex)
{
Errors.ErrorOccured(ex);
}
}
else
{
ViewBag.Message = "No resume was selected to upload.";
return View();
}
ViewBag.Active = true;
ViewBag.Message = "Your resume cannot be parsed.";
ViewBag.Started = false;
ViewBag.Completed = false;
ViewBag.Active = false;
return View();
}
I have attached the serialization class165775-resultscs.txt
In this user's resume there was an employer shown where it did not have this node
emp.PositionHistory.OrgInfo and from what I can tell that is what caused the null object reference
I thought this would check if the object was there
if (emp.PositionHistory.OrgInfo != null)
So how do I check if the reference is null if this is not the correct way to do so?