开发者

DataAnnotations [Required] Attribute doesn't cause Exception to be thrown

开发者 https://www.devze.com 2023-01-09 04:57 出处:网络
I have an Asp.NET MVC application in which I use data annotations to add validation to some fields: [Required]

I have an Asp.NET MVC application in which I use data annotations to add validation to some fields:

    [Required]
    [DisplayName("Course Name")]
    string Name { get; set; }

However this doesn't seem to work as I expected. Basically If the page contains any other errors that I manually check for and throw a new RuleViolation(), then the required violation is shown in the Validation Summary. If the required violation is the only error then it is not shown.

My controller has this code in it:

        catch (Exception ex)
        {
            ModelState.AddModelError("", ex.Message);
            ModelState.AddRuleViolations(courseViewModel.Course.GetRuleViolations());
            return View(courseViewModel);
        }

But given that the required violation is not throwing, I never go in here.

Do I need to do something that I dont know about to trap errors raised by DataAnnotation viola开发者_开发技巧tion?

Thanks for any help

Edit:

Here is the controller action:

    [HttpPost]
    [ValidateInput(true)]
    public ActionResult Edit(int id, CourseViewModel courseViewModel)
    {

        var oldCourse = _eCaddyRepository.GetCourse(id);

        if (courseViewModel.Course == null)
        {
            return View("NotFound", string.Format("Course {0} Not Found", id));
        }

        try
        {
            courseViewModel.Update(oldCourse);
            _eCaddyRepository.SubmitChanges();

            return RedirectToAction("Index", "Course");
        }
        catch (Exception ex)
        {
            ModelState.AddModelError("", ex.Message);
            ModelState.AddRuleViolations(courseViewModel.Course.GetRuleViolations());
            return View(courseViewModel);
        }
    }

Where Update is :

    public class CourseViewModel : BaseViewModel
{
    public Course Course { get; set; }

    public void Update(Course oldCourse)
    {
        oldCourse.Name = this.Course.Name != null ? this.Course.Name.Trim() : string.Empty;
        oldCourse.Postcode = this.Course.Postcode != null ? this.Course.Postcode.Trim() : string.Empty;

        for (var i = 0; i < 18; i++)
        {
            oldCourse.Holes[i].Par = this.Course.Holes[i].Par;
            oldCourse.Holes[i].StrokeIndex = this.Course.Holes[i].StrokeIndex;
        }
    }
}

EDIT: Final code that works and validates as expected using dataannotations. Thanks to mare.

    [HttpPost]
    [ValidateInput(true)]
    public ActionResult Edit(int id, CourseViewModel courseViewModel)
    {
        var oldCourse = _eCaddyRepository.GetCourse(id);

        if (courseViewModel.Course == null)
        {
            return View("NotFound", string.Format("Course {0} Not Found", id));
        }

        if (ModelState.IsValid)
        {
            try
            {
                courseViewModel.Update(oldCourse);
                _eCaddyRepository.SubmitChanges();
                return RedirectToAction("Index", "Course");
            }
            catch (Exception ex)
            {
                ModelState.AddModelError("", ex.Message);
            }
        }

        // Return Model with errors
        ModelState.AddRuleViolations(courseViewModel.Course.GetRuleViolations());
        return View(courseViewModel);
    }


I wonder how no one else pointed this out (jfar was close but his wording was off so chrisp_68 probably did not understand what jfar meant with model state violations) but you are missing this from your controller:

        if (ModelState.IsValid) // this check for model validity, not try..catch block
        {
            // do your stuff here, update to the datastore and return another view
        }

        // you can add additional Model State errors here manually if you wish
        // with AddModelError() like you do it now
        return View(editing); // return the same view with errors

So it's ModelState.IsValid check that you need, because DataAnnotations won't perform any exception throwing by themselves.

EDIT: Actually, to be precise, DataAnnotations don't do exception throwing because it would be nonsense if they did, because that would break the execution of your app, which of course you do not want. You want to return to the same View and give user a chance to correct his mistakes.

On the other hand, you can still have try..catch block inside the if(ModelState.IsValid) to catch the REAL exception like failure to write to disk or failing to store to the database or inserting nulls into DB columns where no nulls are allowed, etc etc.

HTH


There is nothing in MVC2 that would throw an exception because of a [Required] field.

You get model state violations, thats it. Pretty sure exceptions are only thrown from a manual call to the ModelBinder when your trying to bind "Joel Atwood" to a DateTime field.


On class property there u put data annotation, namespace should be "YouProject.Model"

0

精彩评论

暂无评论...
验证码 换一张
取 消