这是一个“hack”吗?如果是,是否有更好的方法来确定返回哪个 ActionResult?

发布于 2024-09-17 00:37:53 字数 1769 浏览 12 评论 0原文

我在每个页面上都有一个 A - Z 目录“小部件”。如果用户在主页上单击目录中的某些内容,我想加载目录页面并加载相应的结果。但是,如果用户位于目录页面上并且单击了某些内容,我想异步加载结果而不进行页面刷新。

目录小部件具有指向 GroupController 上的 DirectoryResult 操作方法的链接,如果它们位于目录页面上,该方法通常会返回 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?

I have an A - Z directory 'widget' that I have on every page. If the user is on the home page and they click something in the directory, I want to load up the directory page with the corresponding result loaded. But if the user is on the directory page and they click something, I want to asynchronously load the result without doing a page refresh.

The directory widget has links that point to the DirectoryResult action method on the GroupController, which would normally return a PartialView if they're on the directory page. But if they're not on the directory page, I redirect to the main Directory action method which returns a View and loads the entire page.

This is the code in question:

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

I showed this to one of the guys in the office and his immediate response was "that's a hack!". I don't know whether to agree with him or not though, because I don't know any better way to do it.

For reference, this is the definition of the widget that exists on every page:

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

Is there a better way for me to determine whether I should return a PartialView or a View depending on the page the request comes from?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧时模样 2024-09-24 00:37:54

虽然您的视图绝对可以改进以避免所有这些意大利面条代码(使用编辑器/显示模板和 HTML 帮助器并避免在视图中对字母表进行硬编码:-)),但操作方法对我来说似乎很好。使用 Request.IsAjaxRequest 来确定是否已使用 AJAX 请求该操作并返回部分视图,如果没有则重定向是完全可以的。

可以被视为黑客的是使用 TempData 而不是使用查询字符串,因为如果用户在重定向页面上按 F5,他将丢失上下文,但是如果这是您期望的行为,那么就可以了。

虽然我不熟悉背景,但我对你们办公室的人用来支持他们对这是黑客行为的反应的论点感兴趣。

While your view can definitely be improved to avoid all this spaghetti code (using editor/display templates and HTML helpers and avoid hard-coding an alphabet in a view :-)), the action method seems fine to me. Using Request.IsAjaxRequest to determine whether the action has been requested with AJAX and return a partial view or if not redirect is perfectly fine.

What could be considered as a hack is the usage of TempData instead of using a query string because if the user presses F5 on the redirected page he will loose the context, but if this is the behavior you expect then it's ok.

While I am not familiar with the context I would be interested in the arguments that the guys at your office used to support their reaction of this being a hack.

酒解孤独 2024-09-24 00:37:54

虽然 Darin 是 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");
}

While Darin is 100% correct and your code is not a hack I usually prefer making two Actions with different names and signatures. This is especially easy if you use an AjaxOnly action filter such as:
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");
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文