将空字符串绑定到 Guid.Empty 或避免模型状态错误
当我发布一个 Guid
字段包含空字符串“”的表单时,我收到错误“MyGuid 字段是必需的”。虽然我还没有设置“必需”属性。
//NOT Required
public Guid MyGuid { get; set; }
模型绑定后,Guid 为 00000000-0000-0000-0000-000000000000
(因为它是默认值),这是正确的。但 ModelState 有上述错误。
我怎样才能避免这个错误?
其他信息:
[Required(AllowEmptyStrings = true)]
没有帮助
我不想使Guid可为空(Guid?
),因为这会导致很多额外的代码(检查它是否有值、映射等)
更新:
好的,我发现我的Guid?
发生了变化视图模型不会导致比我预期的更多更改(对 MyGuid.GetValueOrDefault()
的一些调用或对 MyGuid.HasValue
的一些检查以及对 MyGuid 的调用.值
)。
但是,如果 post 请求中未提供有效的 Guid,则会添加模型错误,原因是 DefaultModelBinder
尝试将 null
绑定到 Guid.解决方案是重写
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);
}
}
When I post a form with an empty string "" for a Guid
field I get the error "The MyGuid field is required." although I haven't set the "Required" attribute.
//NOT Required
public Guid MyGuid { get; set; }
after model binding the Guid is 00000000-0000-0000-0000-000000000000
(because it's the default value) and that's correct. But the ModelState has the mentioned error.
How can I avoid this error?
Additional Info:
[Required(AllowEmptyStrings = true)]
does not help
I don't want to make the Guid nullable (Guid?
) because this would lead to a lot additional code (checking if it has a value, mapping and so on)
Update:
OK, I figured out that a change to Guid?
in my view models doesn't result in that many changes than I expected (some calls to MyGuid.GetValueOrDefault()
or some checks for MyGuid.HasValue
and calls to MyGuid.Value
).
However, the reason that a model error is added if no valid Guid is provided with the post request, is that the DefaultModelBinder
tries to bind null
to Guid
. The solution would be to override the DefaultModelBinder
. And no errors will be added to the model state
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);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果字段的类型是Guid(它是值类型),那么它必须包含一个值(即使它全为零)。拥有非必需 GUID 的正确解决方案是使用
Guid?
(Nullable Guid)。您不想使用 Nullable 的理由没有意义;无论您采用哪种方式编码“空”,您的代码都必须检查它。我认为通常来说 Nullable 实际上使这变得更容易。
If the type of the field is
Guid
(which is a value type), then it must contain a value (even if it’s all zeros). The correct solution to have a non-required GUID is to useGuid?
(Nullable Guid).Your reasons for not wanting to use Nullable don’t make sense; no matter which way you are going to encode “emptiness”, your code will have to check for it. I’d argue that Nullable actually makes this easier, generally.
从我的回答https://stackoverflow.com/a/31268941/4985705的意义上来说ASP.NET MVC:模型绑定中的类型转换
如果需要,以下内容将返回 Guid.Empty 值或 Guid 参数。
在您的控制器中进行如下绑定
in the sense of my answer https://stackoverflow.com/a/31268941/4985705 on ASP.NET MVC: types cast in model binding
the following will return the Guid.Empty values or the Guid parameter, if it is desired.
binding as follows in your controller
在您的应用程序启动事件中设置: DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
请记住,除非明确设置,否则所有值类型都不需要。
不过我同意法比亚诺的观点。 Guid 有点奇怪,它是 Guid.Empty。
In your application start event set: DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
Keeping in mind this will make all value types not required unless explicitly set so.
I agree with Fabiano though. Guid is a bit of a freak with it's Guid.Empty.