2011-03-18 76 views
11

我在ASP.NET MVC 2.0中驗證有問題。我在Controller中使用相同的Action來執行用戶請求。
例如:頁面加載時顯示驗證消息

public ActionResult Index(ReportModel model) 
{ 
    if (!model.IsInitialDisplay && ModelState.IsValid) 
    { 
     model.Result = service.GetResult(model);     
    } 
    return View(model); 
} 

在ReportModel,我定義了一個標誌IsInitialDisplay,以確定該頁面是否是初始顯示或不顯示:

public class ReportModel 
{ 
    [Required(ErrorMessage = "*")] 
    public string Criteria { get; set; } 
    public bool IsInitialDisplay { get; set; } 
    public ReportResult Result { get; set; } 

    public ReportModel() 
    { 
     IsInitialDisplay = true; 
    } 
} 

並在視圖中,我使用以下代碼:

<% using (Html.BeginForm()) 
    { %> 
<table> 
    <tr> 
     <th> 
      Criteria: 
     </th> 
     <td> 
      <%= Html.TextBox("Criteria", "") %> 
      <%= Html.ValidationMessage("Criteria") %> 
     </td> 
    </tr> 
</table> 
<br /> 
<input type="submit" value="Submit" /> 
<%= Html.Hidden("IsInitialDisplay", false) %> 
<% } %> 

如我所料,如果用戶不輸入任何的標準值,並點擊提交按鈕,用於驗證的錯誤信息會迪張開。
但驗證錯誤消息始終顯示在初始頁面加載,我不知道如何防止它?
有誰知道?謝謝,

[更新]
我有如下更新我的行動方法和它似乎是罰款:

public ActionResult Index(ReportModel model) 
{ 
    // Collecting some commons data here... 

    if (model.IsInitialDisplay) 
    { 
     ModelState.Clear(); 
    } 
    else if (ModelState.IsValid) 
    { 
     model.Result = service.GetResult(model);     
    } 
    return View(model); 
} 

回答

-1

型號

public class ReportModel 
{ 
    [Required(ErrorMessage = "*")] 
    public string Criteria { get; set; } 
} 

查看

<% Html.EnableClientValidation(); %>  

<% using (Html.BeginForm()) 
{ %> 
    <%= Html.TextBoxFor(model => model.Criteria) %> 
    <%= Html.ValidationMessageFor(model => model.Criteria) %> 

    <input type="submit" value="Submit" /> 
<% } %> 

工作正常

+0

在我的項目中,我爲_ReportModel.Criteria_使用了複雜的模型對象。所以,你的建議是不合適的。 – aquanilium 2011-03-21 01:23:20

32

在初始頁面加載時顯示錯誤消息的原因是因爲您的控制器操作需要使用ReportModel模型作爲參數。當你第一次訪問/Home/Index這個動作時,你沒有傳入任何參數,當默認模型聯編程序嘗試綁定到ReportModel實例時,它會觸發驗證錯誤。

這是一個不好的做法,同時用於呈現同樣的動作和處理表單提交,但如果你真的想這樣做,你可以嘗試這樣的:

public ActionResult Index(bool? isInitialDisplay) 
{ 
    if (isInitialDisplay.HasValue && !isInitialDisplay.Value) 
    { 
     var model = new ReportModel(); 
     UpdateModel(model); 
     if (ModelState.IsValid) 
     { 
      model.Result = service.GetResult(model);     
     } 
     return View(model); 
    } 

    // Initial request 
    return View(new ReportModel()); 
} 

在這種情況下,您不再需要模型上的IsInitialDisplay屬性或將其設置爲true的構造函數。

這是說,這裏的推薦方式:

public ActionResult Index() 
{ 
    var model = new ReportModel(); 
    return View(model); 
} 

[HttpPost] 
public ActionResult Index(ReportModel model) 
{ 
    if (!ModelState.IsValid) 
    { 
     return View(model); 
    } 
    model.Result = service.GetResult(model);     
    return View(model); 
} 
+0

感謝您的建議,但在我的項目中,我需要爲_ReportModel.Criteria_收集一些公共數據。所以,我不想在兩個操作中複製這些業務邏輯(帶&不帶模型)。 – aquanilium 2011-03-21 01:16:40

+0

這對我來說很好奇,因爲我得到這個錯誤是因爲你描述的原因,但是Action正在接受一個模型,因爲它是一系列表單的一部分,並被張貼到,然後實際的頁面張貼到下一張。 。所以我不知道爲什麼這是一個不好的做法 – BigOmega 2013-07-22 17:49:56

+0

爲什麼「在呈現和處理表單時使用相同的動作」是一種糟糕的做法?怎麼了? – SandRock 2015-02-20 17:31:06

5

這裏是一個融合了一些很好的答案,一個簡單的解決方案:

[HttpGet] 
public ActionResult Index(ReportsModel model) 
{ 
    ModelState.Clear(); //clears the validation 

    return View(model); 
} 

[HttpPost] 
public ActionResult Index(ReportsModel model, string unused) 
{ 
    ... 
} 

它使用HTTP方法來確定它的第一負載(如達林的解決方案)。

最重要的是,它有MVC建立你的控制器,而不是手動新建一個自己。如果您使用依賴注入,或者您有其他上下文數據通過查詢字符串進入(如嵌套的資源ID),這一點非常重要。

+0

謝謝你 – victor 2014-12-11 15:57:19