2010-07-26 68 views
1

我一直在使用MVC 2一段时间,并完成ReturnToAction以及ValidationSummary - 但这是有点不同,因为我的“提交”按钮是通过JavaScript/JQuery控制 - 我调试的行动,它确实进入正确的控制器行动,但一旦它通过RedirecToAction,什么也没有发生......Asp.Net MVC 2 - 奇怪的行为:RedirectToAction和ValidationSummary不工作

我的第二个问题是,我的ValidationSummary无法显示 - 我运行测试,当它返回一个视图时,ModelState无效 - 什么也没有显示

这是我的按钮/形式/提交/ 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" />    

<% } %> 

和控制器看起来是这样的:

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(); 
} 

感谢所有帮助 - 这是推动我逼疯了

回答

0

我觉得你有一对夫妇的问题。

  • 重定向不会发生的方式,你希望

我想这是因为你与$.ajax()调用异步发布的形式,但你不处理的返回值。 A RedirectToAction返回一个URL和一个HTTP状态码302(可能是301,我忘了),它告诉浏览器请求返回的URL。您的控制器操作正在将HTTP重定向返回给异步JavaScript调用,该调用不处理它。

您需要更改提交的JavaScript或使用类似.ajaxSuccess()的方式处理返回值。

  • ValidationSummary not displayed。

由于两个原因,您的ValidationSummary未显示。首先是因为我刚刚描述的阿贾克斯返回的东西。第二个是当你做了RedirectToAction时,你“丢失”了ModelState。除非您明确处理ModelState转移(通常通过将其导出到TempData并将其导入到目标操作中),否则当您重定向时它将丢失。

+0

乔希,我也需要这个回答。如果您将发布适用于我的代码示例,我很乐意为您发布我发布的赏金。 – Rap 2010-12-23 16:34:02

+0

Bah,刚才看到了这个。抱歉耽搁了。如果克里斯的回答不适合你,让我知道,我会重温。 – Josh 2010-12-28 15:33:47

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); 

这会向用户发送直接出现,并会保留您的ModelState,包括验证。