1

I Have a form inside a Partial view that is rendered inside a tab on a tab control that looks like this:

@model USARAFSyncMVC.Areas.Event.Models.EventFullScaffoldModel

@using (Ajax.BeginForm("SaveMainEventDetails", "Event", new { area = "Event" },
    new AjaxOptions { UpdateTargetId = "FormWrapper", OnComplete = "SetSuccessLabel", InsertionMode = InsertionMode.Replace },
    new { method = "post" }))
{
    @Html.Hidden("eventType", "1", new { id = "eventType" })
    <div id="FormWrapper">
      <hr />
      <table border="0">
        <tr>
          <td>Title</td>
          <td>@Html.TextBoxFor(model => model.Title, new { style = "width:300px" })
            @Html.ValidationMessageFor(model => model.Title)</td>

        </tr>
        <tr>
          <td>OPR</td>
          <td> @Html.EditorFor(model => model.OPRID)</td>

        </tr>
        <tr>
          <td>Organization</td>
          <td> @Html.EditorFor(model => model.DomainID)</td>

        </tr>
        <tr>
          <td>POC</td>
          <td> @Html.EditorFor(model => model.POC)</td>

        </tr>
        <tr>
          <td>Location</td>

          <td>
            @Html.EditorFor(model => model.LocationID)
          </td>

        </tr>
        <tr>
          <td>Dates</td>
          <td>
            <table>
              <tr>
                <th>@Html.LabelFor(m => m.StartDate)</th>
                <th> @Html.LabelFor(m => m.EndDate)</th>
              </tr>
              <tr>
                <td> @Html.EditorFor(m => m.StartDate)</td>
                <td>@Html.EditorFor(m => m.EndDate)</td>
              </tr>

            </table>

            <table id="DeployRedeployDiv">
              <tr>
                <th>Deploy</th>
                <th>ReDeploy</th>
              </tr>
              <tr>
                <td> @Html.EditorFor(m => m.EstimatedDeployDate)</td>
                <td>@Html.EditorFor(m => m.EstimatedReDeployDate)</td>
              </tr>

            </table>

          </td>
        </tr>
        <tr>
          <td>OSRs</td>
          <td>
            @(Html.Telerik()
                  .PanelBar()
                  .Name("PanelBar")
                  .HtmlAttributes(new { style = "width:300px;" })
                  .Items(o => o.Add().Text("Click").Content(@<text> 

                @Html.CheckBoxList("OprList",
                    x => x.OprList,
                    x => x.OPRID,
                    x => x.AltTitle,
                    x => x.EventOSRs, Position.Vertical)</text>).Expanded(false)))
          </td>
        </tr>
        <tr>
          <td>Purpose</td>
          <td> @Html.TextBoxFor(model => model.Why, new { style = "width: 400px; height:200px" })</td>
        </tr>
        <tr>
          <td>Background</td>
          <td> @Html.TextBoxFor(model => model.What, new { style = "width: 400px; height:200px" })</td>
        </tr>
        <tr>
          <td>Viewable</td>
          <td> @Html.CheckBoxFor(model => model.Viewable)</td>
        </tr>

      </table>
      <div>
        <input class="t-button" type="submit" name="button" value="Save" />

      </div>

    </div>

}

Here is the Controller:

    [HttpPost]
    public ActionResult SaveMainEventDetails(EventFullScaffoldModel model, string[] OprList, string eventType, string cbLoc, string cbOpr, string cbOrg)
    {
        if (OprList != null)
        {
            model.EventOSRs = miscRepository.GetOprsList().ToModel().Where(o => OprList.Contains(o.OPRID.ToString())).ToList();
        }

        model.Type = int.Parse(eventType);
        model.LocationID = cbLoc;
        model.OPRID = int.Parse(cbOpr);
        model.DomainID = int.Parse(cbOrg);
        eventRepository.Insert(model.ToDto());
        return View();
    }

