Category Archives: ValidationSummary

ValidationSummary

[RESOLVED]Model state still returns false after I make changes as per the required validations.

My Model state still returns false after I make changes as per the  required validations.

 [HttpPost]
        public ActionResult InsertProject(Project project, HttpPostedFileBase ImageFile = null)
        {

            project.RegistrationId = 1;//Testing
            if (ModelState.IsValid)
            {
                if (ImageFile != null)
                {
                    project.ImageType = ImageFile.ContentType;
                    project.Image = new byte[ImageFile.ContentLength];
                    ImageFile.InputStream.Read(project.Image, 0, ImageFile.ContentLength);
                }
                repository.InsertProject(project);
                return RedirectToAction("List");
            }
            
            return View();
        }

This is part of my view

@using (Html.BeginForm("InsertProject", "Project", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    if (ViewData.ModelState.Keys.Any(k => ViewData.ModelState[k].Errors.Count() > 0))
    { 
   <div class="alert alert-warning">@Html.ValidationSummary()</div>
    }

So when user inputs wrong data, validation summary shows up. After making the required changes when user submits the form, the model state is still invalid. I’m pretty new to mvc. Could you please guide me.

Thanks,

Rose

Show also the Project class code. Which validators you have on it? 

 
@OP: I didn’t answer the question, I only asked to show code around Project class. Please unmark my post as an answer, If your problem is solved then you can update the post.

Yes..Show also the Project class code. Which validators you have on it? this will help us to understand the actual reason for Failing your required field. 

[RESOLVED]How to display a default value in Cascading DropDownList using Java Script and MVC4

I have 2 Cascading DropDownLists (State and Cities) .

I populate cities when I select a State.

In the Cities Dropdown list, the default value is not displayed but all the related Cities are displayed.

Can someone please help to populate a default value in Cities Dropdown list?

The following is my model for State and Cities DropDown list

public class AustraliaStates
    {
        [Key]
        [Required]
        public string AustraliaStateId { get; set; }
        [Required]
        public string AustraliaStateName { get; set; }
    }

    public class AustraliaCities
    {
        [Key]
        [Required]
        public string AustraliaCityId { get; set; }

        [Required]
        public string AustraliaCityName { get; set; }
        
        [Required]
        public string AustraliaStateId { get; set; }
        
    }

Accommodation View.cshtml

      <form name="datapluspics" method="post" enctype="multipart/form-data">
                    @Html.ValidationSummary(true)
                    <fieldset>
                    @*Form Display Table START here*@
                    <table class="FormTableStyle" >
                                                
                        <tr>
                            <td class="FormDisplayLeftTableStyle">
                                <div class="editor-label">
                                    @Html.LabelFor(model => model.Suburb)
                                </div>
                            </td>
                            <td class="FormDisplayRightTableStyle">
                                <div class="editor-field">
                                    : @Html.EditorFor(model => model.Suburb)
                                    @Html.ValidationMessageFor(model => model.Suburb)
                                </div>
                            </td>    
                        </tr>

                        <tr>
                            <td class="FormDisplayLeftTableStyle">
                                <div class="editor-label">
                                    @Html.LabelFor(model => model.State)
                                </div>
                            </td>

                            <td class="FormDisplayRightTableStyle">
                                <div class="editor-field">
                                            <div>
                                             : @Html.DropDownListFor(model => model.SelectedAustraliaStateId, Model.AustraliaStates, "Select a state", new { id = "States", @class = "DropDownFieldStyle" })
                                             @Html.ValidationMessageFor(model => model.SelectedAustraliaStateId)
                                </div>
                            </td>    
                        </tr>

                        <tr>
                            <td class="FormDisplayLeftTableStyle">
                                <div class="editor-label">
                                    @Html.LabelFor(model => model.City)
                                </div>
                            </td>
                            <td class="FormDisplayRightTableStyle">
                                <div class="editor-field">
                                    : @Html.DropDownListFor(model => model.SelectedAustraliaCityId, Model.AustraliaCities, "Select a City", new { id = "Cities", @class = "DropDownFieldStyle" })
                                </div>
                            </td>    
                        </tr>

</table> 
                    </fieldset>
                    @*Form Display Table END here*@
                
                </form>

Here is the JS script

@section Scripts {

                    <script type="text/javascript">
                        $("#Cities").hide();

                        $("#States").on("change", function () {

                            var cityDropdown = $('#Cities');
                            cityDropdown.empty();

                            $.getJSON('@Url.Action("GetCities")',
                            { id: $(this).val() },
                            function (cities) 
                            {
                                $.each(cities, function (i, city) 
                                {
                                    $("#Cities").append('<option value="' + city.AustraliaCityId + '">' + city.AustraliaCityName + '</option>');
                                });

                            });


                            $('#Cities').show();

                        });
                    </script>

                }

GetCities Action in Controller:

[HttpGet]
        public ActionResult GetCities(string id)
        {
            var cities = db.AustraliaCities.Where(c => c.AustraliaStateId == id).ToList();

            return Json(cities, JsonRequestBehavior.AllowGet);
        }

Can someone please help me?

Here is my site: http://overseasindians.com.au/

@section Scripts {

                    <script type="text/javascript">
                        $("#Cities").hide();

                        $("#States").on("change", function () {

                            var $cityDropdown = $('#Cities');
                            $cityDropdown.empty();

                            $.getJSON('@Url.Action("GetCities")',
                            { id: $(this).val() },
                            function (cities) 
                            {
                                $cityDropdown.append('<option value="">Select One...</option>').val("");
                                $.each(cities, function (i, city) 
                                {
                                    $cityDropdown.append('<option value="' + city.AustraliaCityId + '">' + city.AustraliaCityName + '</option>');
                                });

                            });


                            $cityDropdown.show();

                        });
                    </script>

                }

Hope this helps. it’s not tested, but you should catch the idea.

[RESOLVED]Table in partial view being replaced with table containing old non-current data

I have a view which we will call Create.cshtml.  On this view there is a call to a partial view called _PurchaseRequestTable.cshtml, using RenderAction, which calls a separate action on the controller called PurchaseRequestTable which returns a partial view.

Now I have two buttons on the form one for creating the record in the database and the other for updating the record on the databases.  Now when the onclick event handler for the each button runs, first an Ajax call is made to a function to interact with
the database, and then an Ajax call is made to the PurchaseRequestTable action to rebuild the partial view and replace the contents of the div rendered in the partial view with the new return from the action.

However what is happenning is that when the buttons are clicked, the new data is properly saved to the database, but when the partial view is replaced in it showing the old data.

Here is the code for the RenderAction and the controller action

@using (Html.BeginForm(null,null, FormMethod.Post, new { id = "PRCreate" })) {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>Add Purchase Requests</legend>
        <div id="overlay" style="position: fixed;top: 0;right: 0;bottom: 0;left: 0;height: 100%;width: 100%;margin: 0;padding: 0;background: #000000;opacity: .15;filter: alpha(opacity=15);-moz-opacity: .15;z-index: 101;display: none;" >

        </div>


        @{ Int32 prID = 0;
            if (Model.PurchaseRequest != null)
            {
                prID = Model.PurchaseRequest.PRID;
            }
            Html.RenderAction("PurchaseRequestTable", new { id = prID });
           }
 
        <br />
        <br />
        <br />
                          ....
        public ActionResult PurchaseRequestTable(Int32 id = 0)
        {
            using (var db = new VFS_ProcurementTrackEntities(Session["csProcTrack"].ToString()))  //breakpoint added here*****
            {
                ViewBag.PRID = id;
                var PR = new PurchaseRequestTableModel();



                if (id != 0)
                {
                    var currentRequest = db.prc_PRs.Find(id);
                    PR.PurchaseRequest = currentRequest;

                }
                else
                {
                    DateTime value = DateTime.Today; // Convert.ToDateTime("01/01/" + DateTime.Today.Year.ToString());
                    PR.PurchaseRequest = new prc_PRs();
                    PR.PurchaseRequest.PRID = 0;
                    PR.PurchaseRequest.PROriginatorUserRecID = (int)Session["UserRecID"];
                    PR.PurchaseRequest.PRDateCreated = value;
                }

                int defaultValue = (int)Session["UserRecID"];
                var AMSList = db.AMSList_get(0).ToList();
                SelectList amsDDList = new SelectList(AMSList, "AMSID", "AMS" , id == 0 ? defaultValue : PR.PurchaseRequest.PROriginatorUserRecID);


                PR.DDAMS = amsDDList;
                return PartialView("_PurchaseRequestTable", PR);
            }
        }

And here is the code for one of the click events being called.

   $(function () {
        //alert("created function");
        var UpdatePRs = function () {
            //alert("called function");
            //debugger
            var sURL = '@Url.Action("UpdatePurchaseRequest", "AJAXFunctions")';
            var goURLid = $("#PurchaseRequest_PRID").val();
            var form = $("#PRCreate");
            var bError = false;
            var returnedInfo = '';
            var sResultMessage = '';

            //alert(options.url);
            $.ajax({
                url: sURL,
                type: 'POST',
                data: form.serialize(),
                cache: false,
                async: false,
                dataType: 'json',
                //contentType: 'application/json; charset=utf-8',
                success: function (data) {
                    ////debugger
                    if (data != null) {
                        $(data).each(function () {
                            returnedInfo = data;
                        });
                    }
                    else {
                        returnedInfo = "Nothing was returned";
                        bError = true;
                    }
                },
                error: function () {
                    sResultMessage = 'An Error has occurred, and the changes to the PR Information were not saved.';
                    bError = true;
                }
            });
            //debugger
            //if (!bError) {
            var sURLRepost = '/PR/PurchaseRequestTable' + '/' + goURLid;
            //var options = 
            //};
            //alert(options.url);
            $.ajax({
                url: sURLRepost,
                type: "get",
                async: false,
                dataType:"html",
                success: function (data) {
                    //debugger
                    if (data != null) {
    //this is where the ajax call returns information showing the data prior to being changed. 
//break point in action is not hit. $("#PRtableView").replaceWith(data); } else { sResultMessage = "An Error has occured and no information was returned"; } }, error: function () { sResultMessage = 'An Error has occurred, and no data returned'; } }); if (!bError) { sResultMessage = "Your Edit has been completed. The changes were saved to the database."; $("#PRCreated").text(sResultMessage).toggle(); } else { sResultMessage = "Your edit was not completed. " + returnedInfo; $("#PRCreated").text(sResultMessage).toggle(); } }; $('#btnEditPR').on('click', UpdatePRs); });

On another thread with a similar problem where the Aijax call was returning a cached version of the action result Starain chen had me add a decoration to the Action like this:

 [OutputCache(NoStore = true, Duration = 0, VaryByParam = "None")]
        public ActionResult Index(int id = 0)
        {
            if (!Request.IsAjaxRequest())
            {
                id = (int)Session["UserRecID"];
            }
             ViewBag.UserID = (int)Session["UserRecID"];
             using (var db = new VFS_ProcurementTrackEntities(Session["csProcTrack"].ToString()))
             {
             //var db = new VFS_ProcurementTrackEntities(Session["csProcTrack"].ToString());
                 var model = (from pr in db.PurchaseRequests_Get_All(id)
                             orderby pr.PR_Number descending
                             select pr).ToList();
                 if (Request.IsAjaxRequest())
                 {
                     return PartialView("_PurchaseRequestsGrid", model);
                 }

                 return View(model);
             }
        }

And that resolved all of my issues.  However when I tried to do the same for the offending action here first I got "Duration must be a positive number and then when I arbitarily set it to 1 then it said that you could not use the parameter "NoStore = true"
on a on a child action.

At this point I was baffled, and asked for advice and it was suggested I start a new thread here.

So if anyone has any ideas then please let me know.

joeller

However what is happenning is that when the buttons are clicked, the new data is properly saved to the database, but when the partial view is replaced in it showing the old data.

Hi joeller,

Thanks for your post.

With your description and code provided, I see you want to update records with ajax call update action.

Then update the UI with ajax call the partial view render action. For the second ajax request always the old

content returned to, I think is the cache caused your problem. Please disable the cache of the second ajax like below:

 
            $.ajax({
                url: sURLRepost,
                type: "get",
                async: false,
                cache: false, 
                dataType:"html",
                success: function (data) {
                   
                  ................

Hope this helps, thanks.

Best Regards!

Fuxiang Zhang – MSFT

Please disable the cache of the second ajax like below:

OK that did it.  as the OP stated I tried to do that with an attribute added to the server side function but was not able to.  It totally slipped my mind that thiscould be done client side.

Thanks loads.  This wa driving me crazy.

[RESOLVED]How to update two different target ids when using Ajax.BeginForm?

How can you replace two different targetids when using Ajax.BeginForm? I have the following form but when there are validation errors eg when user submits form without adding any comments I can only replace targetid "Comments".

@Html.Partial("_CreateComment", Model)

<div id="Comments">
    @* Get list of all comments *@
    @Html.Action("Comments", "Blog")
</div>
// _CreateComment partial view
<div id="CommentForm">

	@Html.ValidationMessageFor(model => model.Comment)

	@using (Ajax.BeginForm("AddComment", "Blog", new AjaxOptions
	{
            HttpMethod = "POST",
            InsertionMode = InsertionMode.Replace,
            UpdateTargetId = "Comments"
         
	} ))
	{
             @Html.ValidationSummary(true)

             @Html.HiddenFor(model => model.BlogID)

  
	    <div>
		Add Comment: @Html.TextAreaFor(model => model.Comment, 1, 100, new { @Class = "commentbox" })
            </div>

             <div >
                <input type="submit" id="button" value="Add" /> 
            </div>
        }
</div>
// AddComment controller action

[HttpPost]
public ActionResult AddComment(Comment comment)
{

	Blog blog = _repository.GetBlogDetails(comment.BlogID);

        if (ModelState.IsValid)
	{

	   // Add Comment to DB..
           _repository.AddBlogComment(Comment);

     
           // Redirect to action and retrieve all comments 
           return RedirectToAction("Comments", new { id = blog.BlogID });

        }

        if (Request.IsAjaxRequest()) //was this request an AJAX request?
        {
                return PartialView("_CreateComment", blog); 
        }
        else
        {
                return View(blog);
        }
}

Any ideas how to fix. Basically i need to update two targetids – one for when comment is successfully added targetid "Comments" needs to replaced and when there are validation errors targetid "CommentForm" needs to be replaced.

If you want to make the Comments field required, just add the annotation to your Comment class

[Required]
public string Comment { get; set; }

And then add the jquery unobtrusive validation script to the scripts-section of your View:

@section scripts {
  @Scripts.Render("~/bundles/jqueryval")
}

This code will validate your form upon submission.

The comment class already has the required annotation and the validation is working. However when there are error what I want to do is simply redsiplay the form with the error message. What i need is some way to have two targetids so that the correct region
is being replaced.

Can you move the "Comments" div inside the partial control (that is inside the Form). If you do this, then on Ajax.BeginForm you can reload the "CommentForm" based on the output of the post.

On the server if the Model is not valid, you can use ModelState.Add to add the error message and hide the "comments" div. if the model is valid, you can show the "Comments" div

I have moved "Comments" div inside the partial control as follows:

<div id="Comments">

   <div id="CommentForm">

	@Html.ValidationMessageFor(model => model.Comment)

	@using (Ajax.BeginForm("AddComment", "Blog", new AjaxOptions
	{
            HttpMethod = "POST",
            InsertionMode = InsertionMode.Replace,
            UpdateTargetId = "Comments"
         
	} ))
	{
             @Html.ValidationSummary(true)

             @Html.HiddenFor(model => model.BlogID)

  
	    <div>
		Add Comment: @Html.TextAreaFor(model => model.Comment, 1, 100, new { @Class = "commentbox" })
            </div>

             <div >
                <input type="submit" id="button" value="Add" /> 
            </div>
        }
   </div>

   <div >
    	    @* Get list of all comments *@
    	    @Html.Action("Comments", "Blog")
   </div>

</div>

The form re-displays correctly but no validation errors are showing? One thing I have noticed is when I comment out the Html.Action() as below then the validation errors seem to work but then obviously none of my existing comments are displayed.

 @* Html.Action("Comments", "Blog") *@

The above html.action displays another partial view which has a for loop to display all the comments as follows:

@model IEnumerable<DB.Models.BlogComment>

@foreach (var item in Model)
{

   //...some stuff
}

any idea why its behaving like this.

GStar99

Html.Action("Comments", "OneToOne")

Where have you included this partial view? Is it inside the comments div?

sorry the partial view should be Html.Action("Comments", "Blog"). I have updated the original reply. It is inside the "comments" div as show above.

GStar99

How can you replace two different targetids when using Ajax.BeginForm?

handle onsuccess venet of ajax form.

in handler, update the two target divs. onsuccess handler has the parameter with output

Onsuccess will always be true since the controller action that is called by the ajax.beginform always works even when there are model validation errors – see the above controller code in my earlier post.

If I’ve miss-understood your answer please provide a short example?

you can have only one target id for a ajax form, what it does is, post the request, get back the response, put the html response in the target element. If i understood correctly you want to give the real time comments, even if the current request has errors.
try the following

1) Remove client side validation, remove both jquery unobtrusive and jquery validate. Have only server side validation.

2) In server code refresh the list of comments irrespective of validation hence even if there is error your comments section is refreshed. Add the comments to database only when it is not empty, so that you dont get empty texts

Blog blog = _repository.GetBlogDetails(comment.BlogID);

        if (ModelState.IsValid)
{

   // Add Comment to DB.. _repository.AddBlogComment(Comment);     
          
// Redirect to action and retrieve all comments

           //
return RedirectToAction("Comments",
new { id
= blog.BlogID
});

        }

// refresh the page even though the current user left the comment column empty

return RedirectToAction("Comments",
new { id
= blog.BlogID
});
       
if (Request.IsAjaxRequest())
//was this request an AJAX request?
       
{
               
return PartialView("_CreateComment", blog);

       
}
       
else
       
{
               
return View(blog);
       
}

[RESOLVED]unobtrusive client side validation not working when using ajax.beginform?

Hi,

Why does unobtrusive client side validation not working when using ajax.beginform? I am using MVC 3 and have the following jquery libraires declared yet when submitting an Ajax.BeginForm the unobtrusive validation doesnt work.

@section scripts {
    @Content.Script("jquery.validate.min.js", Url)
    @Content.Script("jquery.validate.unobtrusive.min.js", Url)
    @Content.Script("jquery.unobtrusive-ajax.min.js", Url)
  
}

  @using (Ajax.BeginForm("AddComment", "Blog", new AjaxOptions
        {
            HttpMethod = "POST",
            InsertionMode = InsertionMode.Replace,
            UpdateTargetId = "blogComments",
            LoadingElementId = "progress"

        })

        )
    {
       
        @Html.AntiForgeryToken()
        @Html.ValidationSummary(true)
        @Html.HiddenFor(model => model.Blog.BlogID)
     

        <div>
            <div>
                Add Comment 
            </div>
            <div>
                @Html.TextAreaFor(model => model.BlogComment.Comment, 1, 100, new { id = "commentbox" })
                @Html.ValidationMessageFor(model => model.BlogComment.Comment)
            </div>
        </div>
        
        <div >
              <input type="submit" id="button" value="Add" />
             
        </div>
            
        
       
    }

In my web config I also have the following enabled:

 <appSettings>
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
    
  </appSettings>

Isa this a partial view rendered in other main view?

if so, how r u rendering?

either through @Html.Partial() or loading on on click of something?

One of the things about validation is that you have a choice in how things are displayed:

 @Html.ValidationSummary(true)

excludePropertyErrorsType: System.Boolean
true to have the summary display model-level errors only, or false to have the summary display all errors.

Try false and let us know what happens.

the Ajax.beginform declaration is in a main view and the form fields are in partial view called using  @Html.Partial("_CreateComment", Model)

Hi GStar99,

Thanks for your post.

GStar99

unobtrusive client side validation not working when using ajax.beginform?

what’s error it renders?You can add script tags in LayOut.cshtml instead of index.cshtml page

 jquery.unobtrusive-ajax.min.js.

More information:

#Unobtrusive AJAX Form Validation in ASP.NET MVC

http://www.codeproject.com/Articles/460893/Unobtrusive-AJAX-Form-Validation-in-ASP-NET-MVC

If there’s anything else I can do for you regarding this matter,please feel free to post this forum.

Best Regards,

Eileen

Hi,

I’ve moved the script to Layout.cshtml and it still doesnt work?

jquery.unobtrusive-ajax.min.js

Hi,

what’s error?Did you add all scripts to layout.cshtml?

[RESOLVED]Viewmodel validation in asp.net mvc

Hi,

I have an asp.net mvc form. The form uses jquery to post the data and a viewmodel is bind to it. To validate the form, I am using the in-built data annotation attributes. But this does not seem to work with a view model. Please help me here. Below is my
sample code for the view and viewmodel.

Thanks.

@using (Html.BeginForm("AddProject", "Project", FormMethod.Post))
{ 
    @Html.ValidationSummary(true)
    
    <table cellspacing="5" cellpadding="10">
<tr>
<td>@Html.HiddenFor(model => model.ProjectID)</td>
</tr> <tr> <td>Project Year:</td> <td>@Html.DisplayFor(model => model.ProjectYear)</td> </tr> <tr> <td>Project Name:</td> <td> @Html.TextBoxFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name) </td> </tr> <tr> <td>Description:</td> <td>
@Html.TextAreaFor(model => model.Description, 5, 30, new { style = "spellcheck: false;" })
@Html.ValidationMessageFor(model => model.Description)
</td> </tr> <tr> <td><input type="button" value="Submit" onclick="SubmitForm();" /></td> </tr> </table> }

Viewmodel

namespace ProjectStatus.ViewModels
{
    public class ProjectViewModel
    {
        private ProjectEntities db = new ProjectEntities();

        public int ProjectID { get; set; }
[Required] public string Name { get; set; }
[Required] public string Description { get; set; }
public short ProjectYear { get; set; }
public ProjectViewModel() { } public ProjectViewModel(Projects prj) { ProjectID = prj.ProjectID; Name = prj.Name; Description = prj.Description; ProjectYear = prj.ProjectYear; } } }

Try this:

 @Html.ValidationSummary(false)

Note you can also try @Html.ValidationSummary

You should also be able to put a break point in the controller method to see what values are being returned.

@v2kea60

I tried it, but that does not seem to solve the issue.

Please include the below 2 scripts and reference it in your view.

<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>

Hi User220,

According to your description, I would like to know how do you use JQuery to post data.

First, please refer to asif’s reply.

Secondly, if you are using the AJAX to submit the data, please call valid() method to do validate.

$("Form").valid();

Best Regards

Starain Chen

[RESOLVED]Ajax.BeginForm() and validaiton message?

How to display the validation message of the Model while using Ajax.BeginForm() ?

It does not matter between Html.BeginForm and Ajax.BeginForm. while declaring validation

1) Please add validation message in Model class as in Html.BeginForm validation

2) Then specify modal dialog name as UpdateTargetId in Ajax.BeginForm

Ajax.BeginForm("Action", "Controller", new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "modal-dialog-name"})

If you are loading controls after the Ajax post and want to enable the validations after the post, you need to manually invoke the validator as shown below

$.validator.unobtrusive.parse('form');

Here is the code I used earlier for this

Ajax.BeginForm(new AjaxOptions() { UpdateTargetId = "AjaxViewContainer", OnSuccess = "RegisterAjaxEvents();", LoadingElementId = "LoadingDiv" });

JavaScript

function RegisterAjaxEvents() {
    $.validator.unobtrusive.parse('form');
    //remaining code
}

Hi abhi0410,

Thanks for your post.

First You enabled validation in the web.config page:

<add key="ClientValidationEnabled" value="true" />   
<add key="UnobtrusiveJavaScriptEnabled" value="true" />

And you can follow these steps:

Unobtrusive AJAX Form Validation in ASP.NET MVC

http://www.codeproject.com/Articles/460893/Unobtrusive-AJAX-Form-Validation-in-ASP-NET-MVC

More information:

Ajax.BeginForm and validation

Ajax.BeginForm not working with Html.ValidationSummary

If there’s anything else I can do for you regarding this matter, please feel free to post it in this forum.

Best Regards,

Eileen

Hello
pprasannak,

i tried but your solution little different.

I have partial view with save button but on first click my server validation occurs.

And when i click second time then i get those error message in my view.

My partial view is loaded dynamically in a view based on click of button present in the view.

<script type="text/javascript">
    function RegisterAjaxEvents() {
        $.validator.unobtrusive.parse('form');
    }
</script>

@using (Ajax.BeginForm("Add", "Account", new AjaxOptions() { UpdateTargetId = "messageid", HttpMethod = "Post", OnSuccess = "RegisterAjaxEvents();" , InsertionMode=InsertionMode.Replace}))
{
    @Html.AntiForgeryToken()
    <div>
        @Html.ValidationSummary(true)
        <table>
            <tr>
                <td>
                    @Html.LabelFor(model => model.name, new { @class = "label" })
                </td>
                <td>
                    @Html.TextBoxFor(m => m.name, new { @class = "textbox" })
                    @Html.ValidationMessageFor(model => model.name, string.Empty, new { @class = "error" })
                </td>
            </tr>
            <tr>
                <td>
                      @Html.LabelFor(model => model.Userid, new { @class = "label" })
                </td>
                <td>
                    @Html.TextBoxFor(m => m.Userid, new { @class = "textbox" })
                    @Html.ValidationMessageFor(model => model.Userid, string.Empty, new { @class = "error" })
                </td>
            </tr>
            <tr>
                <td>
                    @Html.LabelFor(model => model.Email, new { @class = "label" })
                </td>
                <td>
                    @Html.TextBoxFor(model => model.Email, new { @class = "textbox" })
                    @Html.ValidationMessageFor(model => model.Email, string.Empty, new { @class = "error" })
                </td>
            </tr>
            <tr>
                <td>
                    
                </td>
                <td>
                    <div id="messageid"></div>
                    <div>
                        <input type="submit" value="Save" class="btn btn-default" />
                    </div>
                </td>
            </tr>
        </table>
    </div>
}

Hi
Eileen ni

Can you please look into my code snippet and guide me why the validation fires on second click and not in first click?

Thanks

abhi0410

OnSuccess = "RegisterAjaxEvents();"

The validation is firing second time because you are explicitly calling the RegisterAjaxEvents function on the success of the first button click.

For some reason your initial loading is not registering the validator. As a work around try this

<script type="text/javascript">
    function RegisterAjaxEvents() {
        $.validator.unobtrusive.parse('form');
    }

  RegisterAjaxEvents() // call the function manually
</script>

Also move this javascript to the end of the page (after end of the BeginForm)

Hi
pprasannak
,

Thanks.

It works by calling explicitly. but what could be the reason that validator is not registered in initial loading?

And how to highlight the textbox for which the error has occurred?

Ok i could add validation color to the textbox by simply passing the below css pattern to my css file

.input-validation-error
{
    border: 1px solid #ff0000;
    background-color: #ffeeee;
}

Rest was taken care by jquery.

[RESOLVED]Data annotation validation

Hi
I have two questions regarding the data annotation validation.

1. Can you change the look og how the error message i show. Maybe use some of my own html
2. Can i use data annotation validation with viewmodels? I know that i can put data annotation on the attributes of my viewmodels but is it the way to go?

Hope someone can help
Jakobjensen

Yes, in Viewmodels you can implement the INotifyableObject interface.  MVC will call this implementation just before the post back enters the controller to validate anything you want. There are two modes to validation 1) For the Models itself using data
annotations and 2) And any custom business rules you need to implement in the View model.  To notify the view, the ViewModel validate method will return a collection of <ViewResult>  if you use the "Yield return new ViewResults("blah, blah blah")" construct
you can write as many validation rules as you need an very easily send them to the view.  

Reminder, make sure you set up something like @Html.ValidationSummry(true or false) up in the view in order to see them.  One final note, any Action method checking for Model.ViewState is valid any bypassing logic, will force those errors to be fixed!  In
other words it is a controller decision on what to do, however, why set up exception parsing rules for this if you just need to warn the user of something rather than forcing a correction.  For warning messages you are better off implementing on client side.
 Just create a hidden field or dialog that pops up from using JQuery or Javascript for those.

Can you change the look?  Anything is possible if you implement the entire system yourself or use JavaQuery to manipulate the DOM after document.ready.  You’ll easily be able to spot what MVC does to generate those messages.  Jquery can do anything with
them. 

Thanks for the answer.

So the way i do now is that i have some homemade javascript to handle client side validation.
And then i want to use entity frameworks serverside validation.
How do i make entity framework talk with my javascript.
I want the same error to show up both for client side errors and for server side errors

Im not sure i made myself clear…
I want to validate with the annotation from my business classes.
I have viewmodels.
And i have some javascript that validates and thats fine by me. But i dont know how to handle to kind of validation..

Lets say the user enters something wrong. Then he see my error message from javascript.

But if he has javascript disabled he should see the message from entity framework.

How do you handle these to validation?

Hi Jakobjensen,

jakobjensen

Can you change the look og how the error message i show. Maybe use some of my own html

I suggest that you could specify the style in the parent element, such as:

<div style="..."> 
@Html.ValidationMessageFor(m => m.UserName)
</div>

You also could custom HtmlHelper to custom it.

# Custom ValidationSummary template Asp.net MVC

http://stackoverflow.com/questions/5857851/custom-validationsummary-template-asp-net-mvc-3

jakobjensen

Can i use data annotation validation with viewmodels? I know that i can put data annotation on the attributes of my viewmodels but is it the way to go?

You just need add the data annotation validation attribute to the fields or properties of the
ViewModels.

Best Regards

Starain

Hi,

1. Use CSS style, what you want.

2. Custom Data Annotation always good, beco’z you can push your logic into validation.

http://20fingers2brains.blogspot.com/2013/04/custom-annotations-in-aspnet-mvc3-razor.html

Thanks,

Jai.

[RESOLVED]Partial Page Post but do not refresh Main Page

I have a page that has a Webgrid. Then for each row on my webgrid I have a button to edit the details that displays underneath the webgrid in a partial page called EditInventory. But when I submit changes on the partial page it redirects it to just the partial
page so it takes me away from my main page. All I really want to do is submit the changes to the database and then maybe display some message saying the it was saved but do not take the user away from the main page. 

Here is my main View.

@{
Layout = "~/Views/Shared/_Layout.cshtml";
ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
@Html.ActionLink("Create New", "Create")
</p>
<div id="test">
@{
var grid = new WebGrid(Model);
}
@grid.GetHtml(tableStyle: "grid",
selectedRowStyle: "selected",
columns: grid.Columns(
grid.Column("Test2",format: @<text><input id="button" type="submit" value="Edit" onclick="myFunction(@item.ProjectInventoryID)"></text>),
grid.Column("AssetType", "Asset Type", style: "assettype"),
grid.Column("CheckedIn", "Checked In"),
grid.Column("SerialNumber", "Serial Number"),
grid.Column("Installer", "Installer"),
grid.Column("IssueDate", "Issue Date"),
grid.Column("InstallDate", "Install Date"),
grid.Column("CheckInDate", "Checked In Date"),
grid.Column("Size", "Size"),
grid.Column("PrevInstaller", "Previous Installer"),
grid.Column("ProjectName", "Project Name")))
</div>

<div id="inventoryDetails">

</div>

<script>
function myFunction(id) {
$.ajax({
url: ‘/Inventory/EditInventory’,
type: ‘GET’,
data: { projectinventoryid: id },
datatype: ‘html’,
success: function(data){
$(‘#inventoryDetails’).html(data);
}
});
}

</script>

@section Scripts {
@Scripts.Render("~/bundles/jquery")
}

Here is my partial view:

@model FS.Models.ProjectInventory

<script src="~/Scripts/jquery-1.8.2.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>

@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)

<fieldset>
<legend>ProjectInventory</legend>

@Html.HiddenFor(model => model.ProjectInventoryID)

<div class="editor-label">
@Html.LabelFor(model => model.SerialNumber)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.SerialNumber)
@Html.ValidationMessageFor(model => model.SerialNumber)
</div>

<div class="editor-label">
@Html.LabelFor(model => model.AssetType)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.AssetType)
@Html.ValidationMessageFor(model => model.AssetType)
</div>

<div class="editor-label">
@Html.LabelFor(model => model.Installer)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Installer)
@Html.ValidationMessageFor(model => model.Installer)
</div>

<div class="editor-label">
@Html.LabelFor(model => model.IssueDate)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.IssueDate)
@Html.ValidationMessageFor(model => model.IssueDate)
</div>

<div class="editor-label">
@Html.LabelFor(model => model.InstallDate)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.InstallDate)
@Html.ValidationMessageFor(model => model.InstallDate)
</div>

<div class="editor-label">
@Html.LabelFor(model => model.CheckedIn)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.CheckedIn)
@Html.ValidationMessageFor(model => model.CheckedIn)
</div>

