1

I have a partial view with a DropDownList control and a textbox.

When nothing is selected or no text is entered the ModelState.IsValid is FALSE

BUT I can see no validation errors displayed annotated on my properties.

Why is that? I can see in the ModelState.Value.Errors property there is an "Name is

missing" for example.

When I confirm the invalid view I see this in my output window:

A first chance exception of type 'System.InvalidOperationException' occurred in System.Web.Mvc.dll
A first chance exception of type 'System.InvalidOperationException' occurred in System.Web.Mvc.dll
A first chance exception of type 'System.InvalidOperationException' occurred in System.Web.Mvc.dll


public ActionResult Edit()
{
    return LoadEditTemplates();
}


[HttpPost]
public ActionResult Update(EditTemplateListViewModel viewModel)
{
    if (ModelState.IsValid && !_templateDataProvider.TemplateExists(viewModel.Name))
    {
        Template template = Mapper.Map<EditTemplateListViewModel, Template>(viewModel);
        _templateDataProvider.UpdateTemplate(template);
        return new JsonNetResult(new { success = true });
    }

    return PartialView(viewModel);
}

private ActionResult LoadEditTemplates()
{
    var templates = _templateDataProvider.GetTemplates();
    EditTemplateListViewModel editTemplateViewModel = new EditTemplateListViewModel()
    {
        DisplayList = Mapper.Map<IEnumerable<Template>, IEnumerable<TemplateViewModel>>(templates),
    };
    return PartialView(editTemplateViewModel);
}

public class EditTemplateListViewModel
    {
        [Required(ErrorMessage = "No template selected.")]
        public int TemplateId { get; set; }

        [Required(ErrorMessage="Name is missing")]
        public string Name { get; set; }

        public IEnumerable<TemplateViewModel> DisplayList { get; set; }      
    }

@model ITMS.Web.Models.EditTemplateListViewModel

@*Remote Validation*@
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

@using (Html.BeginForm("Update", "Template"))
{       
    @Html.ValidationSummary(false)
    @Html.DropDownListFor(x => x.TemplateId, new SelectList(Model.DisplayList, "TemplateId", "Name"), new { @class = "listviewmodel" })

    <p class="editor-label">@Html.LabelFor(model => model.Name)</p>
    <p class="editor-field">@Html.EditorFor(model => model.Name)</p>
    <p class="editor-field">@Html.ValidationMessageFor(model => model.Name)</p>   
}

3 Answers 3

1

Insated Of using Html,BeginForm use Ajax.BeginForm to submit your partial view

   //In partial View 


<div id="targetId">
     @using (Ajax.BeginForm("Update", "Template", new AjaxOptions { HttpMethod="POST", UpdateTargetId="targetId"}))
        {       
            @Html.ValidationSummary(false)
            @Html.DropDownListFor(x => x.TemplateId, new SelectList(Model.DisplayList, "TemplateId", "Name"), new { @class = "listviewmodel" })

            <p class="editor-label">@Html.LabelFor(model => model.Name)</p>
            <p class="editor-field">@Html.EditorFor(model => model.Name)</p>
            <p class="editor-field">@Html.ValidationMessageFor(model => model.Name)</p>   
        }

return type of Partial view is String so you can catch it at server side, in ajax option you must be specify HttpMethod and UpdateTargetId where you want to show your result in view.here i am quoted your Ajax.BegionForm with div and given UpdateTargetId is Div Id so that if error will occur it append view in same div

In Controller

[HttpPost]
public string Update(EditTemplateListViewModel viewModel)
{
    if (ModelState.IsValid && !_templateDataProvider.TemplateExists(viewModel.Name))
    {
        Template template = Mapper.Map<EditTemplateListViewModel, Template>(viewModel);
        _templateDataProvider.UpdateTemplate(template);
        return new JsonNetResult(new { success = true });
    }

    return RenderPartialViewToString("PartialViewName",viewModel);
}



protected string RenderPartialViewToString(string viewName, object model)
        {
            if (string.IsNullOrEmpty(viewName))
                viewName = ControllerContext.RouteData.GetRequiredString("action");

            ViewData.Model = model;

            using (StringWriter sw = new StringWriter())
            {
                ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
                ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
                viewResult.View.Render(viewContext, sw);
                return sw.GetStringBuilder().ToString();
            }
        }

by passing partialViewName and Model to RenderPartialViewToStringit will return you RenderHtml of View.

NOTE: before using Ajax.BeginForm make sure add following script.

Sign up to request clarification or add additional context in comments.

3 Comments

I am already using Ajax.BeginForm by using Jquery Ajax form post. Ajax.BeginForm is just the MVC "wrapper".
I have checked your code which is from here: craftycodeblog.com/2010/05/15/… ... I can not resolve the class Config.Url.ToString() What is that Config class?
Elisa i have not getting about Config.Url.toString() so can you please me some more detail about it where you have used it in code.
1

When I returned the data from the post action I realized the Argument cast exception because I did not pass data for example to the SelectItem list "DisplayList". It was null and thus bang...

I just filled the missing data to redisplay the view and the errors are visible :) heck... I already stepped in that failure once...

Comments

0

Since server side code is working fine, I would suggest to check if required JQuery libraries are loaded properly.

<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
<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>

4 Comments

Did not help. Just the opposite. When I open the jquery dialog with the partial view I get lots of exceptions in the output window.
If partial view is loaded asynchronously, validation plugin needs to be reinitialized again. Check stackoverflow.com/questions/7005052/… and stackoverflow.com/questions/12516245/…
all my partial views are loaded async. I never needed any further jquery library except the jquery.validate.unobtrusive.min.js". And on my side there is no dynamic content.
Tonight I will put together a running sample so you see.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.