0

以前,我有两种方法,一种用标记,另[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 中使用 a。

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

有一个更好的方法吗?另外因为我之前对同一个 url 进行了 POST 和 GET,所以我需要确保我的路由方法仍然允许这样做。假设上述方法有效,我仍然不确定它如何正确路由。

4

2 回答 2

0

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

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

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

至于区分 Get 和 Post 非常简单——WebApi 知道您在发送请求时使用了哪种方法,然后它会查找以 Get/Post 开头或以 HttpGet/Post 属性装饰的方法名称。

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

http://www.west-wind.com/weblog/posts/2012/Aug/16/Mapping-UrlEncoded-POST-Values-in-ASPNET-Web-API

http://blogs.msdn.com/b/jmstall/archive/2012/04/16/how-webapi-does-parameter-binding.aspx

于 2013-01-10T20:49:25.303 回答
0

不,您不需要定义单独的路线。您只需要一条路线:

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

然后遵循 ApiController 操作的 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)
    {
    }
}

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

于 2013-01-02T11:54:37.807 回答