René Kåbis René Kåbis - 1 year ago 69
ASP.NET (C#) Question

Unable to insert null value into nullable string field

Current project:

  • ASP.NET 4.5.2

  • MVC 5

  • EF 6

  • Fluent API, tweaked for Stored Procedures

I am able to insert null values into everything except for a set of three
fields in one table, and it’s driving me batty.

The DB Model:

public string SpecialtyEquipment { get; set; }
public string EQAttachments { get; set; }
public string SpecialtySafetyTickets { get; set; }

The Fluent API:

Jobs.Property(x => x.SpecialtyEquipment).IsOptional();
Jobs.Property(x => x.EQAttachments).IsOptional();
Jobs.Property(x => x.SpecialtySafetyTickets).IsOptional();

The DB Table in MS SQL Server 2012 R2 is clearly showing all three fields as
and nullable. As this is code-first, I have never touched the DB directly.

My (cut down) controller:

public async Task<ActionResult> JobAdditional(JobAdditionalViewModel model) {
Jobs job = await db.Jobs.FindAsync(model.Job.JobId);
JobMap jobMap = new JobMap(model.Job, job);
db.Entry(job).State = EntityState.Modified;
await db.SaveChangesAsync();
return RedirectToAction("JobDetail", new { id = model.Job.RecruiterJobId });

My ViewModel:

public class JobAdditionalViewModel {
public Jobs Jobs { get; set; } // to display most of the current job
public JobModel Job { get; set; } // to edit a specific portion of the current job

My form model:

public class JobModel {
public Guid? JobId { get; set; }
[DisplayName("Specialty Equipment (not on prior page)")]
public string SpecialtyEquipment { get; set; }
[DisplayName("Specialty Attachments (not on prior page)")]
public string EQAttachments { get; set; }
[DisplayName("Specialty Safety Tickets (not on prior page)")]
public string SpecialtySafetyTickets { get; set; }

My mapping model:

public JobMap(JobModel model, Jobs job) {
job.SpecialtyEquipment = model.SpecialtyEquipment.Trim();
job.EQAttachments = model.EQAttachments.Trim();
job.SpecialtySafetyTickets = model.SpecialtySafetyTickets.Trim();

All errors flag my mapping model, and they flag any one of the three when there is no content in the
-- that is, if it a value that is nothing, or whitespace that gets trimmed to nothing.

I have tried all variations of “handling” strings of no content, and nothing seems to work. Every single time, no matter how I try to handle zero content (an empty
), I get a

For the record, these all fail:

= (string.IsNullOrEmpty(model.SpecialtyEquipment.Trim()) ? null : model.SpecialtyEquipment.Trim());
= (model.SpecialtyEquipment.Trim().Length == 0 ? null : model.SpecialtyEquipment.Trim());

I have even tried to substitute the
, to no avail.

In fact, the only method which seems to work is replacing everything after the equals in my mapping model with
. Yup, that’s right -- force-feeding it null values:

= null;

Instead of trying a ternary operator for which null is one option is the only thing that will actually work.

In fact, I have a number of different nullable fields scattered throughout the project that I can insert null values into without any problems whatsoever. All I have to do is cast the null to a nullable version of the field type:


and it works perfectly.

But since you cannot cast a null as a nullable string, how do you handle it?

Answer Source

This line would throw NullReferenceException on model.SpecialtyEquipment.Trim() if model.SpecialtyEquipment were null

= (string.IsNullOrEmpty(model.SpecialtyEquipment.Trim()) ? null : model.SpecialtyEquipment.Trim());

This line would throw NullReferenceException on model.SpecialtyEquipment.Trim() if model.SpecialtyEquipment where null.

= (model.SpecialtyEquipment.Trim().Length == 0 ? null : model.SpecialtyEquipment.Trim());

To break it down again you are getting the NullReferenceException (NRE) because the value of model.SpecialtyEquipment is null and now you are calling a method on that null value. You can duplicate it by doing this

((string)null).Trim(); // will throw a NRE

This would be the best solution

model.SpecialtyEquipment = string.IsNullOrWhiteSpace(model.SpecialtyEquipment) // an actual null/empty check without the possibility of a NRE
    ? null 
    : model.SpecialtyEquipment.Trim();


If you are using an older version of the framework that does not support this method than do both checks like so:

model.SpecialtyEquipment = model.SpecialtyEquipment == null || model.Trim().Length == 0 
    ? null 
    : model.SpecialtyEquipment.Trim();

Both of these would guard against a NRE being thrown by checking for null and not performing an operation on the string if it is null.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download