Это «взлом», и если да, то есть ли лучший способ определить, какой ActionResult вернуть? - PullRequest
0 голосов
/ 04 сентября 2010

У меня есть директория A - Z, которая есть на каждой странице. Если пользователь находится на домашней странице и щелкает что-то в каталоге, я хочу загрузить страницу каталога с соответствующим загруженным результатом. Но если пользователь находится на странице каталога и что-то щелкает, я хочу асинхронно загрузить результат без обновления страницы.

Виджет каталога имеет ссылки, которые указывают на метод действия DirectoryResult на GroupController, который обычно возвращает PartialView, если он находится на странице каталога. Но если их нет на странице каталога, я перенаправляю на основной метод действия Каталога, который возвращает представление и загружает всю страницу.

Это код вопроса:

    public ActionResult DirectoryResult(string search)
    {
        if (Request.IsAjaxRequest())
        {
            var groups = _groupService.GetGroupsBySearchExpression(search);
            var premiumGroups = _groupService.FilterPremiumGroups(groups);

            return PartialView(new FundDirectoryViewModel
            {
                Groups = groups,
                PremiumGroups = premiumGroups
            });
        }
        else
        {
            TempData[UIMessageDataKeys.FundDirectorySearch] = search;
            return RedirectToAction("Directory", "Group");
        }
    }

Я показал это одному из парней в офисе, и его немедленным ответом было «это взлом!». Я не знаю, соглашаться с ним или нет, потому что я не знаю лучшего способа сделать это.

Для справки, это определение виджета, который существует на каждой странице:

<div id="DirectoryList" class="directory-list">
    <span>Fund Directory</span>

    <% var letters = new [] { "A", "B", "C", "D", "E", "F", "G", "H", "I", ... }; %>
    <% var current = (Model.Search.IsNotNullOrEmpty()) ? Model.Search : "A"; %>
    <% foreach (var letter in letters) { %>

        <span>
            // use HtmlHelper extension to generate links as our system needs them
            <%= Html.RouteActionLink("funddirectory", "DirectoryResult"
                , letter
                , (letter.ToLower() == current) ? new { @class = "active" } : new { @class = "" })%>

        </span>

    <%} %>
</div>

Есть ли лучший способ для меня определить, должен ли я возвращать PartialView или View в зависимости от страницы, с которой поступил запрос?

Ответы [ 2 ]

2 голосов
/ 04 сентября 2010

В то время как ваше представление определенно может быть улучшено, чтобы избежать всего этого спагетти-кода (используя шаблоны редактора / отображения и HTML-помощники и избегать жесткого кодирования алфавита в представлении :-)), метод действия кажется мне подходящим.Использование Request.IsAjaxRequest для определения того, было ли запрошено действие с помощью AJAX, и возврат частичного представления или нет, перенаправление отлично.

То, что можно считать хаком, это использование TempData вместо использования строки запроса, потому что если пользователь нажмет F5 на перенаправленной странице, он потеряет контекст, но еслиэто поведение, которое вы ожидаете, тогда все в порядке.

Хотя я не знаком с контекстом, мне были бы интересны аргументы, которые парни в вашем офисе использовали, чтобы поддержать свою реакцию на то, что это взлом.

1 голос
/ 04 сентября 2010

Хотя Дарин на 100% прав, а твой код не взломан, я обычно предпочитаю сделать два Действия с разными именами и подписями. Это особенно легко, если вы используете фильтр действий AjaxOnly, например: http://helios.ca/2009/05/27/aspnet-mvc-action-filter-ajax-only-attribute/

public ActionResult DirectoryResult(string search)
{        
        var groups = _groupService.GetGroupsBySearchExpression(search);
        var premiumGroups = _groupService.FilterPremiumGroups(groups);

        return PartialView(new FundDirectoryViewModel
        {
            Groups = groups,
            PremiumGroups = premiumGroups
        });        
}

//optional [AjaxOnly]
public ActionResult DirectoryAjaxResult( string search )
{
        TempData[UIMessageDataKeys.FundDirectorySearch] = search;
        return RedirectToAction("Directory", "Group");
}
...