【问题标题】:Any way to test if an action exists based on a URL?有什么方法可以测试基于 URL 的操作是否存在?
【发布时间】:2015-08-25 12:19:08
【问题描述】:

我的登录页面有一个与之关联的redirectURL,但redirectURL 并不总是有效的,例如,如果用户注销然后单击按钮以POST 到没有关联GET 方法的url,或者如果RedirectToAction被使用了。

在重定向之前,我尝试了很多方法来查看路由是否有效,但都没有奏效。

我的返回网址是/MyApplicationName/SomeController/SomeAction/12345

我试过了:

ViewEngineResult viewResult = ViewEngines.Engines.FindView(ControllerContext, returnUrl, null);

BuildManager.GetObjectFactory(returnUrl, false)

还有一些我在 SO 上找到的关于 RouteData 的内容。

到目前为止没有任何效果。

有什么想法吗?

【问题讨论】:

  • 要做到这一点涉及很多(包括 .NET 反射)。看看MvcRouteTester的源代码和MvcSiteMapProviderAuthorizeAttributeAclModule
  • 您自己找到解决方案了吗?
  • 我还没有解决这个问题,bug 还在 bugtracker 中!我可能只是为所有帖子手动编写一些重定向键值对,并在重定向之前检查它们。如果我有时间,我会尝试提取控制器和操作并进行一些反思以检查控制器并查看它是否具有 URL 的有效方法,如果我可以读取属性。走着瞧。如果我以这种方式解决它,我将在下面发布答案。

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


【解决方案1】:

你可以试试下面的,

if (Request.Url != null)
{
    var request = new HttpRequest(null, Request.Url.Scheme + "://" + Request.Url.Authority + givenUrl, string.Empty);
    var response = new HttpResponse(new StringWriter());
    var httpContext = new HttpContext(request, response);
    var routeData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(httpContext));

    if (routeData != null)
    {
        var values = routeData.Values;
        var controllerName = values["controller"].ToString();
        var actionName = values["action"].ToString();

        var controllerType =
            (from a in AppDomain.CurrentDomain.GetAssemblies()
            from t in a.GetTypes()
            where typeof(IController).IsAssignableFrom(t) &&
                  string.Equals(controllerName + "Controller", t.Name, StringComparison.OrdinalIgnoreCase)
            select t).FirstOrDefault();
        if (new ReflectedControllerDescriptor(controllerType).GetCanonicalActions()
                                                             .Any(x => x.ActionName == actionName))
        {
            //Action Exists
        }

    }
}

这里,

  1. 为 httpcontext 创建请求和响应以测试 控制器和操作。

  2. 使用 httpcontext 收集路由数据。

  3. 通过反射找到控制器类型。

  4. 从控制器类型中找到动作名称并测试是否 routedata 中的 actionname 存在于来自的动作名称集合中 控制器。

希望这会有所帮助。

【讨论】:

  • 看起来不错,我只需要弄清楚如何将其过滤为仅 GET 操作,因为 POST 操作不适用于重定向
  • 您的代码运行良好!为了完成它,我循环遍历所有操作而不是使用 .Any(因为可能存在同名的 GET 和 POST),然后我将 ActionDescriptor 转换为具有 MethodInfo 属性的 ReflectedActionDescriptor .然后我可以做reflectedAction.GetCustomAttributes(typeof (ActionMethodSelectorAttribute), true).Cast<ActionMethodSelectorAttribute>().ToList(); 这会给我所有的属性。如果有任何属性是 'HttpPostAttribute' 类型,那么它是一个 POST,否则它是一个 GET。
猜你喜欢
  • 2011-01-17
  • 1970-01-01
  • 1970-01-01
  • 2016-12-01
  • 1970-01-01
  • 2020-10-27
  • 1970-01-01
  • 2013-04-02
  • 2010-11-24
相关资源
最近更新 更多