<div class="editor-label">
@Html.LabelFor(model => model.AuditFlag)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.AuditFlag)
@Html.ValidationMessageFor(model => model.AuditFlag)
</div>

<div class="editor-label">
@Html.LabelFor(model => model.CheckInDate)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.CheckInDate)
@Html.ValidationMessageFor(model => model.CheckInDate)
</div>

<div class="editor-label">
@Html.LabelFor(model => model.Size)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Size)
@Html.ValidationMessageFor(model => model.Size)
</div>

<div class="editor-label">
@Html.LabelFor(model => model.PrevInstaller)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.PrevInstaller)
@Html.ValidationMessageFor(model => model.PrevInstaller)
</div>

<div class="editor-label">
@Html.LabelFor(model => model.ContainerID)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.ContainerID)
@Html.ValidationMessageFor(model => model.ContainerID)
</div>

<div class="editor-label">
@Html.LabelFor(model => model.ProjectId)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.ProjectId)
@Html.ValidationMessageFor(model => model.ProjectId)
</div>

<div class="editor-label">
@Html.LabelFor(model => model.ProjectName)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.ProjectName)
@Html.ValidationMessageFor(model => model.ProjectName)
</div>

<p>
<input id="button" type="submit" value="Save" />
<input id="button1" type="submit" value="Edit" onclick="myFunction2()">
</fieldset>
}

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

