Why do I get null instead of empty string when receiving POST request in from Razor View?
Asked Answered
M

3

82

I used to receive empty string when there was no value:

[HttpPost]
public ActionResult Add(string text)
{
    // text is "" when there's no value provided by user
}

But now I'm passing a model

[HttpPost]
public ActionResult Add(SomeModel Model)
{
    // model.Text is null when there's no value provided by user
}

So I have to use the ?? "" operator.

Why is this happening?

Merta answered 4/9, 2010 at 9:51 Comment(1)
An alternative solution to using attributes on each model property, as described below, is using a custom model binder, see #12734583Pioneer
A
176

You can use the DisplayFormat attribute on the property of your model class:

[DisplayFormat(ConvertEmptyStringToNull = false)]
Artful answered 17/2, 2012 at 5:9 Comment(5)
This helped me with implicit model binding before my action was executed. Used it along with MetadataTypeAttribute to mark auto-generated property of Entity Framework Model-First classConscientious
This is definitively a Should Know.Coward
I am using: public ActionResult Quotations(string projectName, string brandName, string modelName, string clientName) { var model = _dataAccess.Quotations_Select(projectName, brandName, modelName, clientName); return View(model); } calling a stored procedure and supplying values, so, the attribute will not work for me. What should I do?Ethylethylate
It's a long road, but also, in MVC6, if you (like me) for some reason don't want to set this via an attribute and want to store your metadata elsewhere, you can write your own metadata provider and register it in Startup.cs like: AddMvc(o => ModelMetadataDetailsProviders.Add(new YourProvider())). There in GetDisplayMetadata you can do everying that attributes do. For this question it'll be context.DisplayMetadata.ConvertEmptyStringToNull = false;Xenophanes
This conflicted with my other validation I had on the property. I ended up creating a property with a backing field where the get returns empty string if the backing field is null.Refugia
N
9

The default model binding will create a new SomeModel for you. The default value for the string type is null since it's a reference type, so it's being set to null.

Is this a use case for the string.IsNullOrEmpty() method?

Night answered 5/9, 2010 at 18:5 Comment(3)
Yeah, that's what I thought. I didn't realize that default value for the string type is null, not String.Empty though. No, it's not the case for the IsNullOrEmpty method, I have NOT NULL columns in my SQL table, so I get an exception when there'are null strings. So I guess I'll have to continue to use the ?? "" operator. Thanks!Merta
You might also use a property with a backing store and return string.empty instead of null from the ViewModel, eg:Night
woops! here's some psuedocode: private string _text; public string Text { get { return _text; } set { _text = value ?? string.empty; }} -- something like thatNight
Y
2

I am trying this in Create and Edit (my object is called 'entity'):-

        if (ModelState.IsValid)
        {
            RemoveStringNull(entity);
            db.Entity.Add(entity);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View(entity);
    }

Which calls this:-

    private void RemoveStringNull(object entity)
    {
        Type type = entity.GetType();
        FieldInfo[] fieldInfos = type.GetFields(BindingFlags.Instance | BindingFlags.GetField | BindingFlags.Public | BindingFlags.NonPublic);
        for (int j = 0; j < fieldInfos.Length; j++)
        {
            FieldInfo propertyInfo = fieldInfos[j];
            if (propertyInfo.FieldType.Name == "String" )
            {
                object obj = propertyInfo.GetValue(entity);
                if(obj==null)
                    propertyInfo.SetValue(entity, "");
            }
        }
    }

It will be useful if you use Database First and your Model attributes get wiped out each time, or other solutions fail.

Yuu answered 6/11, 2015 at 21:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.