【问题标题】:How can i have two methods with same name in WCF? [duplicate]如何在 WCF 中有两个同名的方法? [复制]
【发布时间】:2013-01-23 05:16:00
【问题描述】:

可能重复:
why you cant overload a method in WCF?

我正在开发一个使用 WCF 服务的项目。我的问题是,在 WCF 服务中,我有一个名为 Display() 的方法,由我的 client1 使用。

现在我想添加另一个具有相同名称但具有一个参数的方法,即。 Display(string name),这样新的clinet2可以使用新的方法,旧的client1可以使用旧的方法。我怎样才能做到这一点?这是我写的代码。

namespace ContractVersioningService
{
  [ServiceContract]
  public interface IService1 
  {
    [OperationContract]
    string Display();

    [OperationContract]
    string GoodNight();
  }     
}

namespace ContractVersioningService
{
   public class Service1 : IService1
   {
     public string Display()
     {
        return "Good Morning";          
     }

     public string GoodNight()
     {
        return "Good Night";
     }
   }
}    

namespace ContractVersioningService
{
  [ServiceContract(Namespace = "ContractVersioningService/01", Name =      "ServiceVersioning")]
  public interface IService2 : IService1
  {
     [OperationContract]
     string Disp(string greet);
  }
}

namespace ContractVersioningService
{
 
   public class Service2 : Service1, IService2
   {
      public string Display(string name)
      {
         return name;
      }

      public string Disp(string s)
      {
         return s;
      }
   }
}

【问题讨论】:

  • @Cristian 根据您的链接,我们需要为操作合同提供“名称”属性。但问题是客户端可以使用属性“名称”值访问这两种方法。我希望客户可以通过原始名称访问这些方法。
  • @Sagar 客户端将看到方法的名称,而不是您在 C# 接口中命名的名称,而是 OperationContract.Name 值中给出的名称。这才是真正的重点,该方法将具有相同的名称。这是唯一可行的方法。您根本不能拥有多个具有完全相同名称的服务操作 - WSDL 不执行重载解析。因此,这是链接问题的副本。
  • @Christian.K 但我希望该客户只看到一个通用名称。我怎样才能实现它?
  • WCF 不支持方法重载,例如你不能有两个同名的方法,只是有不同的参数列表。服务描述中的名称必须是唯一的。没有办法绕过这个要求。

标签: c# .net wcf


【解决方案1】:
    Why WCF doesnot support method overloading directly ?
  • 因为 WSDL 不支持方法重载(不是 OOP)。 WCF 生成 WSDL,它指定服务的位置以及服务公开的操作或方法。

    WCF 使用 Document/Literal WSDL 样式:微软提出了这个标准,soap body 元素将包含 web 方法名称。

  • 默认情况下,所有 WCF 服务都符合文档文字标准,soap 主体应包含方法名称。

    唯一的方法是使用名称属性。例如,

        [OperationContract(Name="Integers")]
        int Display(int a,int b)
        [OperationContract(Name="Doubles")]
        double Display(double a,double b)
    

编译器将生成以下内容,这对于 wsdl 定位是有意义的

     [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
    [System.ServiceModel.ServiceContractAttribute(ConfigurationName=
    "ServiceRef.IService1")]
  public interface IService1
   {
       [System.ServiceModel.OperationContractAttribute(
       Action="http://tempuri.org/Service1/AddNumber",
       ReplyAction="http://tempuri.org/IHelloWorld/IntegersResponse")]                   
       int Display(int a,int b)

       [System.ServiceModel.OperationContractAttribute(
       Action="http://tempuri.org/IHelloWorld/ConcatenateStrings",
       ReplyAction="http://tempuri.org/Service1/DoublesResponse")]
       double Display(double a,double b)
  }

【讨论】:

  • 这里调用方法将使用“Ingeters()”和“Doubles()”。我想使用原始名称(即显示)的用户方法
  • 在没有名称属性的单个服务合同中方法重载是不可能的。但是您可以将其公开为两个不同的合约。
  • 可以通过使用名称属性按原始(显示)名称调用。我认为您仅在服务器端更新名称属性。它必须在两边。
  • 是否可以从服务器端更改客户端的reference.cs文件?
  • 否。如何创建代理 (serviceutil/Channelfactory)?你只能在客户端获取别名,如果你只在服务器端实现 name 属性..所以在双方更新,你得到原始名称..这可能有助于codeguru.com/csharp/.net/net_wcf/article.php/c14773/…
【解决方案2】:

好的,我要回答这个问题,因为现在 cmets 变得过度了。

你基本上有两种选择:

  • 使用单个接口(请注意,接口继承,就像您在问题中建议的那样,在技术上算作 one 接口),但是您必须给每个服务操作一个不同的名称。您可以通过将 C# 方法命名为不同的方法,或者通过应用 [OperationContract(Name = "distinctname")] 属性来做到这一点。

  • 使用两个独立的接口,它们之间没有任何继承关系,将每个接口发布在不同的端点上。然后,您可以在每个中都有一个服务操作,具有相同的名称,但具有不同的参数。当然,如果您愿意/需要,您仍然可以使用一个实现类来实现这两个接口。

【讨论】:

  • 但我必须从两个接口显式实现所有方法。
  • 是的,但这是个问题吗?无论如何你都必须这样做。
  • 是的......它会不必要地增加代码。
  • 然后委托。一个函数(旧的)可以调用新的,为新的/额外的参数提供一个合理的默认值。除此之外,恐怕我在这里看不到您的问题。它看起来像一个常规/通常的事情 - 有或没有 WCF。您可能应该考虑发布一个新问题或更新当前问题以提供更多详细信息。
猜你喜欢
  • 2021-11-28
  • 1970-01-01
  • 2018-06-13
  • 2011-05-21
  • 1970-01-01
  • 1970-01-01
  • 2020-07-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多