2011-08-04 9 views
1

저는 StartDate 및 EndDate가있는 ViewModel이 있습니다. 분명히 StartDate 유효성을 검사해야합니다 < = EndDate. MVC3 서버 유효성 검사가 실행되지 않습니다.

은 내가 StartDateBeforeEndDate 검증 속성을 생성하고 그와 뷰 모델 클래스 장식 :

public class ValidProgramDisplayStartDateAttribute : ValidationAttribute 
{ 
    public override bool IsValid(object value) 
    { 
     ProgramCreateOrEditViewModel vm = value as ProgramCreateOrEditViewModel; 
     if (vm == null) return true; //not our problem 

     if (!vm.EndDisplay.HasValue) return true; 
      //if you don't set an end date, you can't be invalid 

     return vm.StartDisplay <= vm.EndDisplay; 
    } 
} 

을 ...

[ValidProgramDisplayStartDate(ErrorMessage="The program start display date cannot be after the program display end date.")] 
public class ProgramCreateOrEditViewModel 
{ 

    [Required(ErrorMessage = "A program title is required.")] 
    [StringLength(255, ErrorMessage = "The program title cannot exceed 255 characters.")] 
    public virtual string Title { get; set; } 

    private DateTime _startDisplayDate = DateTime.Now; 

    [Display(Name = "Display Start Date")] 
    [Required(ErrorMessage = "A start display date is required")] 
    [DataType(DataType.Date)] 
    public virtual DateTime StartDisplay { get { return _startDisplayDate; } set { _startDisplayDate = value; } } 

    [Display(Name="Display End Date")] 
    [DataType(DataType.Date)] 
    public virtual DateTime? EndDisplay { get; set; } 

...more properties omitted... 
} 

제목이 제대로 검증하고 검증 메시지는 검증 요약으로 나타납니다 예상했지만 IsValid의 중단 점은 실행되지 않으며 유효하지 않은 쌍을 지정하면 유효성 검사 오류가 표시되지 않습니다.

ValidationAttribute은 ViewModel 개체를 만들고 날짜를 채우고 ValidationAttribute 개체를 만들고 IsValid 메서드를 호출하는 단위 테스트에서 올바르게 작동합니다. 또한 컨트롤러의 POST 동작에 중단 점을 설정하고 Visual Studio의 직접 실행 창을 사용하여 ValidationAttribute을 생성하고받은 ViewModel을 전달하면 올바르게 작동합니다.

이 단계에서는 클라이언트 측 유효성 검사에 대해별로 신경 쓰지 않습니다. 그것은 "좋은 시간"을 가지고 있지만 누가 시간을 얻었습니까? 그러나 서버 측 유효성 검사는 필수적입니다.

보기 :

@model MyProject.Web.Mvc.Controllers.ViewModels.ProgramCreateOrEditViewModel 
@using MvcContrib.FluentHtml 
@{ 
    ViewBag.Title = "Index"; 
} 

<h2>Index</h2> 
@using (Html.BeginForm()) 
{ 

<fieldset class="program"><legend>Program</legend> 
    @if (!ViewData.ModelState.IsValid) 
    { 
     <p class="error">Please correct all errors listed below. The program cannot be saved while errors remain.</p> 
     @Html.ValidationSummary(false) 
    } 
    @Html.HiddenFor(m => m.Id) 
    <h3> 
     @Html.LabelFor(m => m.Title) 
     @Html.TextBoxFor(m => m.Title)</h3> 
    <div id="accordion"> 
     <h3><a href="#">Dates:</a></h3> 
     <div class="section"> 
      Dates related to <em>displaying</em> the program on our site:<br /> 
      @Html.LabelFor(m => m.StartDisplay) 
      @Html.EditorFor(m => m.StartDisplay, new { _class = "date" }) 
      @Html.LabelFor(m => m.EndDisplay) 
      @Html.EditorFor(m => m.EndDisplay, new { _class = "date enddisplay" }) 
     </div> 
    ... more form fields omitted ... 
    </div> 
    <p> 
     <input type="submit" value="Save" /></p> 
</fieldset> 
} 

