将空字符串绑定到Guid.Empty或避免模型状态错误

Fab*_*ano 5 c# validation asp.net-mvc model-binding asp.net-mvc-2

当我为一个Guid字段发布一个带有空字符串""的表单时,我收到错误"MyGuid字段是必需的".虽然我没有设置"必需"属性.

//NOT Required   
public Guid MyGuid { get; set; }
Run Code Online (Sandbox Code Playgroud)

在模型绑定之后,Guid是00000000-0000-0000-0000-000000000000(因为它是默认值)并且这是正确的.但ModelState有上述错误.

我怎样才能避免这个错误?

附加信息:

[Required(AllowEmptyStrings = true)] 没有帮助

我不想让Guid为nullable(Guid?),因为这会导致很多额外的代码(检查它是否有值,映射等)

更新:

好的,我发现Guid?在我的视图模型中的更改不会导致比我预期的更多更改(一些调用MyGuid.GetValueOrDefault()或一些检查MyGuid.HasValue和调用MyGuid.Value).

但是,如果没有为post请求提供有效的Guid,则添加模型错误的原因是DefaultModelBinder尝试绑定nullGuid.解决方案是覆盖DefaultModelBinder.并且不会在模型状态中添加任何错误

public class MyModelBinder : DefaultModelBinder
{
    protected override void SetProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, object value)
    {
        if (propertyDescriptor.PropertyType == typeof(Guid) && value == null)
        {
            value = Guid.Empty;
        }
        base.SetProperty(controllerContext, bindingContext, propertyDescriptor, value);

    }
}
Run Code Online (Sandbox Code Playgroud)

Tim*_*mwi 12

如果字段的类型是Guid(值类型),则它必须包含一个值(即使它全为零).具有非必需GUID的正确解决方案是使用Guid?(Nullable Guid).

你不想使用Nullable的原因没有意义; 无论你以哪种方式编码"空虚",你的代码都必须检查它.我认为Nullable实际上通常会让这更容易.

  • @Fabiano:如果你的代码将全零值GUID作为一个特殊的"空"值处理,虽然这可能大体上都有用,但我认为它相当hacky和代码味道.代码的未来维护者无法从属性的类型中知道它可能包含具有特殊含义的魔法值.另一方面,如果你使用`Guid?`,那么很明显它可能是'null`,这意味着什么.因此,我认为代码中容纳Nullable类型所需的更改将非常值得. (3认同)