Laden...

[gelöst] WCF: Hinzufügen einer Service Referenz: NullReferenceException??

Erstellt von Edward vor 12 Jahren Letzter Beitrag vor 12 Jahren 2.182 Views
E
Edward Themenstarter:in
118 Beiträge seit 2007
vor 12 Jahren
[gelöst] WCF: Hinzufügen einer Service Referenz: NullReferenceException??

Hallo zusammen,

ein Kollege von mir hat mit einem WCF Projekt begonnen ("Service A"), welches ich nun fortsetzen soll. In einem anderen WCF Projekt ("Service B") benötige ich eine Referenz auf "Service A".
Jedoch bekomme ich bei dem Versuch, eine Service Referenz hinzuzufügen, eine äußerst vielsagende Fehlermeldung: > Fehlermeldung:

Object reference not set to an instance of an object.

Klingt für mich nach einer klassischen NullReferenceException. Allerdings lässt sich "Service A" selbst problemlos starten.

Im Netz habe ich gelesen, dass beim Hinzufügen von Service Referenzen der Konstruktor nicht aufgerufen wird. Daher habe ich mir dieses Konstrukt eingebaut:


[OnDeserializing]
public void OnDeserializing(StreamingContext streamingContext)
{
    // Activate() ist eine Methode, die eigentlich im Konstruktor aufgerufen wird.
    this.Activate();
}

Allerdings hat das auch nichts gebracht.

Könnte eine etwaige Zirkelreferenz problematisch sein? "Service A" wird von "Service B" konsumiert. Wiederum wird "Service B" auch von "Service A" konsumiert. Könnte das ein Problem darstellen?

So langsam stehe ich echt auf dem Schlauch.

Hat jemand eine Idee?

Vielen Dank schon einmal im Voraus.

Edward

6.911 Beiträge seit 2009
vor 12 Jahren

Hallo Edward,

Im Netz habe ich gelesen, dass beim Hinzufügen von Service Referenzen der Konstruktor nicht aufgerufen wird

Beim Hinzufügen wird nur Code generiert und nichts davon ausgeführt. Zur Laufzeit wird selbstverständlich der Konstruktor aufgerufen, sonst würde das Objekt auch nie erstellt. Dein Hilfskonstrukt ist also nicht notwendig.

Aus den vorhanden Infos tippe ich auch auf die zirkuläre Referenz. Beim Hinzufügen kann diese nicht aufgelöst werden. Umgehe also diese Referenz (indem z.B. ein dritter Service als Vermittler eingeführt wird).

Edit: das jetzt durchgestrichene ist nicht immer gültig. Siehe WCF: Hinzufügen einer Service Referenz: NullReferenceException??

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

E
Edward Themenstarter:in
118 Beiträge seit 2007
vor 12 Jahren

Hallo Gü,

in unserer Solution gibt es schon den Fall, dass sich zwei Services gegenseitig referenzieren. Das schien ohne Probleme funktioniert zu haben.

Ich werde dennoch mal versuchen, die Referenz zu entfernen und schauen, ob es dann klappt.

Viele Grüße,
Edward

E
Edward Themenstarter:in
118 Beiträge seit 2007
vor 12 Jahren

Ich habe die Referenz(en) gelöscht... allerdings hat das am Problem leider nichts geändert. 🙁

849 Beiträge seit 2006
vor 12 Jahren

@gfoidl Edward hat recht wenn er sagt, der Ctor wird nicht (zumindest nicht beim deseralisieren) aufgerufen. Kannst Du hier nachlesen: DataContractSerializer

6.911 Beiträge seit 2009
vor 12 Jahren

Hallo unconnected,

danke für den Hinweis.

Allerdings gibts dabei ein interessantes Detail: ist die Klasse nicht mit dem [DataContract] versehen, so wird der Standard-Konstruktor aufgerufen, ist es jedoch als DataContract markiert dann nicht.
Ob Edward jetzt recht hat od. nicht kann somit nicht festgehalten werden, da wir nicht wissen ob die Klasse als DataContract dekoriert ist od. nicht 😉 Aber egal, denn obiges Detail wusste ich vorher ohnehin nicht.

