我继承了一个WCF项目,其中包含一些构建错误的路由(可以工作),我需要迁移到新的NancyFx项目中。我需要能够在我的Nancy应用程序中定义响应相同GET请求的路由。我暂时无法改变路线。
在WCF项目中,GET请求为...
http://localhost:12345/webapi/GetUsers?UserId=567&Language=en
匹配此UriTemplate:
UriTemplate = "GetUsers?UserId={userId}&Language={language}
我希望这在Nancy
Get["/GetUsers?UserId={userId}&Language={language}"] = p => { ... }
但是相同的GET请求会产生404。
有没有办法构建我的Nancy路由来响应这个GET请求?如果没有,任何解决方法?
我知道这很糟糕,但它是暂时的,直到我可以安排时间与我们的UI团队重写前端以调用正确的休息完整网址。
答案 0 :(得分:8)
约翰,
您的路线是/GetUsers
(顺便说一下,您如何处理/webapi
部分?这是您的应用程序的基本网址还是您正在设置模块路径?)并且您会阅读使用Request.Query
成员的查询字符串。
Query属性返回DynamicDictionary
,您可以使用属性Request.Query.UserId
或字典Request.Query["UserId"]
您无法使查询字符串成为需要匹配的模式的一部分,以便调用路由。如果你真的想要,你可以做的是使用路由条件,这是路由声明中的第二个参数。这使您可以控制谓词,该谓词确定路径是否可以使用。所以你可以做这样的事情
Get["/GetUsers", ctx => ctx.Request.Query.UserId.HasValue && ctx.Request.Query.Language.HasValue] = p {... }
然后你可以将它全部重构为NancyContext上的扩展方法,使其更加整洁
Get["/GetUsers", ctx => ctx.HasQueryValues("UserId", "Language")] = p {... }
并使扩展名像
public static bool HasQueryValues(this NancyContext context, params string[] values)
{
return values.All(x => context.Request.Query[x].HasValue);
}
希望这有帮助!
答案 1 :(得分:5)
继@TheCodeJunkie的回答之后,我有点过度兴奋,因为他想扩展NancyContext
以提供预先检查Query
值以确保请求有效的路由条件。我进一步扩展了NancyContext
以对Form
值,Header
集合甚至Files
集合进行相同的预检查,如下所示:
public static bool HasQuery(this NancyContext context, params string[] values)
{
var query = context.Request.Query;
return values.All(value => query[value].HasValue);
}
public static bool HasForm(this NancyContext context, params string[] values)
{
var form = context.Request.Form;
return values.All(value => form[value].HasValue);
}
public static bool HasHeader(this NancyContext context, params string[] values)
{
var headers = context.Request.Headers;
return values.All(value => !headers[value].FirstOrDefault().IsEmpty());
}
public static bool HasFile(this NancyContext context, params string[] values)
{
var files = context.Request.Files;
return values.All(value => files.Any(file => file.Key == value));
}
这使我可以删除验证查询和表单值的仪式代码(当我记得这样做时,结果并非每次都这样)。因此,您可以获得更易于阅读且更易于记忆的清洁代码,例如:
<强>之前强>
Post["/"]=_=>
{
var form = Request.Form;
if (
!form.username.HasValue ||
!form.password.HasValue ||
!form.email.HasValue ||
!form.claim.HasValue)
{
return HttpStatusCode.UnprocessableEntity;
}
//process form values with confidence
}
<强>后强>
Post["/", ctx => ctx.HasForm("username", "password", "email", "claim")]=_=>
{
//process form values with confidence
};