【问题标题】:Getting NullReferenceException when calling WCF service from client从客户端调用 WCF 服务时出现 NullReferenceException
【发布时间】:2009-07-07 23:27:30
【问题描述】:

我尝试调用的方法具有以下签名:

Results GetPerformanceData(MyEntity entity, bool recurse);

我在方法的开头设置了一个断点,但是在代码执行到达断点之前就抛出了异常。

跟踪 WCF 服务可以得到以下信息:

System.NullReferenceException,mscorlib,版本=2.0.0.0,文化=中性,PublicKeyToken=b77a5c561934e089 你调用的对象是空的。 堆栈跟踪: 在 System.Runtime.Serialization.CodeGenerator.VerifyParameterCount(MethodInfo 方法信息,Int32 预期计数) 在 System.Runtime.Serialization.CodeGenerator.Call(对象 thisObj,MethodInfo methodInfo,对象 param1) 在...

如何确定空变量是什么?我将调试器设置为中断所有异常,但对于这个特定问题并没有中断。看起来我试图调用的方法的“实体”参数无法正确反序列化。

示例调用调用

var 结果 = 客户。 GetPerformanceData(entity, true);

WCF 服务配置

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.diagnostics>
    <sources>
      <source name="System.ServiceModel"
              switchValue="All"
              propagateActivity="true">
        <listeners>
          <add name="traceListener"
              type="System.Diagnostics.XmlWriterTraceListener"
              initializeData= "trace.svclog" />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="basicHttpBindingSettings" closeTimeout="00:01:00"
          openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
          allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
          maxBufferSize="5242880" maxBufferPoolSize="52428800" maxReceivedMessageSize="5242880"
          messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
          useDefaultWebProxy="true">
          <readerQuotas maxDepth="64" maxStringContentLength="8192" maxArrayLength="16384"
            maxBytesPerRead="4096" maxNameTableCharCount="16384" />
        </binding>
      </basicHttpBinding>
    </bindings>
    <services>
      <service name="Company.Service.Engine"
               behaviorConfiguration="ServiceBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8000/Engine"/>
          </baseAddresses>
        </host>
        <endpoint address=""
                  binding="basicHttpBinding"
                  bindingConfiguration="basicHttpBindingSettings"
                  contract="Company.Service.IEngine"/>

        <endpoint address="mex"
                  binding="mexHttpBinding"
                  contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="True"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

【问题讨论】:

  • 如果您能提供调用代码和WCF配置会有所帮助,

标签: wcf


【解决方案1】:

事实证明,我有一些标记为 [DataMember] 的属性有 getter 但没有 setter。

通常,通过查看服务上的跟踪文件或在客户端项目上添加服务引用时的弹出窗口中,我会得到一个描述性错误。这次我没有。

我必须搜索 [DataMember] 的所有实例并一一查看它们以找到缺少 setter 的属性。

【讨论】:

  • 天哪,谢谢你我花了太多时间试图解决这个问题
【解决方案2】:

我知道这个问题很老,但如果其他人偶然发现了这个问题,这可能有助于解决问题

我刚刚遇到了这个问题,并发现了一些关于 [DataMember] 注释的新内容,我有 2 个类,其中一个类引用了另一个类(我们称它们为 A 类和 B 类),其中一些属性和class B 中的字段在 class A 中被引用。

这是我所拥有的一个小例子

[数据合约] 公开课A { [数据成员] 公共 B 类 {get;set;} [数据成员] 公共整数 { 得到 {return classb.Number;} 设置 {classb.Number = value;} } } [数据合约] 公共B类 { [数据成员] 公共整数 { 得到; 放; } }

问题是空引用存在,因为 datamember 意味着它本身拥有一个值,其中 class A 只拥有对 class B 中数字的引用,你现在要做的就是只在其中一个数字上放置一个 Datamember .

【讨论】:

    【解决方案3】:

    当我将传递给数据协定的具体类型更改为缺少[DataContract] 属性的类型时,我还从System.Runtime.Serialization.CodeGenerator.VerifyParameterCount 获得了NullReferenceException。

    [DataContract, KnownType(typeof(NewEngine))]
    public class Car
    {
        [DataMember]
        public IEngine Engine { get; set; }
    }
    
    [DataContract] // DON'T FORGET THIS
    public class NewEngine : IEngine { ... }
    

    【讨论】:

      【解决方案4】:

      我发现了导致该错误的另一个原因:将相同的 DataMember.Name 分配给两个属性导致了我的错误:

      [DataContract]
      public class Car
      {
          [DataMember(Name = "Type")]
          public string EngineType { get; set; }
      
          [DataMember(Name = "Type")]
          public string TyresType { get; set; }
      }
      

      我知道这是一个很大的错误,但是如果属性很多......它可能会发生:-)

      【讨论】:

        【解决方案5】:

        这里可能有几个问题。确保您的数据合同具有适当的属性。确保您的服务引用是最新的,如果没有通过引用程序集来重用您的数据合同,请确保对象的生成是正确的(生成的代码通常位于名为 Reference.cs 的文件中)。还可以尝试在每个服务操作周围放置一个 try catch 块,并将这些异常包装在 FaultExceptions 中。这可以帮助您找到更好的答案。

        try
        {
         ...
        }
        catch (Exception ex)
        {
         // The generic argument might be unnecessary
         throw new FaultException<Exception>(ex);
        }
        

        【讨论】:

        • FaultException 有什么帮助?这就是 WCF 正常做的事情。
        • WCF 生成的客户端代码唯一冒泡的是上面提到的 NullReferenceException,因为我在服务的 app.config 中将 includeExceptionDetailInFaults 设置为 true。
        • 通过将 try catch 块放在服务方法周围,您可能会捕获可能触发其他 FaultException 的异常。 WCF是一种奇怪的动物,我以前也遇到过这种情况。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多