Here is the Model:

   public partial class EventFullScaffoldModel
    {
        public Int32 EventID { get; set; }

        [Required(ErrorMessage = "Required!")]
        public String Title { get; set; }

        [Required(ErrorMessage = "Required!")]
        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:dd-MM-yyyy}")]
        public DateTime StartDate { get; set; }

        [Required(ErrorMessage = "Required!")]
        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:dd-MM-yyyy}")]
        public DateTime EndDate { get; set; }

        [Required(ErrorMessage = "Required!")]
        public String What { get; set; }

        [Required(ErrorMessage = "Required!")]
        public String Why { get; set; }

        public Nullable<DateTime> Modified { get; set; }

        public String ModifiedBy { get; set; }

        public Nullable<DateTime> Created { get; set; }

        public String CreatedBy { get; set; }

        [UIHint("ActiveDirectoryLoadOnDemand"), Required]
        public String POC { get; set; }

        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:MM-dd-yyyy}")]
        public Nullable<DateTime> EstimatedDeployDate { get; set; }

        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:MM-dd-yyyy}")]
        public Nullable<DateTime> EstimatedReDeployDate { get; set; }

        public Nullable<Int32> TSCMISID { get; set; }

        public Nullable<Int32> ReviewStatus { get; set; }

        public int? Type { get; set; }

        public String InactivityReason { get; set; }

        public Boolean Viewable { get; set; }

        public string OPRAltTitle { get; set; }

        [UIHint("OprDropDown"), Required]
        public int OPRID { get; set; }

        [UIHint("OrgDropDown"), Required]
        public int DomainID { get; set; }

        [UIHint("LocationsLoadOnDemand"), Required]
        public string LocationID { get; set; }

        public string LocationTitle { get; set; }

        public IList<OsrModel> EventOSRs { get; set; }

        public IList<TargetAndEffectModel> EventTargetEffects { get; set; }

        public IList<AssociationModel> EventAssociations { get; set; }

        public IList<EventObjectiveModel> EventObjectives { get; set; }

        public IList<StrategicObjectiveModel> EventTSOs { get; set; }

        public IList<TaskModel> EventTasks { get; set; }

        public IList<PaxModel> EventPaxBreakDowns { get; set; }

        public IList<FundingModel> EventFundings { get; set; }

        public IList<UnitModel> EventExecutingUnits { get; set; }

        public IList<OsrModel> OprList { get; set; }

        public IList<ObjectiveModel> ObjectiveList { get; set; }

        public IList<StrategicObjectiveModel> StrategicList { get; set; }

        public IList<OrgModel> OrgsList { get; set; }
    }

The Model NEVER get validated and runs straight through the transaction on the controller. Why is this not working?

Ryan Lege
  • 167
  • 1
  • 2
  • 16

5 Answers5

4

I suggest first to check whether you have included the necessary javascript files for unobtrusive validation in the right order and that will make the validation happen successfully at the client-side.

Regarding the server side validation as other told basically you have to save the model to the database by explicitly checking ModelState.IsValid. Since you are making an AJAX call I may suggest you to return the model state errors as JSON.

So in the OnFailure method of the AjaxOptions you can parse the JSON and display the errors as a summary in a div.

Basically you can follow this pattern.

[HttpPost]
public JsonResult SaveMainEventDetails(..)
{
  if(ModelState.IsValid)
  {
    .. save to database

    return Json(new{ success = true });
  }

  var errorDict =  ModelState..
  return Json(new { success = false, errors = errorDict });
}
VJAI
  • 32,167
  • 23
  • 102
  • 164
2

You need to explicitly check whether ModelState.IsValid in the action, and return to the edit view if it isn't.
If you show the edit view for an invalid model, MVC will automatically display error messages through the Validate helpers.

Buildstarted
  • 26,529
  • 10
  • 84
  • 95
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
0

This should shed some light: What is ModelState.IsValid valid for in ASP.NET MVC in NerdDinner?

Basically you have to trigger model validation by using ModelState.IsValid

Community
  • 1
  • 1
LukeP
  • 10,422
  • 6
  • 29
  • 48
  • I tried this and it even when returning false and returning the partial view it still does not validate. – Ryan Lege Jun 29 '12 at 14:03
0

Add @{ Html.EnableClientValidation(); } in View

and refer thsi link for more details How to: Validate Model Data Using DataAnnotations Attributes

swapneel
  • 3,061
  • 1
  • 25
  • 32
  • No that did not work either. Could it be something with Ajax? The model is validating but on return it does not render the errors – Ryan Lege Jun 29 '12 at 14:18
  • are you using correct required Js files? jquery.unobtrusive-ajax.js, jquery.validate.unobtrusive.js – swapneel Jun 29 '12 at 14:19
0

Ok the problem was the Telerik Script Registrar was not referencing the proper JQuery. Now it is working. I was referencing the JQuery library directly, also the validation scripts. On the Telerik script Registrar, it is already a part of the default group , re-referencing them as I was doing, caused it to freak out for some reason. Only add references to scripts not apart of the original default group. For more info on that, one needs to read the online documentation for this MVC extension.

Ryan Lege
  • 167
  • 1
  • 2
  • 16