您如何调试MVC 4 API路由?


71

我有一个使用RESTsharp与我的MVC4 RESTful服务器通信的WP7游戏,但是我经常遇到使请求正常工作的问题,因此我想调试失败的地方。

这是一个示例,其中我的ConstructorGameController被命中,但是该Post方法未命中,我不明白为什么。

客户代码:

public void JoinRandomGame()
{
  client = new RestClient
  {
      CookieContainer = new CookieContainer(),
      BaseUrl = "http://localhost:21688/api/",
  };

  client.Authenticator = GetAuth();

  RestRequest request = new RestRequest(Method.POST)
  {
      RequestFormat = DataFormat.Json,
      Resource = "game/"

  };

  client.PostAsync(request, (response, ds) =>
  {});
}

服务器代码:

    public void Post(int id)
    {
        if (ControllerContext.Request.Headers.Authorization == null)
        {
            //No auth
        }
        if (!loginManager.VerifyLogin(ControllerContext.Request.Headers.Authorization.Parameter))
        {
            //Failed login
        }

        string username;
        string password;
        LoginManager.DecodeBase64(ControllerContext.Request.Headers.Authorization.Parameter, out username, out password);
        gameManager.JoinRandomGame(username);
    }

我的路线是这样的

       routes.MapHttpRoute(
            name: "gameAPI",
            routeTemplate: "api/game/{gameId}",
            defaults: new
            {
                controller = "game",
                gameId = RouteParameter.Optional
            }             
        );


通过WP7仿真器访问RESTful服务时,看不到调试器信息吗?
Mech0z 2012年

Answers:


36

RouteDebugger对于确定将/将不会命中哪些路由非常有用。

http://nuget.org/packages/routedebugger


上面的评论中已经提出过,但是我看不出应该怎么告诉我哪里出了问题?gratisimage.dk/graphic/images/2012/July/13/C044_50005206.jpg这就是我得到的,并且对api / game / {gameId}控制器=游戏,gameId =我应该做的事情很了解。
Mech0z 2012年

根据您的屏幕截图,gameId不是可选的。尝试包括gameId,看看它是否符合您的路线……
Paul Fleming

另请注意,您的Post操作不能接受可选的gameId。考虑将其设置为强制性,或将参数设置为可空(int?gameId)或设置默认值(int gameId = 0)。
Paul Fleming

1
将您的发布参数重命名为gameId。
保罗·弗莱明

那什么也没做(我只重命名了它是因为我试图删除该参数(我不使用它,只是为了试图使它命中方法而被添加))
Mech0z 2012年

106

另一种方法是在其中添加事件处理程序Global.asax.cs以接收传入的请求,然后在VS调试器中查看路由值。重写Init方法如下:

public override void Init()
{
    base.Init();
    this.AcquireRequestState += showRouteValues;
}

protected void showRouteValues(object sender, EventArgs e)
{
    var context = HttpContext.Current;
    if (context == null)
        return;
    var routeData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(context)); 
}

然后在其中设置一个断点showRouteValues并查看其中的内容routeData

请记住,在Web API项目中,Http路由位于WebApiConfig.cs,而不是RouteConfig.cs


14
又快又脏,正是我所需要的!
凯蒂·基利安

1
这不能扩展到具有数十/数百个控制器的解决方案。
玛丽亚·因内斯·帕尼萨里'17

1

请注意,此程序包适用于c#。似乎不支持vb.net。
Tim Murphy

6
试过这个。对于添加了Web API的ASP.NET MVC 5项目不起作用。然后,由于其很多依赖项,我在卸载项目时完全弄乱了我的项目。考虑它仅安装。
2014年

1
它甚至搞砸了我的Web API 2项目-为什么调试工具需要将Razor,Twitter Bootstrap和其他附件添加到严格的JSON Web服务中?Phil Haack的工具更好,而且非常简单。
2013年

1
我不小心将软件包安装到了错误的项目(只是dll库项目),该项目无论如何都无法调试路由。因此,在发现不适用于MVC 5后,我需要清理的剩余垃圾要多两倍
。– stannius


0

GameController是从ApiController派生的吗?您正在使用WebApi吗?

如果没有,那么我认为“ / api /”是为新的WebApi功能保留的。尝试将您的路由和控制器名称更改为“ gameapi”

但是,如果您使用的是WebApi。

然后从您的BaseUrl中删除api

  client = new RestClient
  {
      CookieContainer = new CookieContainer(),
      BaseUrl = "http://localhost:21688/",
  };

是的,我有它在工作,但是当我有一些我不工作时,我想不出一种好方法来做,但是我的控制器就像这个pastebin.com/qki60LyU
Mech0z 2012年

然后,您可以通过“ flem s”链接使用RouteDebugger,这与我的链接相同:)只需在WP7使用的页面上运行它,即可在浏览器中进行操作。您也可以考虑安装Elmah-nuget.org/packages/elmah
Michal Franc

那只是给我一个XML文件(因此,现在来自routedebugger的信息),而且当我运行它时,我按我的Get而不是我的Post(工作正常)
Mech0z 2012年

您的Post动作是否由[HttpPost]属性修饰?
米哈尔·法兰克

之前不需要pastebin.com/qki60LyU,我的Get请求工作正常,我只是尝试使用它,但没有骰子
Mech0z 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.