2011-01-06 153 views
2

我有2個場景,我需要一些幫助,在我的ASP.NET MVC應用程序重新驗證。我知道在控制器內進行驗證並不理想,所以我希望將其保存在其他地方 - 也許我可以在我的模型上進行驗證。ASP.NET MVC驗證

1)我有一個模型與各種屬性,其中一些使用DataAnnotations對他們進行驗證。然後,我使用我的視圖中的Html幫助器方法在相關字段中公開任何驗證錯誤。在大多數情況下,這些工作如預期。我遇到的例外情況是我的視圖中的一個字段是下拉列表。我列表中的第一項是空的/空白的,其餘是真正的值。這一領域涉及在我的模型的屬性有以下反對:

[Required(ErrorMessage = "A value from the list is required")] 

目前,如果我離開的默認值列表(空白),並沒有從列表中選擇一個真正的價值,我希望它呈現驗證錯誤消息,但它現在將它當作一個有效值處理,並傳遞該驗證。

如果提交的空白/空列表項目被提交,我怎樣才能使它失敗驗證?

2)在我的觀點之一,我有幾個文件上傳控件,使用戶能夠上傳圖像到網站。這些字段不會直接綁定到我的模型中的任何屬性 - 只有生成的文件名(一旦文件被上傳,轉換,重命名等)被分配到我的模型中的'Filename1','Filename2'等屬性。

所以,我想知道如何最好地驗證這些強制性文件上傳?目前我做的每一個文件上傳控件的下面,我的控制器內(!):

HttpPostedFileBase file = null; 

file = Request.Files["Filename1"]; 
     if (file != null && file.ContentLength == 0) 
       ModelState.AddModelError("Filename1", "Image1 is required"); 

一旦爲每個文件上傳控件完成的,我檢查ModelState中是有效的:

if (ModelState.IsValid) 

我敢肯定,必須有執行此驗證的一種更好的方式,和我想像這是不理想有這個控制器,但我不知道最好的方式來處理這個問題。

我很感謝這兩種情況的任何幫助。

回答

0

這裏是我的代碼(解釋後):

形式:

<% using (Html.BeginForm("TestForm", "Home", FormMethod.Post, new { enctype = "multipart/form-data" })) 
    { %> 
    <%: Html.DropDownList("ComboboxValue", new SelectList(Model.ComboboxValues)) %><br /> 
    <input type="file" id="FileUpload" name="FileUpload" /><br /> 
    <input type="submit" id="submit" name="submit" value="Valider" /> 
<%} %> 

型號:

public class TestFormModel 
{ 
    [Required(ErrorMessage = "A value from the list is required")] 
    public string ComboboxValue { get; set; } 

    public List<string> ComboboxValues { get; set; } 

    public HttpPostedFileBase FileUpload { get; set; } 

    public ModelStateDictionary IsFileValid() 
    { 
     ModelStateDictionary modelState = new ModelStateDictionary(); 
     modelState.AddModelError("FileUpload", "Here is the problem."); 
     return modelState; 
    } 

控制器:

public ActionResult TestForm() 
    { 
     TestFormModel model = new TestFormModel(); 
     model.ComboboxValues = new List<string>(){ 
      "", "Red", "Blue", "Yellow" 
     }; 
     return View("TestForm", model); 
    } 
    [HttpPost] 
    public ActionResult TestForm(TestFormModel model) 
    { 
     model.ComboboxValues = new List<string>(){ 
      "", "Red", "Blue", "Yellow" 
     }; 
     ModelState.Merge(model.IsFileValid()); 
     return View("TestForm", model); 
    } 

1)如果你有一個空值,你的模型不會是有效的。

2)爲了避免Request.Files [ 「FILENAME1」];你可以「鍵入」你的表單(new {enctype =「multipart/form-data」})。 有了這個,你的模型將包含該文件。 您可以添加一個擴展方法,例如:

public static bool IsCSVValid(this HttpPostedFileBase file) 
{ 
    return (file != null && file.ContentLength != 0 && file.FileName.EndsWith(".CSV", StringComparison.InvariantCultureIgnoreCase)); 
} 

而且你可以從某處ModelState.Merge添加錯誤()。

我不知道它是否是一個「做一件好事」,但它工作得很好:)

0

對於#1,下拉列表中發佈的值是多少?以及您試圖綁定的模型中的類型是什麼?如果它發佈了一個像「」的值,那麼它將通過驗證。如果你的類型是一個字符串,你需要確保它是一個空字符串。

對於#2,您可以嘗試編寫自定義模型聯編程序,但不知道如何訪問這些文件會有多醜。另一種選擇是讓它在行動結果的參數的一部分:

public ActionResult Test(TestModel model, HttpPostedFileBase files) 

這至少會做自動文件是否存在對您具有約束力,但你仍然要執行手動驗證,就像您做之前。我知道它不是你正在尋找的確切答案,但它確實清理了更多的文件代碼。

而且,這個問題可能會幫助更多一點:ASP.NET MVC posted file model binding when parameter is Model

0

見不着就像你在ASP.net動態數據的工作。如果是的話,ASP.Net動態數據在模塊視圖控制的概念上工作。

在MVC中加載列的控件取決於類的元數據。它讀取類的數據類型,然後相應地加載控件。如果您對這些控件進行任何更改,將會影響其他地方。

頂部處理這應該創建新控件並在該控件中進行驗證,並在該列的類中指定它應該使用您的自定義控件。

如果您需要更多關於如何自定義控件的詳細信息,請告訴我們。