Asp.net mvc 4 了解路线,如何创建两个';相同';既可以获取又可以发布的路线?

Asp.net mvc 4 了解路线,如何创建两个';相同';既可以获取又可以发布的路线?,asp.net-mvc-4,asp.net-web-api,asp.net-mvc-routing,Asp.net Mvc 4,Asp.net Web Api,Asp.net Mvc Routing,以前,我有两个方法,一个用[WebGet]标记,另一个用[WebInvoke(Method=“POST”] 当我对指定的URL执行GET或POST时,它总是调用正确的方法 网址是: POST: fish-length GET: fish-length?start-date={startDate}&pondId={pondId} 现在我正在使用web api,我必须单独定义我的路由,如下所示: RouteTable.Routes.MapHttpRoute( nam

以前,我有两个方法,一个用
[WebGet]
标记,另一个用
[WebInvoke(Method=“POST”]

当我对指定的URL执行GET或POST时,它总是调用正确的方法

网址是:

POST: fish-length
GET: fish-length?start-date={startDate}&pondId={pondId}
现在我正在使用web api,我必须单独定义我的路由,如下所示:

    RouteTable.Routes.MapHttpRoute(
        name: "AddFishLength",
        routeTemplate: "fish-length",
        defaults: new
        {
            controller = "FishApi",
            action = "AddFishLength"
        });


    RouteTable.Routes.MapHttpRoute(
       name: "GetFishLength",
       routeTemplate: "fish-length?start-date={startDate}&pondId={pondId}",
       defaults: new
       {
           controller = "FishApi",
           action = "GetFishLength"
       });
但是,第二条路由不起作用,因为不允许在routeTemplate中使用

我可以将URL格式更改为
fish length/{startDate}/{pondId}
之类的格式,但这并不是公开服务的好方法


还有更好的方法吗?另外,因为我以前做过一篇文章并访问了相同的url,我需要确保我的路由方法仍然允许这样做。假设上述方法有效,我仍然不确定它将如何正确路由。

不,您不需要定义单独的路由。您只需要一个路由:

RouteTable.Routes.MapHttpRoute(
    name: "AddFishLength",
    routeTemplate: "fish-length",
    defaults: new
    {
        controller = "FishApi",
    }
);
然后遵循ApicController操作的RESTful命名约定:

public class FishApiController: ApiController
{
    // will be called for GET /fish-length
    public HttpResponseMessage Get()
    {
        // of course this action could take a view model
        // and of course that this view model properties
        // will automatically be bound from the query string parameters
    }

    // will be called for POST /fish-length
    public HttpResponseMessage Post()
    {
        // of course this action could take a view model
        // and of course that this view model properties
        // will automatically be bound from the POST body payload
    }
}
因此,假设您有一个视图模型:

public class FishViewModel
{
    public int PondId { get; set; }
    public DateTime StartDate { get; set; }
}
继续并修改控制器操作以采用此参数:

public class FishApiController: ApiController
{
    // will be called for GET /fish-length
    public HttpResponseMessage Get(FishViewModel model)
    {
    }

    // will be called for POST /fish-length
    public HttpResponseMessage Post(FishViewModel model)
    {
    }
}

显然,对于不同的操作,您可以有不同的视图模型。

您不能在路由模板中指定查询字符串参数,但只要您有一个与参数名称匹配的方法,WebApi就应该足够聪明,能够自己解决这个问题

public HttpResponseMessage Get(string id)
将对应于请求
{controller}?id=xxx

但是,如果没有看到实际对象,就很难判断您应该如何着手解决您的案例。例如,WebApi不喜欢Get请求中的复杂类型,而且它只以特定方式支持post数据中的url编码内容

至于区分Get和Post,这很简单——WebApi知道发送请求时使用的方法,然后它会查找以Get/Post开头或以HttpGet/Post属性修饰的方法名

我建议看一下以下文章——它们帮助我理解了它的工作原理:


我无法确定它是如何映射到操作的。假设我的方法被称为
GetFishLength
,那么它如何知道如何调用它,而不是
GetFishName
?您没有在路由信息中指定操作的名称。