【问题标题】:C# Web Api: Need to have different handlers for POST method based on input suppliedC# Web Api:需要根据提供的输入为 POST 方法提供不同的处理程序
【发布时间】:2013-02-23 07:00:34
【问题描述】:

我有以下 REST api 实现:

using System.Web.Http;  
public class DeploymentsController : ApiController
{
    public HttpResponseMessage Post(
        string subscriptionId,
        string serviceName,
        string deploymentSlot,
        CreateDeploymentInput input)
    {
    . . . 
    }

    public HttpResponseMessage Post(
        string subscriptionId,
        string serviceName,
        string deploymentSlot,
        UpdateDeploymentStatusInput input)
    {
    . . . 
    }                
 }

这是路由:

        config.Routes.MapHttpRoute(
            name: "DeploymentSlots",
            routeTemplate: "{subscriptionId}/services/hostedservices/{serviceName}/deploymentslots/{deploymentSlot}",
            defaults: new
            {
                controller = "deployments",
            });

        config.Routes.MapHttpRoute(
            name: "Deployments",
            routeTemplate: "{subscriptionId}/services/hostedservices/{serviceName}/deployments/{deploymentName}",
            defaults: new
            {
                controller = "deployments"
            });

我想为新的“升级”操作添加处理,如下所示:

POST /1d42d489-7a4f-4561-91a3-c2033c31f8c6/services/hostedservices/Mytalk123490193975/deployments/Mytalk12349019/?comp=upgrade HTTP/1.1
Content-Type: application/xml; charset=utf-8
x-ms-version: 2012-08-01
Host: localhost:33344
Content-Length: 340
Expect: 100-continue
Accept-Encoding: gzip, deflate

HTTP/1.1 100 Continue

<UpgradeDeployment xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="ht    tp://www.w3.org/2001/XMLSchema-instance"><Mode>auto</Mode><PackageUrl>http://

talkserviceshared.blob.core.windows.net/mycontainer/PackageTXlCaXp0YWxrMTIzNDkwMTkzOTc1

所以我在 ApiController 中添加了一个处理程序:

    public HttpResponseMessage Post(
        string subscriptionId,
        string serviceName,
        string deploymentSlot,
        UpgradeDeploymentInput input)
    {
    . . . 
    }      

但是当我使用客户端调用它时,它会抱怨“找到与请求匹配的多个操作”
公共 HttpResponseMessage 帖子( 字符串订阅 ID, 字符串服务名称, 字符串部署槽, UpdateDeploymentStatusInput 输入) 和
公共 HttpResponseMessage 帖子( 字符串订阅 ID, 字符串服务名称, 字符串部署槽, UpdateDeploymentStatusInput 输入)

然后我尝试将这些方法合二为一:

public HttpResponseMessage Post(
        string subscriptionId,
        string serviceName,
        string deploymentSlot,
        object input)
{
}

并编写了检查运行时类型并采取不同操作的代码。但是这次调用失败了 System.InvalidOperationException

在我开枪之前请帮忙。我没有时间从头开始学习这些东西,我时间紧迫。

【问题讨论】:

    标签: asp.net-web-api


    【解决方案1】:

    我一直跟着你:

    “所以我在 ApiController 中添加了一个处理程序:”

    如果您确实添加了带有参数 *Upgrade*DeploymentInput 输入的第三个 POST 方法,为什么编译器会抱怨有两个带有参数 *Update 的 POST 方法*DeploymentStatusInput 输入。

    可能是您只是复制粘贴方法忘记将输入从“更新”更改为“升级”?

    医生

    【讨论】:

      【解决方案2】:

      从您的帖子中,我了解到您假设配置中的路线 #2 将涵盖 POST 方法 #2 和 #3。

      我可能是错的,但我怀疑问题是如果 url 相同并且不同的参数来自请求正文,WebApi 没有任何方法来区分方法 - 参数的类型不会选择路线时进行检查,因此对于 WebApi 两种方法看起来相同。这就是歧义的来源。

      我无法就解决方法提出建议,因为您没有指定 InvalidOperation 的含义 - 可能是您在某处错过了强制转换或在未检查对象类型的情况下尝试强制转换?

      我认为解决它的一种方法是使用操作:

      config.Routes.MapHttpRoute(
                  name: "Deployments",
                  routeTemplate: "{subscriptionId}/services/hostedservices/{serviceName}/deployments/{action}/{deploymentName}",
                  defaults: new
                  {
                      controller = "deployments"
                  });
      

      然后你需要用一个属性来装饰方法,例如[ActionName("upgrade")] 并通过不同的网址访问它们

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-02-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-03
        • 1970-01-01
        相关资源
        最近更新 更多