Чому я отримую null замість порожнього рядка під час отримання запиту POST із Razor View?


76

Раніше я отримував порожній рядок, коли не було значення:

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

Але зараз я передаю модель

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

Тож я повинен використовувати ?? ""оператор.

Чому це відбувається?


Альтернативним рішенням використання атрибутів для кожної властивості моделі, як описано нижче, є використання користувальницького в'яжучого моделі, див. Stackoverflow.com/questions/12734083/…
Андерс,

Відповіді:


162

Ви можете використовувати DisplayFormatатрибут у властивості вашого класу моделі:

[DisplayFormat(ConvertEmptyStringToNull = false)]

Це допомогло мені з неявним прив'язуванням моделі до того, як була виконана моя дія. Використовував його разом з MetadataTypeAttribute для позначення автоматично згенерованого властивості Entity Framework Model-First class
EvAlex

1
Це, безумовно, слід знати.
Серж

Я використовую: public ActionResult Quotations(string projectName, string brandName, string modelName, string clientName) { var model = _dataAccess.Quotations_Select(projectName, brandName, modelName, clientName); return View(model); } виклик збереженої процедури та надання значень, отже, атрибут для мене не спрацює. Що я повинен зробити?
Talal Yousif

3
Це довгий шлях, але також у MVC6, якщо ви (як і я) з якихось причин не хочете встановити це через атрибут і хочете зберігати свої метадані деінде, ви можете написати власного постачальника метаданих та зареєструвати його в автозавантаженні .cs подобається: AddMvc(o => ModelMetadataDetailsProviders.Add(new YourProvider())). Там GetDisplayMetadataви можете робити все, що роблять атрибути. Для цього питання це будеcontext.DisplayMetadata.ConvertEmptyStringToNull = false;
evilkos

Це суперечило моєму іншому підтвердженню, яке я мав щодо власності. У підсумку я створив властивість із полем для резервного копіювання, де get повертає порожній рядок, якщо поле для резервного копіювання є нульовим.
Peheje,

9

Прив'язка моделі за замовчуванням створить для вас новий SomeModel. Значення за замовчуванням для типу рядка має значення null, оскільки це посилальний тип, тому для нього встановлюється значення null.

Це варіант використання методу string.IsNullOrEmpty ()?


1
Так, я так думав. Я не розумів, що значення за замовчуванням для типу рядка має значення null, а не String.Empty. Ні, це не так для методу IsNullOrEmpty, у моїй таблиці SQL немає стовпців NULL, тому я отримую виняток, коли є нульові рядки. Тож, мабуть, мені доведеться продовжувати використовувати ?? "" оператор. Дякую!
Alex

Ви також можете використовувати властивість із резервним сховищем та повернутими string.empty замість null із ViewModel, наприклад:
hackerhasid

1
ого! ось деякий psuedocode: приватний рядок _text; відкритий рядок Text {get {return _text; } встановити {_text = значення ?? string.empty; }} - щось подібне
hackerhasid

2

Я намагаюся зробити це у режимі Створення та редагування (мій об'єкт називається "сутність"): -

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

        return View(entity);
    }

Що називає це: -

    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, "");
            }
        }
    }

Буде корисно, якщо ви використовуєте Database First, а атрибути Model щоразу стираються, або інші рішення не вдаються.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.