Asp.net mvc 4 具有相同签名的web api mvc4的自定义方法

Asp.net mvc 4 具有相同签名的web api mvc4的自定义方法,asp.net-mvc-4,Asp.net Mvc 4,我正在使用ASP.NET MVC4的Web Api。对于自定义Get方法,我遇到了问题,我将在下面解释 我的WebApiConfig.cs文件是 public static void Register(HttpConfiguration config) { //1 config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{c

我正在使用ASP.NET MVC4的Web Api。对于自定义Get方法,我遇到了问题,我将在下面解释

我的WebApiConfig.cs文件是

   public static void Register(HttpConfiguration config)
    {
        //1
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        //2
        config.Routes.MapHttpRoute(
        name: "FindDetailsByAge",
        routeTemplate: "api/{controller}/{action}/{age}",
        defaults: new { age = RouteParameter.Optional },
        constraints: new { age = @"^[0-9]+$" }
        );


        //3
        config.Routes.MapHttpRoute(
            name: "FindDetailsByName",
            routeTemplate: "api/{controller}/{action}/{name}",
            defaults: new { name = RouteParameter.Optional },
            constraints: new { name = @"^[a-z]+$" }
         );

        //4
        config.Routes.MapHttpRoute(
            name: "FindDetailsByCountry",
            routeTemplate: "api/{controller}/{action}/{country}",
            defaults: new { country = RouteParameter.Optional },
            constraints: new { country = @"^[a-z]+$" }
         );


        // for json
        var appXmlType = config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml");
        config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);

    }
这是我的控制器文件

public class ContactController : ApiController
{
    private ContactRepository contactRepository;

    public ContactController()
    {
        this.contactRepository = new ContactRepository();

    }

    public IEnumerable<Contact> GetAllContact()
    {
        return contactRepository.GetAll();
    }

    public Contact GetNameByAge(int id)
    {
        Contact contact = contactRepository.GetNameByAge(id);
        if (contact == null)
        {
            throw new HttpResponseException(HttpStatusCode.NotFound);
        }
        return contact;
    }


    [HttpGet]
    public Contact FindDetailsByAge(int age)
    {
        Contact contact = contactRepository.FindDetailsByAge(age);
        if (contact == null)
        {
            throw new HttpResponseException(HttpStatusCode.NotFound);
        }
        return contact;
    }


    [HttpGet]
    public IEnumerable<Contact> FindDetailsByName(string name)
    {
        IEnumerable<Contact> lstContactName = contactRepository.FindDetailsByName(name);
        if (lstContactName == null)
        {
            throw new HttpResponseException(HttpStatusCode.NotFound);
        }
        return lstContactName;
    }


    [HttpGet]
    public IEnumerable<Contact> FindDetailsByCountry(string country)
    {
        IEnumerable<Contact> lstContactCountry = contactRepository.FindDetailsByCountry(country);
        if (lstContactCountry == null)
        {
            throw new HttpResponseException(HttpStatusCode.NotFound);
        }
        return lstContactCountry;
    }


}
案例-4

输入
。/api/contact/finddeailsbycountry/india

输出

{“Message”:“未找到与请求URI匹配的HTTP资源 “../api/contact/FindDetailsByCountry/india.”,“MessageDetail”:“否” 在匹配的控制器“联系人”上找到了操作 请求。”}

从上面的输出可以看出,对于案例4,它给出了错误

正在执行FindDetailsByName 未执行FindDetailsByCountry

现在,如果我将MapHttpRoute(第4种情况)放在MapHttpRoute(第3种情况)之前,即交换第3和第4个位置,WebApiConfig.cs看起来像

。。。

然后输出将是

输入

../api/contact/Finddeilsby国家/印度

输出

[{“姓名”:“阿肖克”,“年龄”:60,“国家”:“印度”},{“姓名”:“纳尔吉斯”,“年龄”:30,“国家”:“印度”}]

输入

../api/contact/finddeilsbyname/nargis

输出

{“Message”:“未找到与请求URI匹配的HTTP资源 “../api/contact/finddeilsbyname/nargis.”,“MessageDetail”:“无操作” 在与请求匹配的控制器“联系人”上找到。“}

现在 未执行FindDetailsByName 正在执行FindDetailsByCountry

从上面的代码可以清楚地看出,在3和4之间路由的配置文件中,正在执行哪个先到

我有

方法-1

public Contact  FindDetailsByName(string name)
方法-2

public Contact FindDetailsByCountry(string country)
您可以看到方法FindDetailsByNameFindDetailsByCountry都只接受字符串参数并返回Contact对象

现在我的问题是-我将如何执行这两种方法?MapHttpRoute将是什么?MapHttpRoute的订单是什么? 过去两天我一直在寻找解决方案,但没有得到任何结果。我知道我已经给出了很长的代码描述,请耐心阅读


谢谢。

您应该只需要有一个覆盖这两者的映射。
api/{controller}/{action}/
涵盖了“api/contact/finddeilsbyname/”和“api/contact/finddeilsbycountry”

在当前设置中,国家/地区将首先生效,而名称将被跳过,因为它们具有相同的签名(控制器/操作/参数)

更改方法以接受通用变量名,例如
public IEnumerable FindDetailsByName(字符串搜索值)
,并对以下两种方法使用单一路由:

config.Routes.MapHttpRoute(
        name: "FindDetailsBySearchValue",
        routeTemplate: "api/{controller}/{action}/{searchValue}",
        defaults: new { searchValue = RouteParameter.Optional },
        constraints: new { searchValue = @"^[a-z]+$" }
     );
或者不要在操作中使用模板,如以下回答所示:

public Contact FindDetailsByCountry(string country)
config.Routes.MapHttpRoute(
        name: "FindDetailsBySearchValue",
        routeTemplate: "api/{controller}/{action}/{searchValue}",
        defaults: new { searchValue = RouteParameter.Optional },
        constraints: new { searchValue = @"^[a-z]+$" }
     );
config.Routes.MapHttpRoute(
        name: "FindDetailsByCountry",
        routeTemplate: "api/{controller}/FindDetailsByCountry/{country}",
        defaults: new { country = RouteParameter.Optional },
        constraints: new { country = @"^[a-z]+$" }
     );


    //3
    config.Routes.MapHttpRoute(
        name: "FindDetailsByName",
        routeTemplate: "api/{controller}/FindDetailsByName/{name}",
        defaults: new { name = RouteParameter.Optional },
        constraints: new { name = @"^[a-z]+$" }
     );