<script>
$(function myFunction2() {
$("button1").click(function () {
$(‘#myForm1′).ajaxSubmit();
});
});

</script>

@section Scripts {
@Scripts.Render("~/bundles/jquery")
}

Here is my Controllers:

public ActionResult Index()
{
return View(_db.ProjectInventories.ToList());
// return View(_db.ProjectInventories.ToList());
}

public ActionResult EditInventory(int? projectinventoryid = null)
{
if (projectinventoryid == null)
{
var model1 = _db.ProjectInventories.Where(e => e.ProjectInventoryID == 1).Single(); ;
return PartialView(model1);
}
var model = _db.ProjectInventories.Where(e => e.ProjectInventoryID == projectinventoryid).Single();
return PartialView(model);
}

[HttpPost]
public PartialViewResult EditInventory(int projectinventoryid, FormCollection collection)
{
ProjectInventory coll = _db.ProjectInventories.Where(e => e.ProjectInventoryID == projectinventoryid).Select(e => e).Single();

UpdateModel(coll);
_db.SaveChanges();
return PartialView();

}

the browser does not know anything about partials. if you post to a partial, the browser will just display the response (which is just the partial). the partial should (when successful)  respond with a redirect to the main page. then the browser will redisplay
the page, but the updated info should display.

you other option is to use ajax for the form post. then on a successful form post you hide the edit div, and do another ajax call to get the current grid data.

 

Ok so I tried to create an ajax form post but it is going to a new page with my return content of Success. I thought it should just display in my div with the data. What am I doing wrong?

@model FS.Models.ProjectInventory

<script src="~/Scripts/jquery-1.8.2.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>

@using (Ajax.BeginForm("EditInventory", "Inventory", new AjaxOptions { UpdateTargetId = "result" }))
{

@Html.AntiForgeryToken()
@Html.ValidationSummary(true)

<fieldset>
<legend>ProjectInventory</legend>
<div id="result"></div>
@Html.HiddenFor(model => model.ProjectInventoryID)

<div class="editor-label">
@Html.LabelFor(model => model.SerialNumber)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.SerialNumber)
@Html.ValidationMessageFor(model => model.SerialNumber)
</div>

<div class="editor-label">
@Html.LabelFor(model => model.AssetType)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.AssetType)
@Html.ValidationMessageFor(model => model.AssetType)
</div>

