2011-07-08 8 views
1

Dans MVC2, la validation que j'utilise pour une liste déroulante fonctionne;MVC3: Comment valider une liste déroulante?

<tr> 
        <td align="right"> 
         <%: Html.LabelFor(model => model.contract.ContractTypeId)%><span class="error">*</span> 
        </td>      
        <td> 
         <%: Html.DropDownListFor(model => model.contract.ContractTypeId, Model.contractTypesSelectList, "<--Select-->")%> 
         <%: Html.ValidationMessageFor(model => model.contract.ContractTypeId)%> 
        </td> 
       </tr> 

et avec l'annotation de données;

 [DisplayName("Contract Prefix")] 
     [UIHint("DropDownList")] 
     [Required(ErrorMessage = "You must select a Contract Prefix")] 
     public int ContractTypeId { get; set; } 

Si j'essaye cela dans MVC3, cela ne fonctionne plus;

  <tr> 
       <td align="right"> 
        @Html.LabelFor(model => model.contract.ContractTypeId)<span class="error">*</span> 
       </td>      
       <td> 
        @Html.DropDownListFor(model => model.contract.ContractTypeId, Model.contractTypesSelectList, "<--Select-->") 
        @Html.ValidationMessageFor(model => model.contract.ContractTypeId) 
       </td> 
      </tr> 

annotation de données;

[DisplayName("Contract Prefix")] 
    [UIHint("DropDownList")] 
    [Required(ErrorMessage = "You must select a Contract Prefix")] 
    public int ContractTypeId { get; set; } 

Qu'est-ce que je fais mal?

EDIT

En fait, ce qui se passe est que lorsque je clique sur soumettre, les autres champs sont en perte de vitesse comme non valide. Lorsque je les corrige et que je clique sur Soumettre, les indicateurs déroulants ne sont plus valides. Donc ça fonctionne, mais ça devrait marcher tous en même temps, plutôt que dans cette séquence.

Mon contrôleur est; #region CREER /* ** * **** * CREER * ** * * */ [(Rôles = Autoriser "opérateur de saisie, Administrateur")] public ViewResult Create() { return (nouveau ContractViewModel()); }

// 
    // POST: /Contract/Create 

    [Authorize(Roles = "Inputter,Administrator")] 
    [HttpPost] 
    public ActionResult Create(ContractViewModel contractViewModel) 
    { 
     if (ModelState.IsValid) 
     { 
      CapitaliseNames(ref contractViewModel); 
      int contractId = contractViewModel.contract.Add(); 
      // Store the Addresses for Client and Contract Administrator on the database, 
      // and store the Ids of the new addresses on the Contract object. 
      contractViewModel.clientContact.ContractId = contractId; 
      contractViewModel.contractAdministratorContact.ContractId = contractId; 

      int clientContactId = contractViewModel.clientContact.Add(); 
      int contractAdministratorContactId 
       = contractViewModel.contractAdministratorContact.Add(); 
      contractViewModel.contract.Update(clientContactId, contractAdministratorContactId); 
      return RedirectToAction("List"); 
     } 
     return View(new ContractViewModel()); 
    } 

    private static void CapitaliseNames(ref ContractViewModel contractViewModel) 
    { 
     contractViewModel.clientContact.ContactName = contractViewModel.clientContact.ContactName.UppercaseFirst(); 
     contractViewModel.clientContact.NameOfContact = contractViewModel.clientContact.NameOfContact.UppercaseFirst(); 
     contractViewModel.contractAdministratorContact.ContactName = contractViewModel.contractAdministratorContact.ContactName.UppercaseFirst(); 
     contractViewModel.contractAdministratorContact.NameOfContact = contractViewModel.contractAdministratorContact.NameOfContact.UppercaseFirst(); 
    } 
    #endregion 

My View est; @model HITOC.Models.ContractViewModel

@{ 
    ViewBag.Title = "Create"; 
} 

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script> 
<script type="text/javascript" language="javascript"> 
    $(document).ready(function() { 
     $('#contract_ContractNo_Letter').setMask({ mask: 'a' }); 
     $('#contract_ContractNo_Number').setMask({ mask: '999', type: 'reverse' }); 
     $('#contract_ContractPeriodInWeeks').setMask({ mask: '999', type: 'reverse' }); 
     $('#contract_ContractValue').setMask({ mask: '99.999999999999', type: 'reverse', defaultValue: '000' }); 
    }); 
