2009-11-12 15 views
8

Ich habe die letzten zwei Tage mit WCF gearbeitet und es lief sehr gut mit dem Server und dem Client auf meinem Entwicklungscomputer. Jetzt, da ich versuche, einige verteilte Tests mit dem Client auf einem anderen Rechner im Netzwerk durchzuführen, habe ich Probleme bekommen. Momentan befindet sich der Fehler Ich erhalte ist:So deaktivieren Sie programmgesteuert die Sicherheit in WCF

Die Meldung mit Aktion ‚http://tempuri.org/IWindowUpdateContract/UpdateWindowFrames‘ kann nicht an den Empfänger verarbeitet werden, aufgrund einer Contract Mismatch am EndpointDispatcher. Dies kann entweder auf eine Vertragsfehlanpassung (nicht übereinstimmende Aktionen zwischen Sender und Empfänger) oder auf eine Bindungs-/Sicherheitskonflikt zwischen dem Absender und dem Empfänger zurückzuführen sein. Überprüfen Sie, ob Absender und Empfänger den gleichen Vertrag und die gleiche Bindung haben (einschließlich Sicherheitsanforderungen, z. B. Nachricht, Transport, Keine).

Da dies bereits eine massive Lernerfahrung (ich habe keine Remote getan, RPC, et al vor) ich das Lerninstrument weiterentwickeln will und Sicherheit wieder besuchen, wenn ich fertig bin (ich habe nicht die Absicht, alles zu bauen, das ohne die besten Sicherheitsvorkehrungen genutzt wird.

Hinweise:

  • Ich habe keine Konfigurationsdatei Setup für WCF haben - ich programmatisch alles tun.
  • Mein Netzwerk ist nicht Teil einer Domäne, daher funktionierten die Standardsicherheitseinstellungen für mich nicht (mit net.tcp).
  • Ich benutze '. Net 3.5'.

Mein Server wird wie folgt erstellt:

var svh = new ServiceHost(_serviceImplementation); 

    var binding = new NetTcpBinding(); 

    binding.ReaderQuotas.MaxArrayLength = 2000000; 
    binding.Security.Mode = SecurityMode.None; 
    binding.Security.Transport.ClientCredentialType = TcpClientCredentialType.None; 
    binding.Security.Transport.ProtectionLevel = ProtectionLevel.None; 
    binding.Security.Message.ClientCredentialType = MessageCredentialType.None; 

    svh.AddServiceEndpoint(_serviceInterface, binding, string.Format("net.tcp://{0}:{1}", _endPoint.Address, _endPoint.Port)); 

    _stopFlag = new AutoResetEvent(false); 

    svh.Open(); 

    _stopFlag.WaitOne(); 

Und mein Mandant wird wie folgt erstellt:

var binding = new NetTcpBinding(); 

    binding.ReaderQuotas.MaxArrayLength = 2000000; 
    binding.Security.Mode = SecurityMode.None; 
    binding.Security.Transport.ClientCredentialType = TcpClientCredentialType.None; 
    binding.Security.Transport.ProtectionLevel = ProtectionLevel.None; 
    binding.Security.Message.ClientCredentialType = MessageCredentialType.None; 

    var scf = new ChannelFactory<IUserInputContract>(binding, "net.tcp://192.168.0.42:8001"); 
    _uiUpdateServer = scf.CreateChannel(); 

Und mein Vertrag (die nur in einer Klassenbibliothek, die als hinzugefügt werden eine Referenz sowohl zum Client als auch zum Server) lautet:

I f Aal, dass die Bindung und die Vertragseinrichtung, die ich getan habe, sie identisch machen sollte und ich dieses Problem nicht haben sollte (und Sicherheit sollte ausgeschaltet werden). Ich weiß einfach nicht wohin ich jetzt gehen soll.

Antwort

10

Ich stimme Ihnen zu - es scheint, dass die Sicherheitseinstellungen für Server und Client identisch sind.

Ein Hinweis auf der Seite: wenn Sie das tun:

binding.Security.Mode = SecurityMode.None; 

Ich glaube nicht, dass Sie mehr Einstellung auf dem „binding.Security“ Objekt angeben müssen oder unten - diese zusätzlichen Linien danach sind nicht benötigt.

Was mir auffiel ist Ihr Servicevertrag:

[ServiceContract(ProtectionLevel = ProtectionLevel.None)] 
public interface IWindowUpdateContract 
{ 
    [OperationContract] 
    void UpdateWindowFrames(WindowFrame frame); 
    [OperationContract] 
    void WindowHasClosed(IntPtr hwnd); 
} 

Diese Vorgänge etwas nicht zurück - das ist ungewöhnlich. Das Standardverhalten für einen WCF-Dienst lautet Request/Response - Sie senden eine Anforderung und erhalten eine Antwort zurück.

Entweder sie etwas zurückgeben (ein Status oder so; wie eine Zeichenfolge, ein int), oder dann müssen Sie sie als "unidirektionale" Anrufe markieren, so dass WCF weiß nichts zu erwarten zurück:

[ServiceContract(ProtectionLevel = ProtectionLevel.None)] 
public interface IWindowUpdateContract 
{ 
    [OperationContract(IsOneWay=true)] 
    void UpdateWindowFrames(WindowFrame frame); 
    [OperationContract(IsOneWay=true)] 
    void WindowHasClosed(IntPtr hwnd); 
} 

Marc

+0

ich das Hinzufügen versucht, das Attribut ‚IsOneWay‘ und I reduziert auch die Bindung Code an die eine Zeile, die Sie erwähnt und die Dinge funktionieren jetzt. Vielen Dank für Ihre Hilfe! Ich finde es etwas seltsam, dass eines dieser beiden Dinge diesen spezifischen Fehler verursacht haben könnte ... aber ich habe nichts anderes geändert und jetzt funktioniert es! – InvertedAcceleration

+0

@curiouscoder: Ich würde glauben, dass es die IsOneWay = true Einstellungen waren, die den Unterschied ausmachten. –

Verwandte Themen