MVC 属性路由无效

50

我对MVC框架比较新,但我已经有一个使用AttributeRouting(NuGet包)的API控制器的Web项目-然而,我正在开始另一个项目,它就是不想按照我设定的路由走。

控制器:

public class BlazrController : ApiController
{
    private readonly BlazrDBContext dbContext = null;
    private readonly IAuthProvider authProvider = null;

    public const String HEADER_APIKEY = "apikey";
    public const String HEADER_USERNAME = "username";

    private Boolean CheckSession()
    {
        IEnumerable<String> tmp = null;
        List<String> apiKey = null;
        List<String> userName = null;

        if (!Request.Headers.TryGetValues(HEADER_APIKEY, out tmp)) return false;
        apiKey = tmp.ToList();

        if (!Request.Headers.TryGetValues(HEADER_USERNAME, out tmp)) return false;
        userName = tmp.ToList();

        for (int i = 0; i < Math.Min(apiKey.Count(), userName.Count()); i++)
            if (!authProvider.IsValidKey(userName[i], apiKey[i])) return false;

        return true;
    }

    public BlazrController(BlazrDBContext db, IAuthProvider auth)
    {
        dbContext = db;
        authProvider = auth;
    }

    [GET("/api/q/users")]
    public IEnumerable<string> Get()
    {

        return new string[] { "value1", "value2" };
    }

    [GET("api/q/usersauth")]
    public string GetAuth()
    {
        if (!CheckSession()) return "You are not authorized";

        return "You are authorized";
    }
}

AttributeRoutingConfig.cs

public static class AttributeRoutingConfig
{
    public static void RegisterRoutes(RouteCollection routes) 
    {    
        // See http://github.com/mccalltd/AttributeRouting/wiki for more options.
        // To debug routes locally using the built in ASP.NET development server, go to /routes.axd

        routes.MapAttributeRoutes();
    }

    public static void Start() 
    {
        RegisterRoutes(RouteTable.Routes);
    }
}

Global.asax.cs:

// 注意:如需启用IIS6或IIS7经典模式,请访问http://go.microsoft.com/?LinkId=9394801

public class WebApiApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
    }
}
当我试图导航到 /api/q/users 时,我收到了一个 404 找不到错误。如果我更改路由为 "/api/blazr/users",我会收到有关多个操作和无法确定要执行哪个操作的错误。
欢迎任何帮助 - 我只需要一个小推动就能找出问题所在,不需要完全解决它(我需要学习!)
谢谢
编辑
routes.axd:
api/{controller}/{id}
{resource}.axd/{*pathInfo}          
{controller}/{action}/{id}

当您使用AttributeRouting中的“路由调试器”(应该在~/routes.axd处可用)时,是否可以看到来自属性的预期路由,例如/api/q/users - David Tansey
不,只有api/{controller}/{id}、{resource}.axd/{*pathInfo}和{controller}/{action}/{id}。当我在MapAttributeRoutes()上中断应用程序时,路由集合返回0个路由... - Teagan42
我通过在我的控制器中实现IController接口,在routes.axd中显示了路由 - 但仍然不完全正确(返回空页面)。 - Teagan42
请告诉我们您是如何解决它的。 - David Tansey
我更新了问题。问题在于我有MVC AttributeRouting NuGet,但需要web api nuget来使用AttributeRouting。 - Teagan42
6个回答

133

你不仅需要在App_Start\RouteConfig.cs文件中调用routes.MapMvcAttributeRoutes()方法,而且必须将其放在定义默认路由之前!我是将它放在了忽略{resource}.axd{*pathInfo}之后。我才发现这样做可以让我的MVC 5网站正常使用属性路由。

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapMvcAttributeRoutes();

        routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Account", action = "Index", id = UrlParameter.Optional }
        );

    }

5
这对我很有用,谢谢!不确定为什么微软的那些蠢货无法记录这个简单的东西。 - user275801
1
这就是造成了差异的原因! - Dragos Durlut

39

在你的App_Start/RoutesConfig.cs文件中,确保调用以下代码行:

  routes.MapMvcAttributeRoutes();

21
对于像我这样盲目复制粘贴代码的人,请在尝试之前查看@Derreck_Dean下面的答案。这个答案不完整。 - makhdumi

8
在nuGet包管理器中为您的项目安装Web API Web Host包,然后将此类添加到app_start文件夹中的WebApiConfig.cs中(如果不存在,请创建):
  public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.MapHttpAttributeRoutes(); // pay attention to this method
//here you can map any mvc route
            //config.Routes.MapHttpRoute(
            //    name: "DefaultApi",
            //    routeTemplate: "api/{controller}/{id}",
            //    defaults: new { id = RouteParameter.Optional }
            //);
            config.EnableSystemDiagnosticsTracing();
        }
    }

尝试将您的Global.asax配置更改为:

public class WebApiApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            GlobalConfiguration.Configure(WebApiConfig.Register);
        }
    }

附言:

浏览此文章,非常有用 http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2

干杯


谢谢,这让我意识到我一直在无意识地关注MapMvcAttributeRoutes而不是MapHttpAttributeRoutes - Sandor Drieënhuizen

4
我来到这里寻找与RoutePrefix相关的答案。经过一些测试,我发现只是简单地添加一个没有后续路由属性的 [RoutePrefix("MyPrefix")],意味着RoutePrefix被忽略了。Haack的routedebugger对于确定这一点非常有帮助: https://haacked.com/archive/2008/03/13/url-routing-debugger.aspx/
只需通过NuGet添加它,这将向您的appsettings添加一行代码,然后在您的页面底部显示所有路由。强烈推荐用于任何路由问题。
最终,我的最终版本如下: [RoutePrefix("Asset/AssetType")] [Route("{action=index}/{id?}")]

2

请确保您已安装NuGet包“WebApp API”以使用AttributeRouting。


那是如何工作的? - Nabeel

0
你需要在路由中包含routes.MapMvcAttributeRoutes();,确保它在默认路由之前。
public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapMvcAttributeRoutes();

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接