【问题标题】:Message or a type that has MessageContractAttribute and other parameters of different types消息或具有 MessageContractAttribute 和其他不同类型参数的类型
【发布时间】:2011-06-30 05:04:23
【问题描述】:

我正在开发 WCF 服务,其中某些类具有 [MessageContract] 属性,而有些则没有。

当我尝试运行服务时,我收到以下错误消息:

无法加载操作“ProcessOperation”,因为它具有 System.ServiceModel.Channels.Message 类型的参数或返回类型,或者具有 MessageContractAttribute 和其他不同类型参数的类型。使用 System.ServiceModel.Channels.Message 或带有 MessageContractAttribute 的类型时,该方法不得使用任何其他类型的参数。

这是否意味着所有服务都必须有[MessageContract],尽管它们不相关?

【问题讨论】:

    标签: wcf


    【解决方案1】:

    不,这意味着您在方法上有多个参数,其中一些不是消息。尝试将接口发布到您的服务。

    blog post 解释:

    ...问题是消息契约不能和其他参数类型同时使用。在这种情况下,操作的返回值是一个字符串。返回值只是另一个输出参数,因此此操作将消息合同消息与原始参数类型混合。这会失败,因为消息协定让您可以控制 SOAP 消息的布局,从而阻止系统融合这些附加参数。

    重要提示:

    顺便说一句,当您尝试混合消息合同时收到的错误消息如下所示。

    【解决方案2】:

    这基本上意味着特定操作正在使用以下任意组合中的消息协定类型和原始类型的组合:

    MixType1: Contract type and primitive types as operation parameters
    MixType2: Contract type as a parameter and primitive type as return type
    MixType3: Primitive type as a parameter and Contract type as return type
    

    上面列出的任何情况都会产生错误。

    【讨论】:

      【解决方案3】:

      解决了!

      我无法返回字符串,我已将 Greeting 对象返回给客户端。

      using System;
      using System.ServiceModel;
      using System.Net.Security;
      
      namespace com.blogspot.jeanjmichel.model
      {
          [MessageContract]
          public class Greeting
          {
              private String userGreeting;
      
              private void SetGreeting()
              {
                  DateTime now = DateTime.Now;
      
                  if (now.Hour >= 7 && now.Hour <= 11)
                  {
                      this.userGreeting = "Good morning";
                  }
                  else if (now.Hour >= 12 && now.Hour <= 17)
                  {
                      if (now.Hour == 12 || now.Hour == 13)
                      {
                          this.userGreeting = "Good afternoon, it's lunch time!";
                      }
                      else
                      {
                          this.userGreeting = "Good afternoon";
                      }
                  }
                  else if (now.Hour >= 18 && now.Hour <= 20)
                  {
                      this.userGreeting = "Good evening";
                  }
                  else
                  {
                      this.userGreeting = "Good night";
                  }
              }
      
              [MessageBodyMember(Order = 1, ProtectionLevel = ProtectionLevel.EncryptAndSign)]
              public String UserGreeting
              {
                  get { return this.userGreeting; }
              }
      
              public Greeting()
              {
                  this.SetGreeting();
              }
          }
      }
      
      using System;
      using System.ServiceModel;
      using com.blogspot.jeanjmichel.model;
      
      namespace com.blogspot.jeanjmichel.services.contract
      {
          [ServiceContract(Namespace = "http://jeanjmichel.blogspot.com/services/v0.0.1")]
          public interface IGetGreeting
          {
              [OperationContract]
              Greeting GetGreeting(Credential credential);
          }
      }
      
      using System;
      using System.ServiceModel;
      using com.blogspot.jeanjmichel.services.contract;
      using com.blogspot.jeanjmichel.model;
      
      namespace com.blogspot.jeanjmichel.services
      {
          [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall,
                           Namespace = "http://jeanjmichel.blogspot.com/services/v0.0.1")]
          public class GetGreetingService: IGetGreeting
          {
              public Greeting GetGreeting(Credential credential)
              {
                  if (String.IsNullOrEmpty(credential.Token))
                  {
                      throw new FaultException("Inform the security phrase, and try again.");
                  }
                  else
                  {
                      if (credential.Token.Equals("mySeCuriTyP@ss"))
                      {
                          Greeting g = new Greeting();
                          return g;
                      }
                      else
                      {
                          throw new FaultException("Wrong password.");
                      }
                  }
              }
          }
      }
      

      【讨论】:

        【解决方案4】:

        当你使用 Message 对象作为参数时,该方法应该返回 void

        【讨论】:

          【解决方案5】:

          如果您遇到混合类型的原始类型(例如字符串)和 MessageContract 作为另一种类型的问题,即一个类作为返回和一个字符串参数,我解决此问题的一种方法是从 MessageContract 切换到 DataContract。

          解决此问题的另一种方法是创建一个类来将原始类型作为属性保存,这样您的返回值和参数都可以实现 MessageContract。

          【讨论】:

            【解决方案6】:

            我在代码中维护 API 时遇到了这个错误。 API 突然开始为所有端点返回此错误。 我已经升级了 Ninject 的初始化方法,以摆脱它说已经过时的方法。

            Obsolete method: NinjectWebServiceHostFactory (no error) 
            New method:      NinjectServiceHostFactory    (returns error)
            

            当我恢复更改时,错误消失了。

            【讨论】:

              猜你喜欢
              • 2012-06-03
              • 2014-07-31
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2020-01-23
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多