Bind empty string to Guid.Empty or avoid model state error

When I submit a form with an empty string “for the Guid field, I get the error message“ MyGuid field is required. ”Although I did not set the Required attribute.

 //NOT Required public Guid MyGuid { get; set; } 

after binding the guid model is 00000000-0000-0000-0000-000000000000 (because it is the default value) and it is correct. But ModelState has the indicated error.

How to avoid this error?

Additional Information:

[Required(AllowEmptyStrings = true)] does not help

I do not want the directive to be null ( Guid? ), Because this would lead to many additional codes (checking if the value matters, the mapping, etc.)

Update:

OK, I realized that Guid? change Guid? in my view models does not result in many changes than I expected (some calls to MyGuid.GetValueOrDefault() or some checks for MyGuid.HasValue and calls MyGuid.Value ).

However, the reason that a model error is added if there is no valid Guid submitted a submit request is because 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); } } 
+4
source share
3 answers

If the field type is Guid (which is a value type), it must contain the value (even if all its zeros). The correct solution to have an optional GUID - use Guid? (Nullable Guid).

Your reasons for not wanting to use Nullable do not make sense; no matter how you intend to code "emptiness", your code will need to verify it. I'd argue that Nullable actually makes this simpler, usually.

+11
source

in the sense of my answer fooobar.com/questions/1335488 / ... on ASP.NET MVC: the types used when binding to the model the following return the values ​​of Guid.Empty or the parameter Guid, if necessary.

 public class NullableGuidBinder : DefaultModelBinder { public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { if (bindingContext.ModelType == typeof(Guid?)) { var valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); string input = valueResult.AttemptedValue; if (string.IsNullOrEmpty(input) || input == "0") { // return null, even if input = 0 // however, that is dropdowns' "guid.empty") // base.BindModel(...) would fail converting string to guid, // Guid.Parse and Guid.TryParse would fail since they expect 000-... format // add the property to modelstate dictionary var modelState = new ModelState { Value = valueResult }; bindingContext.ModelState.Add(bindingContext.ModelName, modelState); return Guid.Empty; } } return base.BindModel(controllerContext, bindingContext); } } 

as indicated in your controller

  [HttpPost] [ValidateAntiForgeryToken] public async Task<ActionResult> SelectAction( [ModelBinder(typeof(NullableGuidBinder))] Guid? id) { // your stuff } 
+1
source

A set of events is triggered in your application: DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;

Keeping this in mind, all types of values ​​are not required unless they are explicitly set.

I agree with Fabiano. Guid is a little freak with him. Guid.Empty.

0
source

Source: https://habr.com/ru/post/1335486/


All Articles