Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ASP.NET WebApi-具有类似操作方法的两个控制器_C#_Asp.net_Asp.net Mvc_Asp.net Web Api_Routes - Fatal编程技术网

C# ASP.NET WebApi-具有类似操作方法的两个控制器

C# ASP.NET WebApi-具有类似操作方法的两个控制器,c#,asp.net,asp.net-mvc,asp.net-web-api,routes,C#,Asp.net,Asp.net Mvc,Asp.net Web Api,Routes,我有一个场景,其中我有两个不同的控制器,每个控制器都有多个Get方法。我用ActionName属性修饰了这些方法,但是路由没有像我认为的那样工作 ContactController public ContactModel GetContactByID(string id) { ... } [ActionName("username")] public ContactModel GetContactByUserName(string text) { ... }

我有一个场景,其中我有两个不同的控制器,每个控制器都有多个Get方法。我用
ActionName
属性修饰了这些方法,但是路由没有像我认为的那样工作

ContactController

public ContactModel GetContactByID(string id)
{
    ...
}

[ActionName("username")]
public ContactModel GetContactByUserName(string text)
{
    ...
}
public PaymentModel Get(Guid id)
{
    ...
}

[HttpGet, ActionName("sale")]
public PaymentActivityModel Sale(Guid id)
{
    ...
}
[RoutePrefix("api/client/{clientId}/Contact")]
public class ContactController
{
    // this uses conventional route
    public ContactModel GetContactByID(string id)
    {
        ...
    }

    [Route("username/{userName}")]
    public ContactModel GetContactByUserName(string userName)
    {
        ...
    }
}
[RoutePrefix("api/client/{clientId}/Payment")]
public class PaymentController
{
    // this uses conventional route
    public PaymentModel Get(Guid id)
    {
        ...
    }

    [HttpGet, Route("sale/{id}")]
    public PaymentActivityModel Sale(Guid id)
    {
        ...
    }
}
PaymentController

public ContactModel GetContactByID(string id)
{
    ...
}

[ActionName("username")]
public ContactModel GetContactByUserName(string text)
{
    ...
}
public PaymentModel Get(Guid id)
{
    ...
}

[HttpGet, ActionName("sale")]
public PaymentActivityModel Sale(Guid id)
{
    ...
}
[RoutePrefix("api/client/{clientId}/Contact")]
public class ContactController
{
    // this uses conventional route
    public ContactModel GetContactByID(string id)
    {
        ...
    }

    [Route("username/{userName}")]
    public ContactModel GetContactByUserName(string userName)
    {
        ...
    }
}
[RoutePrefix("api/client/{clientId}/Payment")]
public class PaymentController
{
    // this uses conventional route
    public PaymentModel Get(Guid id)
    {
        ...
    }

    [HttpGet, Route("sale/{id}")]
    public PaymentActivityModel Sale(Guid id)
    {
        ...
    }
}
路线

config.Routes.MapHttpRoute(
    "PaymentControllerActionId", 
    "api/client/{clientId}/{controller}/{action}/{id}", 
    defaults: null 
);

config.Routes.MapHttpRoute(
    "ContactControllerActionText", 
    "api/client/{clientId}/{controller}/{action}/{text}", 
    defaults: null
);

config.Routes.MapHttpRoute(
    "ClientControllerId", 
    "api/client/{clientId}/{controller}/{id}", 
    new { id = RouteParameter.Optional }
);
当我导航到付款时,它工作正常。但当我导航到联系人时,我会收到:

未找到与请求URI匹配的HTTP资源,…/api/client/../contact/username/exampleUserName

在与请求匹配的控制器“联系人”上未找到任何操作

我的印象是参数名将与操作名匹配(
text
vs.
id

使用
Guid
id和
string
id是否存在问题


这是一个面向客户端的API,我有一个客户端友好的ContactID,它是一个字符串。然而PaymentID是一个Guid。

首先我想指出,您的路线没有多大意义

此路由表示它是用于PaymentControllerActionId的,但是您将路由保持打开状态以使用任何控制器,而不是指定它仅用于PaymentControllerActionId

config.Routes.MapHttpRoute(
    "PaymentControllerActionId", 
    "api/client/{clientId}/{controller}/{action}/{id}", 
    defaults: null 
);
回答你的问题。您可能需要将{text}指定为可选的RouteParameter。否则,框架通常希望您已经定义了一个自定义路由约束(并且您应该在{clientId}IMO上有一个路由约束)


此外,如果您的某个操作需要GUID。将其作为Guid参数类型,WebAPI将正确匹配它。或者,由于这两个函数都需要名称或guid,因此您只能有一个接受字符串的函数,并且在db中执行与guid或名称匹配的select语句并返回联系人。更少的代码,更容易阅读,更有意义。

如果您使用的是Web API 2,那么您可以为此使用属性路由

在下面的示例中,控制器混合使用传统+属性路由,但如果需要,可以将其更改为仅按属性路由

例如:

路线配置

config.MapHttpAttributeRoutes();

config.Routes.MapHttpRoute(
    "ClientControllerId", 
    "api/client/{clientId}/{controller}/{id}", 
    new { id = RouteParameter.Optional }
);
ContactController

public ContactModel GetContactByID(string id)
{
    ...
}

[ActionName("username")]
public ContactModel GetContactByUserName(string text)
{
    ...
}
public PaymentModel Get(Guid id)
{
    ...
}

[HttpGet, ActionName("sale")]
public PaymentActivityModel Sale(Guid id)
{
    ...
}
[RoutePrefix("api/client/{clientId}/Contact")]
public class ContactController
{
    // this uses conventional route
    public ContactModel GetContactByID(string id)
    {
        ...
    }

    [Route("username/{userName}")]
    public ContactModel GetContactByUserName(string userName)
    {
        ...
    }
}
[RoutePrefix("api/client/{clientId}/Payment")]
public class PaymentController
{
    // this uses conventional route
    public PaymentModel Get(Guid id)
    {
        ...
    }

    [HttpGet, Route("sale/{id}")]
    public PaymentActivityModel Sale(Guid id)
    {
        ...
    }
}
PaymentController

public ContactModel GetContactByID(string id)
{
    ...
}

[ActionName("username")]
public ContactModel GetContactByUserName(string text)
{
    ...
}
public PaymentModel Get(Guid id)
{
    ...
}

[HttpGet, ActionName("sale")]
public PaymentActivityModel Sale(Guid id)
{
    ...
}
[RoutePrefix("api/client/{clientId}/Contact")]
public class ContactController
{
    // this uses conventional route
    public ContactModel GetContactByID(string id)
    {
        ...
    }

    [Route("username/{userName}")]
    public ContactModel GetContactByUserName(string userName)
    {
        ...
    }
}
[RoutePrefix("api/client/{clientId}/Payment")]
public class PaymentController
{
    // this uses conventional route
    public PaymentModel Get(Guid id)
    {
        ...
    }

    [HttpGet, Route("sale/{id}")]
    public PaymentActivityModel Sale(Guid id)
    {
        ...
    }
}

您的控制器是System.We.Mvc控制器还是System.Web.Http.ApicController?