그리고 마지막으로, 편집기 템플릿 :

@model DateTime? 
@Html.TextBox("", Model.HasValue ? Model.Value.ToString("MM/dd/yyyy") : String.Empty, new { @class = "date" }) 
+0

UnobtrusiveJavaScript가 필요하다면 사용하도록 설정 했습니까? – stack72

+0

나는 그 길을 내려다 보지 않았다. b/c 나는 서버쪽에 대해 완전히 염려하고있다. 자바 스크립트가 서버 쪽 유효성 검사에 영향을 준다면 나는 오늘 더 많은 카페인을 필요로 할 것이다. . :) –

답변

1

. 이 클래스는 클래스 내의 ValidationAttributes가 모두 충족 된 후에 만 ​​처리됩니다.

[ValidProgramDisplayStartDate(ErrorMessage="The program start display date cannot be after the program display end date.")]을 클래스 꾸미기에서 ID 속성 꾸미기로 이동하면 다른 모델 오류가있는 경우에도 서버 측 유효성 검사가 수행됩니다.

counsellorben

+0

그 말이 정확하고 심각하게 짜증납니다. viewModel을 얻으려면 validationcontext에 액세스하기 위해 속성 클래스를 변경해야합니다. 속성 오류가있는 경우에도 VM에서 ValidationAttributes를 만드는 방법을 아는 사람이없는 한 .... –

+0

지금이 사이트를 방문하는 모든 사용자에게 유효성 검사를 강제 실행하기위한 몇 가지 좋은 옵션이 있습니다. http : // stackoverflow를 참조하십시오.com/questions/6431478/how-to-force-mvc-validate-ivalidatable 객체 –

1

이상한, 다음 코드는 나를 위해 큰 일했습니다.

컨트롤러 :

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     return View(new ProgramCreateOrEditViewModel 
     { 
      StartDisplay = DateTime.Now, 
      EndDisplay = DateTime.Now.AddDays(-1), 
      Title = "foo bar" 
     }); 
    } 

    [HttpPost] 
    public ActionResult Index(ProgramCreateOrEditViewModel model) 
    { 
     return View(model); 
    } 
} 

보기 :

문제는 클래스 속성의 모든 모델에 오류가있는 경우 클래스 ValidationAttribute이 처리되지 않습니다 것으로 보인다
@model ProgramCreateOrEditViewModel 

@using (Html.BeginForm()) 
{ 
    <fieldset class="program"> 
     <legend>Program</legend> 

     @if (!ViewData.ModelState.IsValid) 
     { 
      <p class="error">Please correct all errors listed below. The program cannot be saved while errors remain.</p> 
      @Html.ValidationSummary(false) 
     } 

     <h3> 
      @Html.LabelFor(m => m.Title) 
      @Html.TextBoxFor(m => m.Title) 
     </h3> 
     <div id="accordion"> 
      <h3><a href="#">Dates:</a></h3> 
      <div class="section"> 
       Dates related to <em>displaying</em> the program on our site:<br /> 
       @Html.LabelFor(m => m.StartDisplay) 
       @Html.EditorFor(m => m.StartDisplay, new { _class = "date" }) 
       @Html.LabelFor(m => m.EndDisplay) 
       @Html.EditorFor(m => m.EndDisplay, new { _class = "date enddisplay" }) 
      </div> 
     </div> 
     <p><input type="submit" value="Save" /></p> 
    </fieldset> 
} 
+0

나중에 @counselorben에 의해 지적 된 바와 같이 이것은 속성 수준의 유효성 검사 오류가 없기 때문에 효과가 있습니다. 예제를 Title = String.Empty로 변경하면; 다시 실행하면 제목 오류 만 표시됩니다. –

관련 문제