<div class="editor-label">
@Html.LabelFor(model => model.Installer)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Installer)
@Html.ValidationMessageFor(model => model.Installer)
</div>

<div class="editor-label">
@Html.LabelFor(model => model.IssueDate)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.IssueDate)
@Html.ValidationMessageFor(model => model.IssueDate)
</div>

<div class="editor-label">
@Html.LabelFor(model => model.InstallDate)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.InstallDate)
@Html.ValidationMessageFor(model => model.InstallDate)
</div>

<div class="editor-label">
@Html.LabelFor(model => model.CheckedIn)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.CheckedIn)
@Html.ValidationMessageFor(model => model.CheckedIn)
</div>

<div class="editor-label">
@Html.LabelFor(model => model.AuditFlag)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.AuditFlag)
@Html.ValidationMessageFor(model => model.AuditFlag)
</div>

<div class="editor-label">
@Html.LabelFor(model => model.CheckInDate)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.CheckInDate)
@Html.ValidationMessageFor(model => model.CheckInDate)
</div>

<div class="editor-label">
@Html.LabelFor(model => model.Size)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Size)
@Html.ValidationMessageFor(model => model.Size)
</div>

<div class="editor-label">
@Html.LabelFor(model => model.PrevInstaller)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.PrevInstaller)
@Html.ValidationMessageFor(model => model.PrevInstaller)
</div>

