检查路由在NancyFX中的RequestStartup中是否有效

时间:2016-03-03 08:15:26

标签: c# .net rest nancy self-hosting

我的wpf应用程序中有一个自我托管的REST API,使用NancyFX构建。该应用程序用于更新固件并在使用USB电缆连接到计算机的不同消费产品上运行诊断程序。

必须将产品连接到计算机才能使用API​​。所以我认为在WindsorNancyBootstrapper中重写RequestStartup()方法进行检查是明智的,这意味着可以在一个位置完成检查,而不是在每个模块中完成。它按预期工作。如果没有连接产品,任何模块都不会处理请求。

但是这会在以下情况中导致不必要的副作用:

  • 产品未连接到计算机
  • 路径无效

这将始终返回404,并显示一条消息,指出设备未连接,而不是“坏网址”消息。我可以将支票移到每个模块,但我讨厌这样做。我想要的是什么:

  • 如果网址无效,无论是否有连接设备,请始终返回404“错误网址”响应而不涉及任何模块
  • 如果网址有效,但没有连接设备,则返回400“无连接设备”而不涉及任何模块

我想在一个地方做这件事。我四处寻找解决方案,但我没有找到任何东西。我在想,也许我的方法是死路一条。毕竟,我正在使用BeforeRequest管道,这可能意味着还没有办法验证URL呢?

我的方法(简化)目前看起来像这样:

protected override void RequestStartup(IWindsorContainer container, IPipelines pipelines, NancyContext context)
{
    pipelines.BeforeRequest.AddItemToEndOfPipeline(ctx =>
    {
        // TODO: Here I would like to check if the url is valid in order to be able to return a 404 "bad url" response

        if (!_hasConnectedDevice)
        {
            // ResponseBase is my base class for all my JSON responses
            var response = new ResponseBase(ctx.Request.Url, Messages.DeviceNotConnected);
            return new JsonResponse(response, new DefaultJsonSerializer())
            {
                StatusCode = HttpStatusCode.NotFound
            };
        }
        if (!_deviceIsReady)
        {
            var response = new ResponseBase(ctx.Request.Url, Messages.DeviceNotReady);
            return new JsonResponse(response, new DefaultJsonSerializer())
            {
                StatusCode = HttpStatusCode.BadRequest
            };
        }


        return null;
    });

    // Catch all unhandled exceptions here.
    pipelines.OnError += (ctx, ex) =>
    {
        var response = new ResponseBase(ctx.Request.Url, ex.Message);
        return new JsonResponse(response, new DefaultJsonSerializer())
        {
            StatusCode = HttpStatusCode.InternalServerError
        };
    };
}

1 个答案:

答案 0 :(得分:0)

我能想到的最好的方法是做一些类似于我们对安全性做的事情,你在INancyModule上创建一个扩展方法,在pipline上添加一些东西来检查设备是否插入并准备就绪如果不是,则返回相关的状态代码,否则只返回null,然后在每个模块中只想使用你添加的USB设备:

this.RequiresUsbThings(); //或者你想要的任何东西:)