1

この投稿は長くなりますが、あらかじめお詫び申し上げます。

Visual Studio から実行しているサービスと通信する Silverlight アプリケーションを作成しようとしていますが、現時点では IIS でホストされていません。このプロトタイプでは、コードと構成をできるだけ少なくしようとしています。インターネットには、これに関する答えとしての質問がたくさんありますが、どれも私の特定の苦境には当てはまらないようです.

私のサービス ソリューションには、IAsyncResult インターフェイス、サービス インターフェイス、ISimpleService、および SimpleService でのサービスの実際の実装を実装する SimpleServiceAsyncResult があります。このサービスは次のように実装されます。

public class SimpleService : ISimpleService
{
    public IAsyncResult BeginSimpleMethod(string msg, AsyncCallback callback, object state)
    {
        return new SimpleServiceAsyncResult<string>(msg);
    }

    public string EndSimpleMethod(IAsyncResult result)
    {
        SimpleServiceAsyncResult<string> res = result as SimpleServiceAsyncResult<string>;
        return res.Result;
    }

    public string SimpleMethod(string msg)
    {
        return msg;
    }


    public Message ProvideCrossDomainFile()
    {
        FileStream fileStream = File.Open(@"CrossDomain.xml", FileMode.Open, FileAccess.Read, FileShare.Read);

        XmlReaderSettings settings = new XmlReaderSettings();
        settings.DtdProcessing = DtdProcessing.Parse;

        XmlReader reader = XmlReader.Create(fileStream, settings);

        Message result =  Message.CreateMessage(MessageVersion.None, "", reader);
        return result;
    }

    public Message ProvidePolicyFile()
    {
        FileStream fileStream = File.Open(@"ClientAccessPolicy.xml", FileMode.Open, FileAccess.Read, FileShare.Read);
        XmlReader reader = XmlReader.Create(fileStream);
        Message result = Message.CreateMessage(MessageVersion.None, "", reader);
        return result;
    }
}

プロジェクトには 2 つの xml ファイルがあります。次のような ClientAccessPolicy.xml および CrossDomain.xml。

ClientAccessPolicy.xml

<?xml version="1.0" encoding="utf-8"?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from http-request-headers="*">
        <domain uri="*"/>
      </allow-from>
      <grant-to>
        <resource path="/" include-subpaths="true"/>
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>

CrossDomain.xml

<?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="*" />
  <allow-http-request-headers-from domain="*" headers="SOAPAction" />
</cross-domain-policy> 

これに加えて、次のような App.config があります。

App.config

<behaviors>
  <serviceBehaviors>
    <behavior name="SimpleServiceBehavior">
      <serviceMetadata httpGetEnabled="True"/>
    </behavior>
  </serviceBehaviors>
</behaviors>

さて、このすべての良さが実際に機能するかどうかを確認したかった. そこで、Program.cs と App.config のみを使用して、コンソール プロジェクトを使用してソリューションを作成しました。

もちろん、プログラムは特別なものではなく、最低限のものです。

       var factory = new ChannelFactory<ISimpleService>("SimpleService");
        ISimpleService service = factory.CreateChannel();

        var asResult = service.BeginSimpleMethod("tesmsg", null, null);

        Console.WriteLine("Data: " + service.EndSimpleMethod(asResult);

これはすべてうまく機能し、探しているデータが戻ってくるので、満足しています。次に達成したかったことは、Silverlight アプリを使用して、同じサービスからデータを取得することでした。

これを実現するために、クライアント ソリューションで Silverlight プロジェクトを作成し、サービス参照を作成して、soms 配管を行いました。MainPage.xaml.cs にいくつかのコードを追加して、SimpleMethod を実行しようとしています。

    void SimpleMethodCompletedProxyCallback(object sender, SimpleMethodCompletedEventArgs e)
    {
        if (e.Error == null)
        {
            data = e.Result;
        }
    }

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        SimpleServiceClient proxy = new SimpleServiceClient();

        proxy.SimpleMethodCompleted += new EventHandler<SimpleMethodCompletedEventArgs>(SimpleMethodCompletedProxyCallback);
        try
        {

            proxy.SimpleMethodAsync("teststring");
        }
        catch (CommunicationException cex)
        {
            label1.Content = cex.Message;
        }
    }

この配管が完了すると、データを取得できると思いましたが、SimpleMethod を呼び出そうとすると、生成された ServiceReference コードから CommunicationException がスローされ続けます。

        public string EndSimpleMethod(System.IAsyncResult result) {
            object[] _args = new object[0];
            string _result = ((string)(base.EndInvoke("SimpleMethod", _args, result)));
            return _result;
        }

私はこれについて数時間ウェブをサーフィンしており、最終的には CrossDomain.xml と ClientAccessPolicy.xml とこれを公開するメソッドに行き着きましたが、何を試しても同じ例外が発生し続けます。次に何をすればいいのかわからないので、これについてもう少し助けていただければ幸いです。

敬具

4

1 に答える 1

2

あなたのサービス コードでは、SimpleServiceクラスは 1 つのインターフェイス ( ISimpleService) を実装します。これは装飾されていると想定し[ServiceContract]、5 つの操作コントラクト (BeginSimpleMethod、EndSimpleMethod、SimpleMethod、ProvideCrossDomainFile、ProvidePolicyFile) を定義します。ProvidePolicyFile も [WebGet(UriTemplate = "/clientaccesspolicy.xml")] で装飾されている可能性があります。

ここでは、インターフェースが 1 つしかないため、サーバー内のエンドポイントが SOAP エンドポイント (例: -basicHttpBindingベース) であるか、エンドポイントが REST エンドポイント (例: webHttpBinding/webHttp動作) のいずれかになります。

前者の場合、clientaccesspolicy.xml を返す操作の場所が正しくありません。WebGetAttributeのドキュメントの備考セクションによると、これは受動的な動作であり、エンドポイントにWebHttpBehavior. Silverlight はそのポリシー ファイルを 1 つの場所 (http://your_service/clientaccesspolicy.xml) で検索し、別の場所 (http://your_service/endpoint、メソッドを示す SOAPAction ヘッダー付き) でアクセスできるようにします。

後者の場合、Silverlight は既定でこれらのエンドポイントを呼び出すことができないため ( SL から REST /POXおよびREST/JSONエンドポイントを呼び出すための投稿を参照)、どちらも機能しません。

http://blogs.msdn.com/b/carlosfigueira/archive/2008/03/07/enabling-cross-domain-calls-for-silverlight-apps-on-self-hosted-web-services.aspxの投稿SLがセルフホステッドWCFサービスでサービスを呼び出せるようにするための「正規の」方法はAFAIKです。2 つのエンドポイント (おそらく 2 つのインターフェイス) が必要です。1 つはサービス自体用、もう 1 つはポリシー ファイル用です。投稿には、この問題の詳細があります。

于 2011-08-12T16:00:54.233 に答える