Validation of Guid

前端 未结 8 923
忘了有多久
忘了有多久 2020-12-31 02:47

I have a strongly-typed view which has a DropDownListFor attribute on it.

Each item in the dropdown list is represented by a GUID.

What I\'m after is a way

8条回答
  •  陌清茗
    陌清茗 (楼主)
    2020-12-31 03:33

    Edited Answer

    Upon re-reading your question, it sounds like you just want to know if a value is selected. If that's the case then just apply the RequiredAttribute to the Guid property and make it nullable on the model

    public class GuidModel
    {
        [Required]
        public Guid? Guid { get; set; }
    
        public IEnumerable Guids { get; set; }
    }
    

    then in the strongly typed View (with @model GuidModel)

    @Html.ValidationMessageFor(m => m.Guid)
    @Html.DropDownListFor(
        m => m.Guid,
        Model.Guids.Select(g => new SelectListItem {Text = g.ToString(), Value = g.ToString()}),
        "-- Select Guid --")
    

    Add the client validation JavaScript script references for client-side validation.

    The controller looks like

    public class GuidsController : Controller
    {
        public GuidRepository GuidRepo { get; private set; }
    
        public GuidsController(GuidRepository guidRepo)
        {
            GuidRepo = guidRepo;
        }
    
        [HttpGet]
        public ActionResult Edit(int id)
        {
            var guid = GuidRepo.GetForId(id);
            var guids - GuidRepo.All();
    
            return View(new GuidModel { Guid = guid, Guids = guids });
        }
    
        [HttpPost]
        public ActionResult Edit(GuidModel model)
        {
            if (!ModelState.IsValid)
            {
                model.Guids = GuidRepo.All();
                return View(model);
            }
    
            /* update db */
    
            return RedirectToAction("Edit");
        }
    }
    

    This will ensure that the Guid property is required for a model-bound GuidModel.

    Original Answer

    I don't believe that there is a ready made Data Annotation Validation attribute that is capable of doing this. I wrote a blog post about one way to achieve this; the post is using an IoC container but you could take the hard coded dependency if you're wanting to get something working.

    Something like

    public class ValidGuidAttribute : ValidationAttribute
    {
        private const string DefaultErrorMessage = "'{0}' does not contain a valid guid";
    
        public ValidGuidAttribute() : base(DefaultErrorMessage)
        {
        }
    
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            var input = Convert.ToString(value, CultureInfo.CurrentCulture);
    
            // let the Required attribute take care of this validation
            if (string.IsNullOrWhiteSpace(input))
            {
                return null;
            }
    
            // get all of your guids (assume a repo is being used)
            var guids = new GuidRepository().AllGuids();
    
            Guid guid;
            if (!Guid.TryParse(input, out guid))
            {
                // not a validstring representation of a guid
                return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
            }
    
            // is the passed guid one we know about?
            return guids.Any(g => g == guid) ?
                new ValidationResult(FormatErrorMessage(validationContext.DisplayName)) : null;
        }
    }
    

    and then on the model you send into the controller action

    public class GuidModel
    {
        [ValidGuid]
        public Guid guid { get; set; }
    }
    

    This gives you server side validation. You could write client side validation to do this as well, perhaps using RemoteAttribute but I don't see a lot of value in this case as the only people that are going to see this client side validation are people that are messing with values in the DOM; it would be of no benefit to your normal user.

提交回复
热议问题