这可能不是很清楚所以让我详细说明:
正如我目前所知,"行动" web api控制器的数量由参数的数量和类型决定。因此,如果您传入两个字符串,您将获得方法签名中包含两个字符串的Get或Post。
我想做的是设置几条这样的路线:
config.Routes.MapHttpRoute(
name: "fileFunctionsDelete",
routeTemplate: "api/{controller}/{appName}/{userID}/Delete",
defaults: new {
appName = RouteParameter.Optional,
userID= RouteParameter.Optional,
fileAction= RouteParameter.Optional
}
);
config.Routes.MapHttpRoute(
name: "fileFunctionsUpload",
routeTemplate: "api/{controller}/{appName}/{userID}/Upload",
defaults: new {
appName = RouteParameter.Optional,
userID= RouteParameter.Optional,
fileAction= RouteParameter.Optional
}
);
这些显然应该转到同一个控制器,但在MVC网站上,我会去一个名为"删除"或"上传"。
到目前为止,我所看到的只是获取和帖子,其中params的数量和类型用于确定所调用的内容。这太令人困惑了。
有没有什么方法可以让它更多" MVC网站" - 就像通话行为一样?
澄清:如果我想要一个特定的行动,我会通过名字来称呼它。 " public ActionResult ThisAction(object [] params)。在web api中,所有的sigatures都像Get或Put或Post。我希望能够说出像" url:../删除"并调用相应的删除获取或发布。我不希望必须通过传入的参数数量来区分我的方法,或者解析字符串以查看用户的意图。这些是失败的食谱
更新
Kenneth,lgor和Tu Hoang的答案都有关键信息需要合在一起(限制路线,动作,模型属性等方法),每个信息都有完整答案的信息。我无法将它们全部标记,所以我标记了最正确的#34;对于我的问题。
答案 0 :(得分:4)
就个人而言,当您想要在您的操作上使用自定义路由时,我发现属性路由更容易使用。在官方ASP.NET网站上As exemplified,您可以使用[Route]
属性将路由直接应用于您的操作:
e.g。
public class CustomerController : ApiController
{
[Route("api/Customer/{model.LastName}/{model.FirstName}/Upload")]
public void Post(CustomerModel model)
{
// ...
}
}
我不记得你能否以{controller}
的方式替换默认路线,但我相信你可以。我有一个复杂的对象作为参数进入,因此是点符号,但如果你只使用简单类型,那么你可以直接使用变量名(例如[Route("api/Customer/{lastName}/{firstName}/Upload")]
)。
您还可以将[RoutePrefix]
属性应用于控制器,这样您就不必重复api/Customer/
,例如,对每个操作都重复:
[RoutePrefix("api/Customer")]
public class CustomerController : ApiController
{
[Route("{model.LastName}/{model.FirstName}/Upload")]
public void Post(CustomerModel model)
这不是一个非常好的例子,因为我正在演示一个POST并且参数是通过URL来的,但它应该证明这个想法。
答案 1 :(得分:1)
您可以在action
中指定routeTemplate
占位符,就像在MVC中一样。请参阅下面的代码,我将Delete
替换为{action}
。如果你在参数之间是可选的,那么它可能会变得棘手,所以这里的顺序可能很关键,我希望它是api/{controller}/{action}/{appName}/{userID}/
或api/{action}/{controller}/{appName}/{userID}/
。
config.Routes.MapHttpRoute(
name: "fileFunctionsDelete",
routeTemplate: "api/{controller}/{appName}/{userID}/{action}",
defaults: new {
appName = RouteParameter.Optional,
userID= RouteParameter.Optional,
fileAction= RouteParameter.Optional
}
);
(来自评论)...带有样本方法签名
方法签名与任何其他签名一样。
// I am not sure what type of parameters these are so I am going to take a wild guess
[HttpPost]
public async Task<IHttpActionResult> Post(string appName = null, int? userID = null, CancellationToken token) {}
这取决于你传递的是什么。这可以很好地使用您可能拥有的post,put,get,delete或自定义名称。如果你想根据http动词限制访问,请记住应用HttpGet / HttpPost / HttpPut / HttpDelete属性(这里没什么不同)。
您还可以使用Kennith指定的Route和RoutePrefix属性。我不会窃取他的答案,这是一个很好的答案,如果不是首选的话,也完全可以接受,视情况而定。
答案 2 :(得分:1)
如下所示?您需要action
默认值并在控制器操作上匹配ActionName
属性。
话虽这么说,你的路线样本看起来需要一些工作。具体来说,让所有路由参数可选是什么意思。如果userId
是可选的,删除会做什么?如果appName
是可选的,那么路由甚至是有效的。
config.Routes.MapHttpRoute(
name: "fileFunctionsDelete",
routeTemplate: "api/{controller}/{appName}/{userID}/Delete",
defaults: new {
appName = RouteParameter.Optional,
userID= RouteParameter.Optional,
action = "Delete"
},
constraints: new { HttpMethod = new HttpMethodConstraint(HttpMethod.Post) });
);
[HttpPost]
[ActionName("Delete")]
public async Task<HttpResponseMessage> DeleteUser(
string controller,
string appName,
string userID)
{
}