为什么Post调用路由到具有不同签名的Post方法?

时间:2013-12-20 00:28:53

标签: asp.net-mvc asp.net-web-api controller repository asp.net-web-api-routing

我的Web API服务器中有两个名为Post *的方法:

控制器

public void PostNoBills(int accountid, string name)
{
    duckbillsRepository.Post(accountid, name);
}

public void Post(NoBills noBills)
{
    duckbillsRepository.Post(noBills); 
}

存储库:

public void PostNoBills(int accountid, string name)
{
    int maxId = noBills.Max(d => d.Id);
    NoBills duckbill = new NoBills();
    duckbill.Id = maxId + 1;
    duckbill.AccountId = accountid;
    duckbill.Name = name;
    NoBills.Add(duckbill);
}

public void Post(NoBills noBills)
{
    int maxId = NoBills.Max(d => d.Id);
    NoBills.Id = maxId + 1;
    NoBills.Add(noBills);
}

所以当我从客户端调用Post方法时,传递一个int和一个字符串:

string uri = String.Format("http://platypi:28642/api/NoBills/{0}/{1}", onAccountOfWally, moniker);
var request = System.Net.WebRequest.Create(uri);
request.Method = "POST";
string postData = String.Format("{0}/{1}", onAccountOfWally, moniker);
byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(postData);
request.ContentType = "application/json";
request.ContentLength = byteArray.Length;
using (var requestStream = request.GetRequestStream())
{
    requestStream.Write(byteArray, 0, byteArray.Length);
}

using (var response = request.GetResponse())

...我希望带有“int accountid,string name”参数的方法是被调用的方法,但它不是 - 另一个(接受“NoBills noBills”作为其参数的那个)是。为什么呢?

(顺便说一句,我完全不确定上面的客户端代码是“正确的”)

更新

默认Kian Challa的邀请/要求,这里是WebApiConfig:

public static class WebApiConfig {     public static void Register(HttpConfiguration config)     {         // Web API配置和服务

    // Web API routes
    config.MapHttpAttributeRoutes();

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

    config.Routes.MapHttpRoute(
        name: "DefaultApiWithParameters",
        routeTemplate: "api/{controller}/{ID}/{CountToFetch}"
        //defaults: new { ID = RouteParameter.Optional, CountToFetch = RouteParameter.Optional }
    );

    config.Routes.MapHttpRoute(
        name: "DefaultApiWith3Parameters",
        routeTemplate: "api/{controller}/{ID}/{packSize}/{CountToFetch}"
        //defaults: new { ID = RouteParameter.Optional, packSize = RouteParameter.Optional, CountToFetch = RouteParameter.Optional }
    );

作为奖励,这里是RouteConfig.cs:

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}   

......以及可能相关的Global.asax.cs:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    GlobalConfiguration.Configure(WebApiConfig.Register);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
}

更新2

回复Kian Challa的评论,其中包含“ on action public void PostNoBills(int accountid,string name)

好的,那就是(如果你在谈论控制器代码):

public void PostNoBills(int accountid, string name)
{
    duckbillsRepository.Post(accountid, name);
}

如何更改:

[Route("api/nobills/{accountid}/{name}")]

?你暗示我不需要向WebApiConfig添加任何内容(“... 而不是在WebApiConfig.cs中创建新路由 ...”)所以......我需要添加什么,以及在哪里我需要添加吗?

1 个答案:

答案 0 :(得分:1)

您的操作的FromUri参数可以绑定到路由数据或查询字符串值,在这种情况下名称为accountidname ...因为您的路由都没有这些路由变量名称Web API无法提供任何名称为accountidname的路由数据,因此您的预期操作不会被调用...来解决此问题,而不是在WebApiConfig.cs中创建新路由,为什么不使用属性路由,因为您似乎已经调用了...示例:[Route("api/nobills/{accountid}/{name}")]