</script> 
@using (Html.BeginForm()) { 
    @Html.ValidationSummary(true) 
     <h1>CREATE an Instruction to Open File Form</h1> 
     <hr /> 
     <p>DIRECTOR OR HEAD OF DIVISION <b>ONLY</b> TO INSTRUCT</p> 
     <fieldset> 
      <legend>Enter the contract details here:</legend> 
      <p>Where you see <span class="error">*</span> you must enter data.</p> 
      <table> 
       <tr> 
        <td align="right"> 
         @Html.LabelFor(model => model.contract.SignOffDate)<span class="error">*</span> 
        </td>      
        <td> 
         @Html.EditorFor(model => model.contract.SignOffDate) 
         @Html.ValidationMessageFor(model => model.contract.SignOffDate) 
        </td> 
       </tr> 
       <tr> 
        <th colspan="2">-- Enter Contract Number</th> 
       </tr> 
       <tr> 
        <td align="right"> 
         @Html.LabelFor(model => model.contract.ContractTypeId)<span class="error">*</span> 
        </td>      
        <td> 
         @Html.DropDownListFor(model => model.contract.ContractTypeId, Model.contractTypesSelectList, "<--Select-->") 
         @Html.ValidationMessageFor(model => model.contract.ContractTypeId) 
        </td> 
       </tr> 
       <tr> 
        <td align="right"> 
         @Html.LabelFor(model => model.contract.ContractNo_Letter)<span class="error">*</span> 
        </td>      
        <td> 
         @Html.TextBoxFor(model => model.contract.ContractNo_Letter, 
          new { autocomplete = "off", maxlength = "1", style = "width:15px;text-transform: uppercase;" }) 
         @Html.ValidationMessageFor(model => model.contract.ContractNo_Letter) 
        </td> 
       </tr> 
       <tr> 
        <td align="right"> 
         @Html.LabelFor(model => model.contract.ContractNo_Number)<span class="error">*</span> 
        </td>      
        <td> 
         @Html.TextBoxFor(model => model.contract.ContractNo_Number, 
          new { autocomplete = "off", maxlength = "3", style = "width:30px;" }) 
         @Html.ValidationMessageFor(model => model.contract.ContractNo_Number) 
        </td> 
       </tr> 
       <tr> 
        <td align="right"> 
         @Html.LabelFor(model => model.contract.ContractNo_Suffix) 
        </td>      
        <td> 
         @Html.TextBoxFor(model => model.contract.ContractNo_Suffix, 
          new { maxlength = "2", style = "width:30px;text-transform: uppercase;" }) 
        </td> 
       </tr> 
       <tr> 
        <th colspan="2">-- Enter Estimate and Order Details</th> 
       </tr> 
       <tr> 
        <td align="right"> 
         @Html.LabelFor(model => model.contract.EstimateNumber)<span class="error">*</span> 
        </td>      
        <td> 
         @Html.TextBoxFor(model => model.contract.EstimateNumber, 
          new { autocomplete = "off", style = "text-transform: uppercase;" }) 
         @Html.ValidationMessageFor(model => model.contract.EstimateNumber) 
        </td> 
       </tr> 
       <tr> 
        <td align="right"> 
         @Html.LabelFor(model => model.contract.ClientOrderNumber) 
        </td>      
        <td> 
         @Html.EditorFor(model => model.contract.ClientOrderNumber) 
        </td> 
       </tr> 
       <tr> 
        <td align="right"> 
         @Html.LabelFor(model => model.contract.InstructionWithoutClientOrder)<br /> 
         (Only if no Client Order Number) 
        </td>      
        <td> 
         @Html.TextAreaFor(model => model.contract.InstructionWithoutClientOrder, 
          new { maxlength = "255", style = "width:200px;height:100px;"}) 
        </td> 
       </tr> 
       <tr> 
        <td align="right"> 
         @Html.LabelFor(model => model.contract.GivenDate)<span class="error">*</span> 
        </td>      
        <td> 
         @Html.EditorFor(model => model.contract.GivenDate) 
         @Html.ValidationMessageFor(model => model.contract.GivenDate) 
        </td> 
       </tr> 
       <tr> 
        <th colspan="2">-- Enter Client Details</th> 
       </tr> 
       <tr> 
        <td align="right"> 
         Client Organisation Name<span class="error">*</span> 
        </td>      
        <td> 
         @Html.TextBoxFor(model => model.clientContact.ContactName, new { autocomplete = "off", style = "text-transform: capitalize;" }) 
         @Html.ValidationMessageFor(model => model.clientContact.ContactName) 
        </td> 
       </tr> 
       <tr> 
        <td align="right"> 
         Client Address<span class="error">*</span> 
        </td>      
        <td> 
         @Html.EditorFor(model => model.clientContact.AddressLine1) 
         @Html.ValidationMessageFor(model => model.clientContact.AddressLine1) 
        </td> 
       </tr> 
       <tr> 
        <td></td>      
        <td> 
         @Html.EditorFor(model => model.clientContact.AddressLine2) 
        </td> 
       </tr> 
       <tr> 
        <td align="right"> 
         Post code<span class="error">*</span> 
        </td>      
        <td> 
         @Html.TextBoxFor(model => model.clientContact.PostCode, 
          new { autocomplete = "off", style = "text-transform: uppercase;" }) 
         @Html.ValidationMessageFor(model => model.clientContact.PostCode) 
        </td> 
       </tr> 
       <tr> 
        <td align="right"> 
         Name of contact 
        </td>      
        <td> 
         @Html.TextBoxFor(model => model.clientContact.NameOfContact, new { autocomplete = "off", style = "text-transform: capitalize;" }) 
         @Html.ValidationMessageFor(model => model.clientContact.NameOfContact) 
        </td> 
       </tr> 
       <tr> 
        <td align="right"> 
         Tel No 
        </td>      
        <td> 
         @Html.EditorFor(model => model.clientContact.Phone) 
         @Html.ValidationMessageFor(model => model.clientContact.Phone) 
        </td> 
       </tr> 
       <tr> 
        <th colspan="2">-- Enter Contract Administrator Details</th> 
       </tr> 
       <tr> 
        <td></td> 
        <td><input id="chkCopyContact" type="checkbox" name="chkCopyContact" /> Click here to copy across the client contact details </td> 
       </tr> 
       <tr> 
        <td align="right"> 
         Name<span class="error">*</span> 
        </td>      
        <td> 
         @Html.TextBoxFor(model => model.contractAdministratorContact.ContactName, new { autocomplete = "off", style = "text-transform: capitalize;" }) 
         @Html.ValidationMessageFor(model => model.contractAdministratorContact.ContactName) 
        </td> 
       </tr> 
       <tr> 
        <td align="right"> 
         Address<span class="error">*</span> 
        </td>      
        <td> 
         @Html.EditorFor(model => model.contractAdministratorContact.AddressLine1) 
         @Html.ValidationMessageFor(model => model.contractAdministratorContact.AddressLine1) 
        </td> 
       </tr> 
       <tr> 
        <td></td>      
        <td> 
         @Html.EditorFor(model => model.contractAdministratorContact.AddressLine2) 
        </td> 
       </tr> 
       <tr> 
        <td align="right"> 
         Post code<span class="error">*</span> 
        </td>      
        <td> 
         @Html.TextBoxFor(model => model.contractAdministratorContact.PostCode, 
          new { autocomplete = "off", style = "text-transform: uppercase;" }) 
         @Html.ValidationMessageFor(model => model.contractAdministratorContact.PostCode) 
        </td> 
       </tr> 
       <tr> 
        <td align="right"> 
         Name of contact 
        </td>      
        <td> 
         @Html.TextBoxFor(model => model.contractAdministratorContact.NameOfContact, 
          new { autocomplete = "off", style = "text-transform: capitalize;" }) 
         @Html.ValidationMessageFor(model => model.contractAdministratorContact.NameOfContact) 
        </td> 
       </tr> 
       <tr> 
        <td align="right"> 
         Tel No 
        </td>      
        <td> 
         @Html.EditorFor(model => model.contractAdministratorContact.Phone) 
         @Html.ValidationMessageFor(model => model.contractAdministratorContact.Phone) 
        </td> 
       </tr> 
       <tr> 
        <th colspan="2">-- Enter Contract Title/Address</th> 
       </tr> 
       <tr> 
        <td align="right"> 
         @Html.LabelFor(model => model.contract.ContractTitle)<span class="error">*</span> 
        </td>      
        <td> 
         @Html.EditorFor(model => model.contract.ContractTitle) 
         @Html.ValidationMessageFor(model => model.contract.ContractTitle) 
        </td> 
       </tr> 
       <tr> 
        <td></td>      
        <td> 
         @Html.EditorFor(model => model.contract.ContractAddressLine1) 
        </td> 
       </tr> 
       <tr> 
        <td></td>      
        <td> 
         @Html.EditorFor(model => model.contract.ContractAddressLine2) 
        </td> 
       </tr> 
       <tr> 
        <td align="right"> 
         Post code<span class="error">*</span> 
        </td>      
        <td> 
         @Html.TextBoxFor(model => model.contract.ContractPostCode, 
          new { autocomplete = "off", style = "text-transform: uppercase;" }) 
         @Html.ValidationMessageFor(model => model.contract.ContractPostCode) 
        </td> 
       </tr> 
       <tr> 
        <th colspan="2">-- Enter Work Description</th> 
       </tr> 
       <tr> 
        <td align="right"><span class="error">*</span></td>      
        <td > 
         @Html.TextAreaFor(model => model.contract.WorkDescription, 
          new { maxlength = "255", style = "width:200px;height:100px;" }) 
         @Html.ValidationMessageFor(model => model.contract.WorkDescription) 
        </td> 
       </tr> 
       <tr> 
        <th colspan="2">-- Enter Contract Details</th> 
       </tr> 
       <tr> 
        <td align="right"> 
         @Html.LabelFor(model => model.contract.StartDate) 
        </td>      
        <td> 
         @Html.EditorFor(model => model.contract.StartDate) 
         @Html.ValidationMessageFor(model => model.contract.StartDate) 
        </td> 
       </tr> 
       <tr> 
        <td align="right"> 
         @Html.LabelFor(model => model.contract.ContractPeriodInWeeks)<span class="error">*</span> 
        </td>      
        <td> 
         @Html.TextBoxFor(model => model.contract.ContractPeriodInWeeks, new { style = "width:30px" }) 
         @Html.ValidationMessageFor(model => model.contract.ContractPeriodInWeeks) 
        </td> 
       </tr> 
       <tr> 
        <td align="right"> 
         @Html.LabelFor(model => model.contract.OperationsManagerUserId)<span class="error">*</span> 
        </td>      
        <td> 
         @Html.DropDownListFor(model => model.contract.OperationsManagerUserId, Model.operationManagerSelectList, "<--Select-->") 
         @Html.ValidationMessageFor(model => model.contract.OperationsManagerUserId) 

        </td> 
       </tr> 
       <tr> 
        <td align="right"> 
         @Html.LabelFor(model => model.contract.ContractValue) 
        </td>      
        <td> 
         @Html.TextBoxFor(model => model.contract.ContractValue, new {style = "width:120px" }) 
         (Leave as zero if not decided yet). 
         @Html.ValidationMessageFor(model => model.contract.ContractValue) 
        </td> 
       </tr> 
       <tr> 
        <td align="center" colspan="2" style="padding-top:20px;"><input type="submit" value="Create" /></td> 
       </tr> 
      </table> 
     </fieldset> 
} 

