EDIT2:我的同事發現了一個可用的解決方案:來自微軟的Web Service Enhancements。它確實需要IIS,並且在引入WCF時已被棄用,但在純淨的.Net Framework 2.0中運行良好,並且應該可部署到Mono XSP。
EDIT:下面溶液是沒有意義的,因爲淨2.0暴露使用SOAP 1.1 RPC /編碼模型web服務,和Silverlight需要SOAP 1.2文檔/文字。因此,儘管解決方法適用於問題中指出的問題,但Web服務仍然無法使用。
我設法使這項工作,而不訴諸極端黑客。我的解決方案的關鍵是在請求處理隊列中插入額外的IServerChannelSink
。所以,我改變
var channel = new HttpChannel(8085);
正常管道之前註冊我的自定義IServerChannelSink
:
var provider = ChainProviders(
new PolicyServerSinkProvider(),
new SdlChannelSinkProvider(),
new SoapServerFormatterSinkProvider(),
new BinaryServerFormatterSinkProvider());
var channel = new HttpChannel(new Hashtable(1) {{"port", 8085}}, null, provider);
我使用一個輔助的方法來鏈水槽供應商一起:
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
簡單的創建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
委託鏈中的所有消息,除非它獲得crossdomain.xml
的請求 - 那麼它會將所需的xml寫入響應流。
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; }
}
這也可以用來與網絡服務一起提供其他文件。我目前正在使用這種方法來託管我的Silverlight應用程序(Web服務的使用者),而無需單獨的http服務器。
你曾經嘗試在Windows機器上運行你的web服務..?是那個作品.. ?? – RameshVel 2009-08-25 10:59:08
是的,它的確如此,這只是Silverlight的安全限制,可以防止我想到的情況。 – skolima 2009-08-25 12:35:08