views:

238

answers:

0

Hi,

I want to do some server side validation that is done on Action not in model (dataannatations).

if(ok) //somecode else {
ModelState.AddModelError("", "Some error"); }

For that example I don't get any notification with validation summary. Even if I put property name from model into AddModelError methods it don't work. I tryed to throw new RuleException("","Some error"), but on method View(); I get Exception that RuleException was thrown.

Update:

After some research I found that it might be problem with my control ( partial view). I`m using strongly typed partial View with ajax and after ajax submit my html isn't replaced.

I done replace on form element after ajax post, and my error from ModelState is visible but xval don't generate that error, so mu validation summary is empty I have only field validation text.

Update

Hopefully I found solution to this:)

  • Remove Ajax.BeginForm() - replace it with ajax.post() example1.
  • Use $('#formid').valid() - method for validation:)
  • Changed xval script to show/hide element validation from partial view ( <%: Html.ValidationMessageFor(model => model.Last)%> )

$.Ajax() :

    $.ajax({
        type: "POST",
        url: $("#form1").attr("action"),
        data: $("#form1").serialize(),
        success: function (html) {                    
            $('#form1').replaceWith(html);
            $('#form1').valid();
            alert("epic win!!")
        },
        error: function (XMLHttpRequest, textStatus, errorThrown) {
            alert("epic fail!")

        }
    });

replaceWith - to replace old html with new one from server.

But I don't like to write so much code evrytime I want to have submit so here is simple plugin for JQ :

// plugin definition
$.fn.MVCFormSubmit = function (options) {
    // Extend our default options with those provided.
    // Note that the first arg to extend is an empty object -
    // this is to keep from overriding our "defaults" object.
    var opts = $.extend({}, $.fn.MVCFormSubmit.defaults, options);
    opts.FormID = '#' + opts.FormID;
    opts.ProgressContetnId = '#' + opts.ProgressContetnId;
    // Our plugin implementation code goes here.
    $(opts.ProgressContetnId).show();
    $.ajax({
        type: opts.type,
        url: $(opts.FormID).attr("action"),
        data: $(opts.FormID).serialize(),
        success: function (html) {
            $(opts.FormID).replaceWith(html);
            $(opts.FormID).valid();
            alert("epic win!!!1!1!")
            $(opts.ProgressContetnId).hide();
        },
        error: function (XMLHttpRequest, textStatus, errorThrown) {
            alert("epic fail!")
            $(opts.ProgressContetnId).hide();

        }
    });

};
// plugin defaults - added as a property on our plugin function
$.fn.MVCFormSubmit.defaults = {
    type: 'POST',
    FormID: '#',
    ProgressContetnId:"#AjaxInfo"
};

Addition feature here is progressContentID some ajax info :)

Ok Now example Partial View :

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ValidationTest.Models.SampleForm>" %>
<% using (Html.BeginForm("ValidateSampleModelControl", "Home", FormMethod.Post, new { id = "form1" }))
   {%>
<div id="summary1">
    <%: Html.ValidationSummary(true,"") %>
</div>
<% Html.EnableClientValidation(); %>
<fieldset>
    <legend>Fields</legend>
    <div class="editor-label">
        <%: Html.LabelFor(model => model.Name)%>
    </div>
    <div class="editor-field">
        <%: Html.TextBoxFor(model => model.Last)%>
        <%: Html.ValidationMessageFor(model => model.Last)%>
    </div>
    <div class="editor-label">
        <%: Html.LabelFor(model => model.Last)%>
    </div>
    <div class="editor-field">
        <%: Html.TextBoxFor(model => model.Name)%>
        <%: Html.ValidationMessageFor(model => model.Name)%>
    </div> 
</fieldset>
<div id="prgoressID" class="ajax_progress">
    Ajax Progress.......</div>
<%= Html.ClientSideValidation<ValidationTest.Models.SampleForm>().UseValidationSummary("summary1") %>
<div id="testClick">
    Click me ajax</div>
<% } %>
<script type="text/javascript">
    $('#testClick').click(function () {
        $('#form1').MVCFormSubmit(
            {
                FormID: "form1",
                ProgressContetnId: "prgoressID"
            });

        return false;
    });      
</script>

Action :

public ActionResult ValidateSampleModelControl(SampleForm form)
{
    if (ModelState.IsValid)
    {
    }
    ModelState.AddModelError("", "Some Error");
    return View();
}

SampleForm :

public class SampleForm { [Required] public string Name { get; set; } [Required] public string Last { get; set; } public DateTime Time { get; set; } }

XVal Script Change :

highlight: function(element) { 
                    $(element).addClass("input-validation-error");  

                    $(element).next().show();
                     },
                    unhighlight: function(element) {
                     $(element).removeClass("input-validation-error");
                     $(element).next().hide();
                      }

So here I only Added $(element).next().hide() /show() to hide/show from field validation message (DataAnnotation).