<div> 
    @Html.ActionLink("Back to List", "List") 
</div> 

Répondre

3

Votre modèle de vue n'a pas de sens. Vous mettez l'attribut Required sur une propriété entière non nullable qui aura toujours une valeur (0 dans votre cas). Alors, commencez par modifier votre modèle de vue:

[DisplayName("Contract Prefix")] 
[UIHint("DropDownList")] 
[Required(ErrorMessage = "You must select a Contract Prefix")] 
public int? ContractTypeId { get; set; } 

Maintenant vous pouvez avoir des listes déroulantes avec des valeurs nulles:

@Html.DropDownListFor(
    x => x.contract.ContractTypeId, 
    Model.contractTypesSelectList, 
    "<--Select-->" 
) 
@Html.ValidationMessageFor(x => x.contract.ContractTypeId) 

Ensuite, si vous voulez faire la validation côté client dans ASP.NET MVC 3, jQuery et les plugins jQuery validate sont utilisés pour cela. Donc, assurez-vous que vous avez inclus les scripts suivants à votre page:

  • jquery.validate.js
  • jquery.validate.unobtrusive.js

Assurez-vous également que votre action contrôleur reçoit correctement la valeur sélectionnée:

[HttpPost] 
public ActionResult Foo(MyViewModel model) 
{ 
    if (!ModelState.IsValid) 
    { 
     // there was an error => redisplay the view 
     return View(model); 
    } 

    // model.contract.ContractTypeId will contain a value 
    // at this stage here => use it to do some processing 
    ... 
} 
+0

J'ai essayé votre solution et il n'a pas résolu le problème. En fait, j'étais imprécis avec ma question, alors je vais l'éditer maintenant. – arame3333

+0

@ arame3333, c'est bizarre quand vous dites que ma solution n'a pas fonctionné car j'utilise le code comme ça dans beaucoup de mes projets et ça a toujours fonctionné sans problème. –

+0

J'aurais dû mieux formuler mon dernier commentaire, vous pouvez voir dans mon edit que le problème est différent de ce que je pensais. – arame3333

Questions connexes