EDIT2: mein Kollege hat eine brauchbare Lösung gefunden: Web Service Enhancements von Microsoft. Es benötigt IIS und es wurde mit der Einführung von WCF veraltet, aber funktioniert gut mit einfachem .Net Framework 2.0 und sollte mit Mono XSP deployable sein.
EDIT: Lösung unten ist sinnlos, weil .NET 2.0 Web-Services setzt unter Verwendung von SOAP 1.1 rpc/encoded Modell und Silverlight erfordert SOAP 1.2 Dokument/Literal. Während die Problemumgehung für das in der Frage angegebene Problem funktioniert, kann der Web-Service dennoch nicht verwendet werden.
Ich schaffte es, diese Arbeit ohne den Rückgriff auf extreme Hacks zu machen. Der Schlüssel zu meiner Lösung war das Einfügen einer zusätzlichen IServerChannelSink
in die Anforderungsverarbeitungswarteschlange.Also änderte ich
var channel = new HttpChannel(8085);
zu meinen benutzerdefinierten registrieren IServerChannelSink
vor der normalen Pipeline:
var provider = ChainProviders(
new PolicyServerSinkProvider(),
new SdlChannelSinkProvider(),
new SoapServerFormatterSinkProvider(),
new BinaryServerFormatterSinkProvider());
var channel = new HttpChannel(new Hashtable(1) {{"port", 8085}}, null, provider);
Ich benutze eine Hilfsmethode zur Kette der Spüle Anbieter zusammen:
private static IServerChannelSinkProvider ChainProviders(
params IServerChannelSinkProvider[] providers)
{
for (int i = 1; i < providers.Length; i++)
providers[i-1].Next = providers[i];
return providers[0];
}
PolicyServerSinkProvider
einfach erstellt a PolicyServerSink
:
internal class PolicyServerSinkProvider : IServerChannelSinkProvider
{
public void GetChannelData(IChannelDataStore channelData){}
public IServerChannelSink CreateSink(IChannelReceiver channel)
{
IServerChannelSink nextSink = null;
if (Next != null)
nextSink = Next.CreateSink(channel);
return new PolicyServerSink(channel, nextSink);
}
public IServerChannelSinkProvider Next { get; set; }
}
PolicyServerSink
delegiert alle Nachrichten in der Kette, außer wenn sie eine Anforderung für crossdomain.xml
erhält - dann schreibt sie das benötigte XML in den Antwortstream.
internal class PolicyServerSink : IServerChannelSink
{
public PolicyServerSink(
IChannelReceiver receiver, IServerChannelSink nextSink)
{
NextChannelSink = nextSink;
}
public IDictionary Properties { get; private set; }
public ServerProcessing ProcessMessage(
IServerChannelSinkStack sinkStack, IMessage requestMsg,
ITransportHeaders requestHeaders, Stream requestStream,
out IMessage responseMsg, out ITransportHeaders responseHeaders,
out Stream responseStream)
{
if (requestMsg != null || ! ShouldIntercept(requestHeaders))
return NextChannelSink.ProcessMessage(
sinkStack, requestMsg, requestHeaders, requestStream,
out responseMsg, out responseHeaders, out responseStream);
responseHeaders = new TransportHeaders();
responseHeaders["Content-Type"] = "text/xml";
responseStream = new MemoryStream(Encoding.UTF8.GetBytes(
@"<?xml version=""1.0""?><!DOCTYPE cross-domain-policy SYSTEM "
+ @"""http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd"">"
+ @"<cross-domain-policy><allow-access-from domain=""*"" />"
+ @"</cross-domain-policy>")) {Position = 0};
responseMsg = null;
return ServerProcessing.Complete;
}
private static bool ShouldIntercept(ITransportHeaders headers)
{
return ((string) headers["__RequestUri"]).Equals(
"/crossdomain.xml", StringComparison.InvariantCultureIgnoreCase);
}
public void AsyncProcessResponse(IServerResponseChannelSinkStack sinkStack,
object state, IMessage msg, ITransportHeaders headers, Stream stream)
{
}
public Stream GetResponseStream(IServerResponseChannelSinkStack sinkStack,
object state, IMessage msg, ITransportHeaders headers)
{
throw new NotSupportedException();
}
public IServerChannelSink NextChannelSink { get; private set; }
}
Dies kann auch verwendet werden, um andere Dateien zusammen mit dem Webdienst zu bedienen. Ich verwende diese Methode derzeit, um meine Silverlight-Anwendung (den Consumer des Webdienstes) ohne einen separaten HTTP-Server zu hosten.
haben Sie jemals versucht, Ihren Webservice in Windows-Maschine zu betreiben ..? funktioniert das .. ?? – RameshVel
Ja, das sind nur die Sicherheitseinschränkungen von Silverlight, die das Szenario verhindern, das ich mir vorgenommen habe. – skolima