【问题标题】:MVC action name exposed when javascript disabled禁用 javascript 时暴露的 MVC 操作名称
【发布时间】:2014-09-01 23:02:46
【问题描述】:

我们目前正在开发一个 MVC 应用程序,但我们的 URL 遇到了一些问题。

我们在控制器中有两个简单的操作方法:

public PartialViewResult Index(ListingPagePress currentPage)
    {
        var model = new ListingPagePressViewModel(currentPage);

        var pressReleaseChildren = GetData(currentPage, 0);
        model.PressReleasePages = pressReleaseChildren;
        model.TotalPages = 3;

        return PartialView(model);
    }

    public PartialViewResult PressReleaseList(ListingPagePress currentPage, int pageNo)
    {
        IEnumerable<PressReleasePageViewModel> data = GetData(currentPage, pageNo);
        return PartialView(data);
    }

PressReleaseList 使用动作呈现,即:

@Html.Action("PressReleaseList", new { pageNo = 0 })

然后我们有一些简单的分页:

@for (var i = 0; i < Model.TotalPages; i++)
{
@Ajax.ActionLink(i.ToString(), "Index",
        new { pageNo = i },
        new AjaxOptions
        {
            UpdateTargetId = "pressReleaseTable",
            OnBegin = "OnAjaxRequestBegin",
            OnFailure = "OnAjaxRequestFailure",
            OnSuccess = "OnAjaxRequestSuccess",
            OnComplete = "OnAjaxRequestComplete"
        })
        }

不引人注目的 ajax 工作得很好。问题是,如果客户端禁用了 javascript,他们最终会通过一个可怕的 url 导航到部分视图,例如:

http://example.com/press-releases/PressReleaseList/?pageNo=1

而我们希望保留真实的 URL 结构,即:http://example.com/press-releases/?pageNo=1

我们如何实现这一目标?映射路线是唯一的可能性吗?这对我们来说非常困难,因为我们正在使用 CMS,所以我们永远不知道确切的 url 前缀是什么,因为用户可以更改“新闻稿”的 url。

任何建议将不胜感激

问候 点开发

【问题讨论】:

  • 为什么支持禁用 javascript 的客户端很重要?听起来像是 10 年前的问题。我想知道你为什么还要关心?
  • 主要是因为搜索引擎没有启用Javascript,所以他们会索引带有ActionNAme的url。

标签: asp.net-mvc asp.net-mvc-4 asp.net-ajax


【解决方案1】:

基本上,您要实现的是从 URL 中删除操作名称。

Index 方法实现了这一点,因为它有一个默认的操作名称 Index。

因此,您可以通过将int? pageNo 作为参数来重载索引操作。如果它不为空,则分支,所以它最终是这样的:

public PartialViewResult Index(ListingPagePress currentPage, int? pageNo)
{
    if (pageNo == null)
    {
        var model = new ListingPagePressViewModel(currentPage);

        var pressReleaseChildren = GetData(currentPage, 0);
        model.PressReleasePages = pressReleaseChildren;
        model.TotalPages = 3;

        return PartialView(model);
    }
    else
    {
        IEnumerable<PressReleasePageViewModel> data = GetData(currentPage, pageNo);
        return PartialView(data);
    }
}

您可以通过实现一个动作选择器并通过使用不同的动词或不同的标头使第二次调用转到不同的方法来使其更加分离。

作为旁注 MVC vNext 支持方法重载,因此您可以根据额外参数拆分方法。

【讨论】:

  • 感谢 Yishai - 你的帖子让我找到了最终的解决方案,重载了 Index 方法。
  • 我假设使用 ActionSelector?另请注意(我意识到它可能不是 100% 适用于您的情况)如果您关心 url 形状,您也可以使用属性路由
猜你喜欢
  • 1970-01-01
  • 2021-08-02
  • 2020-06-02
  • 2011-09-07
  • 1970-01-01
  • 1970-01-01
  • 2018-06-19
  • 2015-05-23
  • 2012-08-20
相关资源
最近更新 更多