Asp.Net MVC 2 - странное поведение: RedirectToAction и ValidationSummary не работают - PullRequest
1 голос
/ 26 июля 2010

Я работал с MVC 2 некоторое время, и я сделал ReturnToAction, а также ValidationSummary - но это немного отличается тем, что мои кнопки "submit" являются элементами управления с помощью javascript / JQuery - я отлаживаю действие, и оно действительно в правильное действие контроллера, но как только он проходит через RedirecToAction, ничего не происходит ....

Моя вторая проблема заключается в том, что мой ValidationSummary не показывает - я запускаю тест, и когда он возвращает View, когда 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();  
} 

Спасибо за любую помощь - это доводит меня до стены

Ответы [ 2 ]

2 голосов
/ 27 декабря 2010

Для него нормально пройти через 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);

Это отправит пользователя прямо туда и сохранит ваше состояние модели, включая проверки.

0 голосов
/ 16 августа 2010

Я думаю, у вас есть пара проблем.

  • Перенаправление не происходит так, как вы ожидаете

Я думаю, это потому, что вы отправили форму асинхронно с вызовом $.ajax(), но вы не обрабатываетевозвращаемые значения.RedirectToAction возвращает URL-адрес и код состояния HTTP 302 (может быть, 301, я забыл), который сообщает браузеру запросить возвращенный URL-адрес.Ваше действие контроллера возвращает HTTP-перенаправление на асинхронный вызов javascript, который не обрабатывает его.

Вам необходимо либо изменить JavaScript для отправки, либо обработать возвращаемое значение с помощью чего-то вроде .ajaxSuccess().

  • ValidationSummary не отображается.

Ваша ValidationSummary не отображается по двум причинам.Во-первых, из-за того, что я только что описал возврат Ajax.Во-вторых, вы «потеряли» ModelState, когда сделали RedirectToAction.Если вы явно не обработаете передачу ModelState (обычно экспортируя ее в TempData и импортируя ее в целевом действии), она будет потеряна при перенаправлении.

...