Das Initialisieren eines Objekts ohne Aufruf eines Ctors geht übrigens mittels FormatterServices.GetUninitializedObject.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

E
Edward Themenstarter:in
118 Beiträge seit 2007
vor 12 Jahren

Hallo zusammen.

Sorry, wenn der Post etwas länger gedauert hat. Ich poste hier einfach mal die Web.config des Service, den ich referenzieren möchte (der Service, um den es sich handelt ist "RacingPostImport"):


<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding_IRacingPostImport" bypassProxyOnLocal="false" allowCookies="false"
          maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
     useDefaultWebProxy="true">
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
            maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
        </binding>
        <binding name="BasicHttpBinding_IUserService" maxBufferSize="2147483647"
          maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647">
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
            maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
        </binding>
        <binding name="BasicHttpBinding_SisImportService" closeTimeout="05:00:00"
     openTimeout="05:00:00" receiveTimeout="05:00:00" sendTimeout="05:00:00"
     allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
     maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"
     messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
     useDefaultWebProxy="true">
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
           maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
          <security mode="None">
            <transport clientCredentialType="None" proxyCredentialType="None"
             realm="" />
            <message clientCredentialType="UserName" algorithmSuite="Default" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="UserService-Adresse"
        binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IUserService"
        contract="UserService.IUserService" name="BasicHttpBinding_IUserService" />
      <endpoint address="SIS-Service-Adresse"
        binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_SisImportService"
        contract="SisImportServiceReference.ISisImportService" name="BasicHttpBinding_SisImportService" />
    </client>
    <services>
      <service behaviorConfiguration="BGT_RacingPostImport" name="BGT_RacingPostImport.RacingPostImport">
        <endpoint binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IRacingPostImport"
          name="IRacingPostImport" bindingName="IRacingPostImport" contract="BGT_RacingPostImport.IRacingPostImport" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="BGT_RacingPostImport">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
          <dataContractSerializer maxItemsInObjectGraph="2147483647" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

Auf der Clientseite gibt es ja noch keine Binding-Informationen für den RacingPost Service. Also spare ich mir die Web.config.

Das Interface von RacingPostImport:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Web;
using System.Text;
using BGT_RacingPostImport.Objects;

namespace BGT_RacingPostImport
{
    [ServiceContract]
    public interface IRacingPostImport
    {
        [OperationContract]
        void Activate();

        [OperationContract]
        void SubscribeEvents(List<EarlyBirdTO> topicData);

        [OperationContract]
        void UnsubscribeEvents(List<string> externalEventIds);
    }
}

Und die implementierende Klasse:


[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class RacingPostImport : IRacingPostImport
{
	// ......
}

Vielleicht hab ich schon Tomaten auf den Augen, aber mir fällt da nichts verdächtiges auf... 🙁
Seht ihr da irgendwas?

Viele Grüße,
Edward

6.911 Beiträge seit 2009
vor 12 Jahren

Hallo Edward,

ich sehe auch nichts verdächtiges, ob ebenfalls an den Tomaten liegt kann ich nicht sagen 😉

Aber probier mal nicht alle Services, sondern einen nach den anderen. Also ein Vorgehen wie in [Tutorial] Vertrackte Fehler durch Vergleich von echtem Projekt mit minimalem Testprojekt finden beschrieben.

BTW: Weißt du dass mit WCF 4 die Konfiguration erheblich vereinfacht wurde, zumindest für die Standardfälle? Siehe A Developer's Introduction to Windows Communication Foundation 4.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

849 Beiträge seit 2006
vor 12 Jahren

Hallo Edward, versuch mal folgendes:

Studio schliessen, per explorer in die sulution, die .suo Datei löschen.
Studio Starten -> Clean -> Rebuild und dann versuchen die Referenz hinzufügen.
Falls es immer noch passiert, im Feher Window auch die WARNUNGEN kontrollieren. manchmal geben diese mehr aufschluss als die Error Anzeigen.

G

Jan