Asp.Net MVC 2 - 奇怪的行为:RedirectToAction和ValidationSummary无法正常工作

时间:2010-07-26 18:38:46

标签: jquery asp.net-mvc-2 asp.net-mvc-2-validation

我已经使用MVC 2一段时间了,我已经完成了ReturnToAction以及ValidationSummary - 但这有点不同,因为我的“提交”按钮是javascript / JQuery的控件 - 我调试动作它确实去了进入正确的控制器动作,但一旦它通过RedirecToAction,没有任何反应......

我的第二个问题是我的ValidationSummary无法显示 - 我运行了一个测试,当它返回一个View时,ModelState无效 - 没有任何显示

我的按钮/表单/ submit / JQuery是否有问题?

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">      

<script type="text/javascript">  
    $(function () {  

            /*stuff here to setup some JQuery Sortable lists*/  

        $("#UpdateButton").click(function () {  

            //create Arrays from JQuery Sortable List and go to Action for "submit"                   //processing  

            $.ajax({  
                url: '/Admin/SortedLists/',  
                data: { items: editedRoles, items2: $("#deleteList").sortable('toArray') },  
                type: 'POST',  
                traditional: true  
            });  
        });  

            //go to Action and just "Reload" the page  
        $("#UndoButton").click(function () {  
            //reload the page  
                var url = '<%= Url.Action("EditRoles") %>';                
            window.location.href = url;  
        });  

        $("#roleList, #deleteList").disableSelection();  
        $("#deleteList").hide();  
    });  


    function addNewRole() {  
        var text = $("#New_Role").val();  

        $("#roleList").append('<li id="-1~' + text + '" class="ui-state-default">' +  
                              '<span class="ui-icon ui-icon-closethick"></span>' +  
        //                    '<span class="ui-icon ui-icon-arrowthick-2-n-s"></span>' +  
                              '<input id="-1" type="text" value="' + text + '" />' +                                    
                              '</li>');  
        $("#roleList").sortable('refresh');  
    }  
</script>  

<%= Html.ActionLink("Back", "Index") %>      

<% using (Html.BeginForm()) { %>    
    <br />       
    <%= Html.Encode(ViewData["Message"]) %>  
    <%=Html.ValidationSummary(true, "Edit was unsuccessful. Please correct the errors and try again.")%>  
    <div class="demo">         

        <%=Html.TextBox("New Role", "New Role")%>  
        <a href="javascript:addNewRole()"> Add</a>  

        <br />  
        <br />  
        <ul id="roleList" class='droptrue'>  

         //create an unordered list with textboxes and a close icon  
            <%  
           foreach (var item in Model.Roles)  
           {%>                                   
             <li class="ui-state-default" id="<%=Html.AttributeEncode(item.Id)%>~<%=Html.AttributeEncode(item.Name)%>"><span class="ui-icon ui-icon-closethick"></span><%=Html.TextBox(item.Id.ToString(), item.Name, new {@id = item.Id})%></li>                                                                              

         <% } %>        
        </ul>  

        <ul id="deleteList" class='droptrue'>  
        </ul>         

        <br />  

        </div>        

            <input id="UpdateButton" type="submit" name="submitButton" value="Update" /><%= Html.ValidationMessage("UpdateButton", "*") %>                  
            <input id="UndoButton" type="submit" name="submitButton" value="Undo" />              

<% } %>  

Controller看起来像这样:

public AdminController()  
    {  
        var wrapper = new ModelStateWrapper(ModelState);  
        _rolesService = new RolesService(new RolesRepository(), new RolesValidator(wrapper, new DateValidator(wrapper)));  
    }  

    public ActionResult Index()  
    {  
        return View();  
    }  

    public ActionResult EditRoles()  
    {  
        var roles = _rolesService.FetchAllRoles();  
        return View(new AdminEditRolesViewModel(roles));  
    }  

    [HttpPost]  
    public ActionResult SortedLists(List<string> items, List<string> items2)  
    {  
        var roles = _rolesService.BuildRolesFromList(items);  
        var deletedRoles = _rolesService.BuildRolesFromList(items2);  

        //The Services have contain the ModelState, this is where errors happen  
        //ValidationSummary doesnt show anything  
        if (_rolesService.EditRoles(roles) == false)  
        {  
            roles = _rolesService.FetchAllRoles();  
            return View("EditRoles", new AdminEditRolesViewModel(roles));  
        }  

        if (_rolesService.DeleteRoles(deletedRoles) == false)  
        {  

            roles = _rolesService.FetchAllRoles();  
            return View("EditRoles", new AdminEditRolesViewModel(roles));  
        }  

        _rolesService.Save();  

        //This RedirecToAction is passed, but doesnt actually go to my Index()  
        return RedirectToAction("Index");  

    }  

我的服务处理诸如验证之类的东西,我将它传递给ModelState和一个ModelStateDictionary包装器并添加错误 - 我是否错误地添加了错误?

public bool DeleteRoles(IEnumerable<Role> deletedRoles)  
{  
    //some work, if fails add error  

    _validator.AddError("UpdateButton",  
        "Role: " + role.Name +  
        " can not be deleted because Employees still use this";

    return _validator.IsValid();  
} 

感谢您提供任何帮助 - 这让我感到困扰

2 个答案:

答案 0 :(得分:2)

它在调试器中传递RedirectToAction()是正常的。在从方法返回之前,它实际上不会进行重定向。但是你的控制器动作正在运行。你只是没有看到任何东西,因为作为网页的前端表示层没有做任何事情来处理你的ajax调用设置的回调。要解决这个问题,你将创建一个类似的回调函数:

        $.ajax({  
            url: '/Admin/SortedLists/',  
            data: { items: editedRoles, items2: $("#deleteList").sortable('toArray') },  
            type: 'POST',  
            traditional: true,
            success: function(data) {
                alert(data);
            }
        });

显然你会对“数据”做一些更有用的事情,但我们现在只是展示它。

validatorSummary未显示,因为创建它的方法不是您在POST时的操作。 RedirectToAction正在“删除”它。要解决这个问题,你可以使用类似的东西:

return View("~/Views/Home/Index.aspx", model);

这将直接向用户发送并保留您的模型状态,包括验证。

答案 1 :(得分:0)

我认为你有几个问题。

  • 重定向没有按照您期望的方式发生

我认为这是因为您使用$.ajax()调用异步发布表单,但是您没有处理返回值。 RedirectToAction返回一个URL和HTTP状态代码302(可能是301,我忘了),它告诉浏览器请求返回的URL。您的控制器操作正在将HTTP重定向返回到异步javascript调用,该调用未处理它。

您需要更改提交JavaScript或使用.ajaxSuccess()等处理返回值。

  • ValidationSummary未显示。

您的ValidationSummary没有显示有两个原因。第一个是因为我刚才描述的ajax返回的事情。第二个是你在执行RedirectToAction时“丢失”了ModelState。除非您明确处理ModelState传输(通常通过将其导出到TempData并在目标操作中导入它),否则在重定向时它将丢失。