<div class="editor-label">
@Html.LabelFor(model => model.ContainerID)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.ContainerID)
@Html.ValidationMessageFor(model => model.ContainerID)
</div>

<div class="editor-label">
@Html.LabelFor(model => model.ProjectId)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.ProjectId)
@Html.ValidationMessageFor(model => model.ProjectId)
</div>

<div class="editor-label">
@Html.LabelFor(model => model.ProjectName)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.ProjectName)
@Html.ValidationMessageFor(model => model.ProjectName)
</div>

<p>
<input id="button" type="submit" value="Save" />
<input id="button1" type="submit" value="Edit" onclick="myFunction2()">
</fieldset>
}

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

<script>
$(function myFunction2() {
$("button1").click(function () {
$(‘#myForm1′).ajaxSubmit();
});
});

function myFunction(m) {
$.ajax({
url: ‘/Inventory/EditInventory’,
type: ‘POST’,
datatype: ‘html’,
success: function (data) {
$(‘#inventoryDetails’).html(data);
}
});
}

</script>

@section Scripts {
@Scripts.Render("~/bundles/jquery")
}

public ActionResult EditInventory(int? projectinventoryid = null, int? installer = null)
{
if (projectinventoryid == null)
{
var model1 = _db.ProjectInventories.Where(e => e.ProjectInventoryID == 1).Single(); ;
return PartialView(model1);
}

var model = _db.ProjectInventories.Where(e => e.ProjectInventoryID == projectinventoryid).Single();
return PartialView(model);
}

[HttpPost]
public ActionResult EditInventory(int projectinventoryid, FormCollection collection)
{
ProjectInventory coll = _db.ProjectInventories.Where(e => e.ProjectInventoryID == projectinventoryid).Select(e => e).Single();

UpdateModel(coll);
_db.SaveChanges();
return Content("Success", "text/html");

}


You need to include the Mvc ajax scripts. You just included validation only. Or just use jQuery for the form post

add a preventDefault to your button click event 

$("button1").click(function (e) {
e.preventDefault();
$('#myForm1').ajaxSubmit();
});
});

Great that worked perfectly. The last thing I am having trouble with on this page is when I click my Edit button on my Index View within the Webgrid it will show my partial page of EditInventory. But if I want to select a different record and click Edit
it does not refresh the partial view of EditInventory. Why does it not fire my function again?

Thanks for all the help on this form. I have everything figured out now.