我正在尝试在Web API中创建一个RouteConfig,它允许以下模式:
模式:
/api/{controller}
/api/{controller}/{id} (int, optional)
/api/{controller}/{action}
/api/{controller}/{action}/{id} (int, optional)
用例:
/api/profile/ (get all profiles)
/api/profile/13 (get profile number 13)
/api/profile/sendemail/ (send email to all profiles)
/api/profile/sendmail/13 (send email to profile number 13)
我正在尝试的是以下内容:
routes.MapHttpRoute(
name: "ControllerAndID",
routeTemplate: "api/{controller}/{id}",
defaults: null,
constraints: new { id = @"^\d+$" } // Dekkar heiltölur eingöngu í id parameter
);
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { action = "Get", id = RouteParameter.Optional }
);
我得到的错误是:
找到与请求匹配的多个操作: \ r \ nMinarSidur.Models.DataTransfer.UserProfileDTO sendmail(System.String) 在类型上 MinarSidur.Controllers.ProfileController \ r \ nMinarSidur.Models.DataTransfer.UserProfileDTO sendpaycheck(System.String)类型MinarSidur.Controllers.ProfileController
你能帮我完成吗?
答案 0 :(得分:1)
您的异常实际上抱怨他们在Profile
控制器上的这两种方法之间存在冲突:
不是Get and Get(?);虽然这也是一个问题。
实际上,在执行进行更改或触发操作的RPC操作时,您应该使用POST动词。这样做可以解决上面提到的路由问题。
<强>更新强>
您是否考虑过针对您问题的更加以资源为中心的方法?在所有情况下,资源都是“Profile”,它似乎具有唯一的id。它似乎还有另外两个可能的唯一id的电子邮件和ssn?
如果这些是您可以接受的URL
http://localhost/api/profile
http://localhost/api/profile/x
http://localhost/api/profile/?email=myemail@x.com
http://localhost/api/profile/?ssn=x
你可以使用:
public class ProfileController : ApiController
{
public string Get(int id)
{
return string.Format("http://localhost/api/profile/{0}", id);
}
public string Get([FromUri] string email = null, [FromUri] int? ssn = null)
{
if (!string.IsNullOrEmpty(email))
{
return string.Format("http://localhost/api/profile/?email={0}", email);
}
if (ssn.HasValue)
{
return string.Format("http://localhost/api/profile/?ssn={0}", ssn.Value);
}
return "http://localhost/api/profile";
}
}
只使用标准的webapi路由:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
<强>但是强>
如果您确实想继续使用/ email和/ ssn,则可能会遇到电子邮件问题...特别是“。”在电子邮件地址中,这可能会混淆路由引擎...为此,您必须设置一个尾部斜杠,即http://localhost/api/profile/email/me@me.com/
我认为您会发现http://localhost/api/profile/email/me@me.com
无效。
这支持:
http://localhost/api/profile
http://localhost/api/profile/x
http://localhost/api/profile/email/myemail@x.com/
http://localhost/api/profile/ssn/x
我会尝试这个并使用(NB。使用名称 rpcId 来区分路线):
public class ProfileController : ApiController
{
public string Get(int id)
{
return string.Format("http://localhost/api/profile/{0}", id);
}
public string Get()
{
return "http://localhost/api/profile";
}
[HttpGet]
public string Ssn(int rpcId)
{
return string.Format("http://localhost/api/profile/ssn/{0}", rpcId);
}
[HttpGet]
public string Email(string rpcId)
{
return string.Format("http://localhost/api/profile/email/{0}", rpcId);
}
}
我的路由将是:
config.Routes.MapHttpRoute(
name: "ProfileRestApi",
routeTemplate: "api/profile/{id}",
defaults: new { id = RouteParameter.Optional, Controller = "Profile" }
);
config.Routes.MapHttpRoute(
name: "PrfileRpcApi",
routeTemplate: "api/profile/{action}/{rpcId}",
defaults: new { Controller = "Profile" }
);
答案 1 :(得分:0)
规则重叠。路由中Id的验证是否会造成巨大损失?在Get操作中,您仍然可以将Id参数作为int。如果是这种情况,我认为您可以完全删除ControllerAndID ,只需使用与您的所有用例匹配的第二个。