Chr*_*ton 60 c# query-string asp.net-web-api attributerouting asp.net-web-api-routing
我正在使用System.Web.Http.RouteAttribute
并System.Web.Http.RoutePrefixAttribute
为我的Web API 2应用程序启用更干净的URL.对于我的大部分请求,我可以使用路由(例如Controller/param1/param2
)或者我可以使用查询字符串(例如Controller?param1=bob¶m2=mary
).
不幸的是,对于我的一个控制器(并且只有一个),这会失败.这是我的控制器:
[RoutePrefix("1/Names")]
public class NamesController : ApiController
{
[HttpGet]
[Route("{name}/{sport}/{drink}")]
public List<int> Get(string name, string sport, string drink)
{
// Code removed...
}
[HttpGet]
[Route("{name}/{drink}")]
public List<int> Get(string name, string drink)
{
// Code removed...
}
}
Run Code Online (Sandbox Code Playgroud)
当我使用路由请求时,两者都可以正常工作.但是,如果我使用查询字符串,它会失败,告诉我该路径不存在.
我已经尝试将以下内容添加到我的WebApiConfig.cs
类' Register(HttpConfiguration config)
函数(在默认路由之前和之后),但它没有做任何事情:
config.Routes.MapHttpRoute(
name: "NameRoute",
routeTemplate: "{verId}/Names/{name}/{sport}/{drink}",
defaults: new { name = RouteParameter.Optional, sport = RouteParameter.Optional, drink = RouteParameter.Optional },
constraints: new { verId = @"\d+" });
Run Code Online (Sandbox Code Playgroud)
所以为了清楚起见,我希望能够做到这两点:
localhost:12345/1/Names/Ted/rugby/coke
localhost:12345/1/Names/Ted/coke
Run Code Online (Sandbox Code Playgroud)
和,
localhost:12345/1/Names?name=Ted&sport=rugby&drink=coke
localhost:12345/1/Names?name=Ted&drink=coke
Run Code Online (Sandbox Code Playgroud)
但遗憾的是查询字符串版本不起作用!:(
更新
我完全删除了第二个Action,现在尝试使用带有可选参数的单个Action.我已经改变了我的路线属性,[Route("{name}/{drink}/{sport?}")]
因为托尼建议让运动变得可空,但是现在localhost:12345/1/Names/Ted/coke
由于某些原因这会阻止它成为一条有效的路线.查询字符串的行为与以前相同.
更新2 我现在在我的控制器中有一个单一的动作:
[RoutePrefix("1/Names")]
public class NamesController : ApiController
{
[HttpGet]
[Route("{name}/{drink}/{sport?}")]
public List<int> Get(string name, string drink, string sport = "")
{
// Code removed...
}
}
Run Code Online (Sandbox Code Playgroud)
但是,使用查询字符串时找不到合适的路径,而使用路由方法时则没有.
Mos*_*ain 63
我正面临着同样的问题"如何将搜索参数包含为查询字符串?",而我正在尝试为我当前的项目构建一个web api.谷歌搜索后,以下工作正常:
Api控制器动作:
[HttpGet, Route("search/{categoryid=categoryid}/{ordercode=ordercode}")]
public Task<IHttpActionResult> GetProducts(string categoryId, string orderCode)
{
}
Run Code Online (Sandbox Code Playgroud)
我通过邮递员尝试的网址:
http://localhost/PD/search?categoryid=all-products&ordercode=star-1932
http://localhost/PD is my hosted api
Run Code Online (Sandbox Code Playgroud)
Chr*_*ton 42
经过艰苦的琐事和谷歌搜索,我想出了一个"修复".我不知道这是不是理想/最佳做法/普通老错,但它解决了我的问题.
[Route("")]
除了我已经使用的路线属性之外,我所做的只是添加.这基本上允许Web API 2路由允许查询字符串,因为这现在是有效的路由.
现在的一个例子是:
[HttpGet]
[Route("")]
[Route("{name}/{drink}/{sport?}")]
public List<int> Get(string name, string drink, string sport = "")
{
// Code removed...
}
Run Code Online (Sandbox Code Playgroud)
这使得双方localhost:12345/1/Names/Ted/coke
和localhost:12345/1/Names?name=Ted&drink=coke
有效.
Ton*_*ony 19
使用属性路由,您需要指定默认值,以便它们是可选的.
[Route("{name}/{sport=Football}/{drink=Coke}")]
Run Code Online (Sandbox Code Playgroud)
分配值将允许它是可选的,因此您不必包含它,它将传递要指定的值.
我没有为此测试查询字符串,但它应该工作相同.
我只是重新阅读了这个问题而且我看到你有2个Get动词具有相同的路径,我相信这会引起冲突,因为路由不知道使用哪个,也许使用可选的参数将有所帮助.您还可以指定一个可以为null,并在方法中检查如何继续.
[Route("{name}/{sport?}/{drink?}")]
Run Code Online (Sandbox Code Playgroud)
然后检查方法中的变量以查看它们是否为null并根据需要进行处理.
希望这有帮助,有些人?大声笑
如果不是这个站点,它会有更多关于属性路由的细节.
http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2
从该网站剪辑:
可选参数和默认值您可以通过向参数添加问号来指定参数是可选的,即:
Run Code Online (Sandbox Code Playgroud)[Route("countries/{name?}")] public Country GetCountry(string name = "USA") { }
目前,必须在可选参数上指定默认值才能使操作选择成功,但我们可以调查解除该限制.(如果这很重要,请告诉我们.)
可以用类似的方式指定默认值:
Run Code Online (Sandbox Code Playgroud)[Route("countries/{name=USA}")] public Country GetCountry(string name) { }
可选参数'?' 并且默认值必须出现在参数定义中的内联约束之后.
Jur*_*uri 10
我的部分也是旁注.为了使queryString params起作用,您需要为方法参数提供一个默认值,以使其可选.就像通常调用C#方法时一样.
[RoutePrefix("api/v1/profile")]
public class ProfileController : ApiController
{
...
[HttpGet]
[Route("{profileUid}")]
public IHttpActionResult GetProfile(string profileUid, long? someOtherId)
{
// ...
}
...
}
Run Code Online (Sandbox Code Playgroud)
这允许我像这样调用端点:
/api/v1/profile/someUid
/api/v1/profile/someUid?someOtherId=123
Run Code Online (Sandbox Code Playgroud)
UsingRoute("search/{categoryid=categoryid}/{ordercode=ordercode}")
将使您能够使用mosharaf hossain回答的查询字符串和内联路由参数。写这个答案,因为这应该是最佳答案和最佳方式。Route("")
如果您有多个 Gets/Puts/Posts/Deletes,使用会导致问题。
这是@bhargav kishore mummadireddy 的答案的一个轻微偏差,但一个重要的偏差。他的答案会将查询字符串值默认为实际的非空值。此答案将默认它们为空。
它允许您通过路径路由或使用查询字符串来调用控制器。本质上,它将查询字符串的默认值设置为空,这意味着它将始终被路由。
这对我来说很重要,因为如果未指定查询字符串,我希望返回 400(错误请求),而不是让 ASP.NET 返回“无法在此控制器上找到此方法”错误。
[RoutePrefix("api/AppUsageReporting")]
public class AppUsageReportingController : ApiController
{
[HttpGet]
// Specify default routing parameters if the parameters aren't specified
[Route("UsageAggregationDaily/{userId=}/{startDate=}/{endDate=}")]
public async Task<HttpResponseMessage> UsageAggregationDaily(string userId, DateTime? startDate, DateTime? endDate)
{
if (String.IsNullOrEmpty(userId))
{
return Request.CreateResponse(HttpStatusCode.BadRequest, $"{nameof(userId)} was not specified.");
}
if (!startDate.HasValue)
{
return Request.CreateResponse(HttpStatusCode.BadRequest, $"{nameof(startDate)} was not specified.");
}
if (!endDate.HasValue)
{
return Request.CreateResponse(HttpStatusCode.BadRequest, $"{nameof(endDate)} was not specified.");
}
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
70263 次 |
最近记录: |