为什么从Razor View接收POST请求时,我得到的是null而不是空字符串?


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/...
安德斯

Answers:


161

您可以DisplayFormat在模型类的属性上使用属性:

[DisplayFormat(ConvertEmptyStringToNull = false)]

这有助于我在执行操作之前进行隐式模型绑定。与MetadataTypeAttribute一起使用,以标记Entity Framework Model-First类的自动生成的属性
EvAlex

1
这绝对是应该知道的。
Serge 2013年

我正在使用: 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 2015年

3
这是一条漫长的道路,但是,在MVC6中,如果您(像我一样)出于某种原因不想通过属性设置它并且想要将元数据存储在其他地方,则可以编写自己的元数据提供程序并将其注册在Startup中的.cs喜欢:AddMvc(o => ModelMetadataDetailsProviders.Add(new YourProvider()))。在这里GetDisplayMetadata你可以做的是万万做的属性。对于这个问题,它将是context.DisplayMetadata.ConvertEmptyStringToNull = false;
evilkos,2016年

这与我对该物业进行的其他验证相冲突。我最终创建了一个带有后备字段的属性,如果后备字段为null,则get返回空字符串。
Peheje '18 -10-1

9

默认的模型绑定将为您创建一个新的SomeModel。字符串类型的默认值是null,因为它是引用类型,所以将其设置为null。

这是string.IsNullOrEmpty()方法的用例吗?


1
是的,这就是我的想法。我没有意识到字符串类型的默认值为null,但不是String.Empty。不,对于IsNullOrEmpty方法不是这种情况,我的SQL表中没有NOT NULL列,因此当存在空字符串时会出现异常。所以我想我将不得不继续使用?? “”运算符。谢谢!
亚历克斯

您可能还会使用带有后备存储的属性,并从ViewModel返回string.empty而不是null,例如:
hackerhasid 2010年

1
woo!这是一些伪代码:私有字符串_text; 公共字符串Text {get {return _text; }设置{_text =值?? string.empty; }} –类似的东西
hackerhasid 2010年

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属性,否则其他解决方案将失败,这将很有用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.