2016-07-26 97 views
2

我們正在創建幾個輸入字段,其中將包含一個開始日期和結束日期時間,每個字段中包含一個日期時間。我們驗證了當前正在工作,因此如果用戶在結束時間之後放置開始時間(並且在開始之前結束時間反之),它會顯示錯誤消息,但我們遇到了一個有趣的問題。MVC驗證 - 更新另一個字段?

例如,如果用戶在開始時間之前放置了結束時間,我們會在結束時間收到錯誤消息,如預期的那樣。

enter image description here

然而,如果開始日期然後修正,而不是結束日期,消息依然存在。

enter image description here

有沒有一種方法,以消除對不同字段/更新/改正驗證消息?下面是驗證碼:

[Required(ErrorMessage = "{0} is required!")] 
[Display(Name = "Start Date")] 
[Remote("IsTestPlanEndCorrect", "Analysis", AdditionalFields = "EndDate", HttpMethod = "Post", ErrorMessage = "Test Plan Start Time must be before End.")] 
public System.DateTime StartDate { get; set; } 

[Required(ErrorMessage = "{0} is required!")] 
[Display(Name = "End Date")] 
[Remote("IsTestPlanEndCorrect", "Analysis", AdditionalFields = "StartDate", HttpMethod = "Post", ErrorMessage = "Test Plan End Time must be after Start.")] 
public System.DateTime EndDate { get; set; } 

IsTestPlanEndCorrect僅僅是返回如果傳遞的數據通過驗證true或false根據的方法。

編輯:爲字段 剃刀代碼:控制器

<div class="form-group"> 
@Html.LabelFor(t => t.StartDate, new { @class = "col-md-2 control-label" }) 
<div class="col-md-10"> 
     @Html.TextBoxFor(t => t.StartDate, new { @class = "form-control datetimepicker", placeholder = "Enter Test Plan Start"}) 
     @Html.ValidationMessageFor(t => t.StartDate) 
    </div> 
</div> 

<div class="form-group"> 
    @Html.LabelFor(t => t.EndDate, new { @class = "col-md-2 control-label" }) 
    <div class="col-md-10"> 
     @Html.TextBoxFor(t => t.EndDate, new { @class = "form-control datetimepicker", placeholder = "Enter Test Plan End"}) 
     @Html.ValidationMessageFor(t => t.EndDate) 
    </div> 
</div> 

輸入驗證碼:

[HttpPost] 
public JsonResult IsTestPlanEndCorrect(DateTime EndDate, DateTime StartDate) 
{ 
    return Json(TimeManipulation.checkDate(StartDate,EndDate)); 
} 
+0

什麼是您的驗證代碼''IsTestPlanEndCorrect呢? – Shyju

+0

'分析'是具有'IsTestPlanEndCorrect'方法的控制器的名稱 – Novastorm

+0

是的。你可以分享這些代碼嗎?當你調試開始日期時,是否進行異步調用? – Shyju

回答

1

行爲的原因是,jQuery的客戶端驗證觸發您編輯的元素(最初在.blur()和其後.keyup())。更改StartDate文本框中的值不會觸發對EndDate值的驗證,它只會觸發驗證StartDate值,因此驗證消息不會消失。

您可以通過專門引發了「其他」文本框中.keyup()事件

$('#StartDate').change(function() { 
    $('#EndDate').trigger('keyup'); // or $('#EndDate').valid(); 
}); 
$('#EndDate').change(function() { 
    $('#StartDate').trigger('keyup'); // or $('#StartDate').valid(); 
}); 

但是使用RemoteAttribute檢查這是在客戶端已知值解決這個問題,例如是一種資源的浪費,每次更改值時,您至少要對數據庫進行2次調用。另外,遠程驗證僅適用於客戶端,您需要在POST方法中再次重複驗證邏輯,並手動添加ModelStateError以防止惡意用戶訪問。

相反,使用實現IClientValidatable,讓您無需Ajax調用同時獲得客戶端和服務器端驗證自定義驗證屬性。有關實施自己的指導,請參閱The Complete Guide To Validation In ASP.NET MVC 3 - Part 2。或一個現成的解決方案,可以考慮使用foolproof[GreaterThan][LessThan]驗證特性。請注意,通常您將其中一個或另一個應用於其中一個屬性,但是如果您確實想將其應用於兩個屬性,

[LessThan("EndDate")] 
public DateTime StartDate { get; set; } 
[GreaterThan("StartDate")] 
public DateTime EndDate { get; set; } 

那麼您仍然需要觸發上面提到的.keyup()事件,以使其他消息消失。

0

你可能會想/需要實現這跟jQuery

$('#StartDate, #EndDate').change(function() { 
    $('#StartDate, #EndDate').valid(); 
}); 

這將導致驗證被要求爲字段每次有變化要麼字段。您可能希望在此代碼中添加一些額外的檢查,例如,如果結束日期爲空,您可能不想檢查它。

+0

你知道是否有可能將其鏈接到html驗證?這個解決方案看起來很理想,但我不確定如何將它鏈接到實際驗證消息 – Novastorm

+0

@Novastorm道歉,我很愚蠢。你是什​​麼意思?如果你在前端有jQuery驗證(假設你是通過遠程驗證來完成的話),那麼它應該沒問題,然後自動完成。 – ediblecode

+0

啊,所以您在UI上看到的驗證消息來自我們的ViewModel(這是帖子中的第一個代碼塊)。我認爲遠程是用來定義驗證執行的是應用程序端而不是客戶端(因爲這個方法在斷點和代碼中被調試時被命中)。當我說的鏈接它返回到HTML驗證我指的是你的UI獲得的消息(在我的部分在那裏工作的窮人的選擇!) – Novastorm