MVC 3 Razor。部分视图验证无效。

11

我遇到了一个问题,我无法在加载到div中的部分视图内触发客户端验证。在这个例子中,我停止了div的“切换”来查看验证是否触发,但是没有用,什么也没发生。

幸运的是,模型不接受任何无效的输入,但它也不会警告用户实际的错误。如果有任何帮助,将不胜感激。

以下是我的模型:

public class Help
{
    [HiddenInput(DisplayValue=true)]
    public int HelpID { get; set; }

    [Required(ErrorMessage = "Please enter a proper URL")]
    public string URL { get; set; }

    [Required(ErrorMessage = "Please enter a content description:")]
    [DataType(DataType.MultilineText)]
    public string HelpContent { get; set; }

    /*? 2 properites are nullable*/
    public DateTime? createDateTime { get; set; }
    public DateTime? modifiedDateTime { get; set; }        
}

这是我的控制器:

namespace HelpBtn.WebUI.Controllers
{
    /*Create the admin controller*/
    public class AdminController : Controller
    {
        //declare interface object
        private IHelpRepository repository;

        /*Pass a db interface to controller*/
        public AdminController(IHelpRepository repo)
        {
            repository = repo;
        }

        /*default admin screen. displays help table obs*/
        public ViewResult Index()
        {
            return View();
        }

        /*Returns add view form*/
        public ViewResult AddForm()
        {
            return View();
        }

        /*Returns edit view form, searches for object to edit with id
          if no id provided, 0 by default*/
        public ViewResult EditForm(int helpID = 0)
        {
            Help help = repository.Help.FirstOrDefault(q => q.HelpID == helpID);
            return View(help);
        }

        /*Will handle the post for the edit screen after user has
          submitted edit information*/
        [HttpPost]
        [ValidateInput(false)] //this allows admin to place html in field. may cause validation problems
        public ActionResult EditForm(Help help)
        {

            if (ModelState.IsValid) //if all fields are validated
            {
                //set the edit date
                help.modifiedDateTime = DateTime.Now;
                repository.SaveHelp(help);
                return RedirectToAction("Index");
            }
            else //there is something wrong. send back to view            
            {
                return View(help);
            }
        }

        /*Delete action method, searches with id*/
        [AcceptVerbs(HttpVerbs.Post)]
        [GridAction]
        public ActionResult Delete(int helpId)
        {
            Help helpDel = repository.Help.FirstOrDefault(p => p.HelpID == helpId);
            if (helpDel != null) //if the object is found, delete
            {
                repository.DeleteHelp(helpDel);
            }

            //in all cases return to index
            return RedirectToAction("Index");
        }

        /*Used by the telerik table to rebind grid*/
        [GridAction]
        public ActionResult AjaxBinding()
        {
            return View(new GridModel(repository.Help));
        }
    }//end admin class
}//end namespace

这是我的主视图:

<div id="addContent" style="display: none"></div>

//Select Function. saves selected row
function onRowSelect(e) {
    HelpID = e.row.cells[0].innerHTML;
} //end onRowSelect

//Refresh grid function
function refreshGrid() {
    $("#Grid").data('tGrid').rebind();
} //end refresh grid

//Variables. '$' b4 name for intellisense
var HelpID;
var $editContent = $("#editContent");
var $addContent = $("#addContent");
//end variables  

//Add Form call. loads partial view to div:content
$("#Add").click(function () {
    $editContent.hide();
    $editContent.html("");
    $.ajax({
        type: "Get",
        url: "/Admin/AddForm",
        datatype: "html",
        success: function (data) {
            $addContent.html(data);
            $addContent.toggle();
        } //end success
    }); //end ajax
});        //end add

//Edit Form call. loads partial view to div:content
$("#Edit").click(function () {
    $addContent.hide();
    $addContent.html("");
    $.ajax({
        type: "Get",
        url: "/Admin/EditForm",
        dataType: "html",
        data: { HelpID: HelpID },
        success: function (data) {
            $editContent.html(data);
            $editContent.toggle();
        } //end sucess
    }); //end ajax
});         //end edit

//Delete call. deletes selected row in table
$("#Delete").live('click', function () {
    $.post("/Admin/Delete", { HelpID: HelpID }, function () {
        $addContent.html("");
        $editContent.html("");
        refreshGrid();
    }); //end function
});   //end delete

//post add form data back to server
        $("#btnAdd").live('click', function (e) {
            e.preventDefault();
            $.post($('#Addx').attr('action'), $('#Addx').serialize(), function (data) {
                refreshGrid();
             $addContent.html("");
            }); //end post
            e.preventDefault();
        });
        //    end .live

        //post edit form data back to server
        $("#btnEdit").live('click', function (e) {
            $.post($('#Editx').attr('action'), $('#Editx').serialize(), function (data) {
                refreshGrid();
                $editContent.html("");
            });

            e.preventDefault();
        }); //end post edit

这是我的部分视图,它加载到主页面的div中:

@model HelpBtn.Domain.Entities.Help
@*THIS POSTS BACK TO EDIT/ADMIN. needs to be asynchronous*@
@using (Html.BeginForm("EditForm", "Admin", FormMethod.Post, new { id = "Addx" }))
{
    <fieldset>
        <legend>Add Entry</legend>
        <div class="editor-label">
            @Html.LabelFor(model => model.URL)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.URL)
            @Html.ValidationMessageFor(model => model.URL)
        </div>
        <div class="editor-label">
            @Html.LabelFor(model => model.HelpContent, "Help Content")
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.HelpContent)
            <p>
                @Html.ValidationMessageFor(model => model.HelpContent, "Enter a value")
            </p>
        </div>
        <div class="editor-label">
            @Html.LabelFor(model => model.createDateTime, "Created Date")
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.createDateTime)
            @Html.ValidationMessageFor(model => model.createDateTime)
        </div>
        <p>
            <input id="btnAdd" type="submit" value="Create" />
        </p>
    </fieldset>   
}

可能是重复的问题:jquery客户端验证在MVC3部分视图中无法工作 - Zairja
1个回答

37

每次执行 AJAX 调用并用控制器操作返回的部分 HTML 内容替换 DOM 中的某些部分时,您需要重新解析客户端侵入式验证规则。因此,在您的 AJAX 成功回调中,当您调用 .html() 方法刷新 DOM 之后,您需要进行解析:

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

唯一的问题是每当我提交表单时都会出现错误。错误信息是“Microsoft JScript运行时错误:无法获取属性'unobtrusive'的值:对象为null或未定义”。你知道为什么吗? - user1238864
实际上,Darin,你的答案完全有效。显然,问题是由Telerik jquery验证和Internet Explorer兼容性问题引起的。在运行Chrome时,$.validator.unobtrusive.parse('elementOrForm')正好做到了它需要做的事情:替换丢失的事件处理程序,而不是在运行Internet Explorer时抛出“未定义”异常。我还发现,在使用Internet Explorer时,这个调用加上主视图代码的顶部可以解决兼容性问题。Html.Telerik().ScriptRegistrar().jQuery(false).jQueryValidation(false);非常感谢! - user1238864
谢谢,但我最后不得不添加 $('form').valid(); 来消除部分视图替换时的验证错误。 - Shaiju T

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接