0

我正在尝试在 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) on type MinarSidur.Controllers.ProfileController\r\nMinarSidur.Models.DataTransfer.UserProfileDTO sendpaycheck(System.String) on type MinarSidur.Controllers.ProfileController

你能帮我完成这个吗?

4

2 回答 2

1

您的异常实际上是在抱怨它们是Profile控制器上这两种方法之间的冲突:

  • 发送工资支票(字符串)
  • 发送邮件(字符串)

不是 Get 和 Get(?); 虽然这也是一个问题。

确实,在执行 RPC 操作以进行更改或触发操作时,您应该使用 POST 动词。通过这样做,您上面提到的路由问题应该得到解决。

更新

您是否考虑过以资源为中心的方法来解决您的问题?在所有情况下,资源都是“配置文件”,并且它似乎具有唯一的 id x。它似乎还有另外两个可能的唯一 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

我会尝试这个并使用(注意。使用名称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" }
        );
于 2012-11-21T14:34:42.223 回答
0

规则重叠。路由中Id的验证会不会是很大的损失?您仍然可以在 Get 操作中将 Id 参数作为 int 参数。如果是这种情况,我认为您可以完全删除 ControllerAndID并使用与您的所有用例匹配的第二个。

于 2012-11-21T13:43:05.643 回答