Laden...

[erledigt] Silverlight-Zugriff auf self-hosted WCF-Service (clientaccesspolicy.xml)

Erstellt von Desert Fox vor 12 Jahren Letzter Beitrag vor 12 Jahren 1.256 Views
D
Desert Fox Themenstarter:in
33 Beiträge seit 2010
vor 12 Jahren
[erledigt] Silverlight-Zugriff auf self-hosted WCF-Service (clientaccesspolicy.xml)

Hallo Community,

ich möchte auf einen in einem eigenen Dienst gehosteten WCF Service in silverlight zugreifen, der service ist mit einem BasicHttp Binding gehosted. Ich habe mittlerweile herausgefunden das ich ein clientpolicy file im Root des Ports hosten. Mein problem ist jetzt wenn ich auf den Service zugreife bekomme ich ein File Not Found.

Ich habe das Ganze mit Fiddler analysiert, die clientaccesspolicy wird abgefragt allerdings gibt der server beim eigentlichen wcf aufruf einen http 500 error zurück.

PS: Ich habe gelesen man kann auch tcp bindings verwenden sofern man das clientaccesspolicy file auf http port 80 hosted, kann man irgentwie vermeiden das ganze nicht auf port 80 zu hosten?

hier mein server code:

( hier im beispiel ist rootUrl http://MICHAEL-PC:19701


    public class GameServiceHost
    {
        protected InstanceServer _server;
        protected ServiceHost _gameServiceHost;
        protected ServiceHost _accessPolicicyServiceHost;

        public GameServiceHost(InstanceServer server)
        {
            _server = server;

            ConnectionString connectionString = ConnectionString.HosingConnectionString(server.GameInstance.Name);

            string rootUrl = connectionString.GetRootUrl();
            string gameServiceUrl = connectionString.GetServerInstanceGameServiceUrl();
            
            _gameServiceHost = new ServiceHost(typeof(GameService), new Uri(rootUrl));

            // Game Service
            var binding = ServiceDefinition.GetBinding();
            _gameServiceHost.AddServiceEndpoint(typeof(IGameService), binding, connectionString.InstanceName + "/" + ConnectionString.GameServiceUri /*new Uri(serviceUrl)*/);
            _gameServiceHost.AddServiceEndpoint(typeof(IClientAccessPolicy), new WebHttpBinding(), "")
                .Behaviors.Add(new WebHttpBehavior());

            // Http Get
            var metadataBehavior = _gameServiceHost.Description.Behaviors.Find<ServiceMetadataBehavior>();
            if (metadataBehavior == null)
            {
                metadataBehavior = new ServiceMetadataBehavior();
                _gameServiceHost.Description.Behaviors.Add(metadataBehavior);
            }

            metadataBehavior.HttpGetEnabled = true;
            metadataBehavior.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;

            // Debug Behavoir
            var debugBehavior = _gameServiceHost.Description.Behaviors.Find<ServiceDebugBehavior>();
            if (debugBehavior == null)
            {
                debugBehavior = new ServiceDebugBehavior(){ };
                _gameServiceHost.Description.Behaviors.Add(debugBehavior);
            }
            debugBehavior.IncludeExceptionDetailInFaults = true;

            // Add MEX endpoint
             _gameServiceHost.AddServiceEndpoint(
              ServiceMetadataBehavior.MexContractName,
              MetadataExchangeBindings.CreateMexHttpBinding(),
              "mex"
            );
        }

        public void Start()
        {
            //_accessPolicicyServiceHost.Open();
            _gameServiceHost.Open();
        }
    }

Hier ein ausschnitt aus der ConnectionString-Klasse



        public const string GameServiceUri = "GameService";

        public const int BasePortNumber = 19000;

        /// <summary>
        /// Gets the root url for clientaccesspolicy.
        /// </summary>
        /// <returns></returns>
        public string GetRootUrl()
        {
           int portNumber = ConnectionString.BasePortNumber + PortOffset;
           return string.Format("http://{0}:{1:d}", Server, portNumber);
        }

        public string GetClientInstanceGameServiceUrl()
        {
            return GetServerInstanceGameServiceUrl();
            //return string.Format("{0}/{1}", GetServiceUrl(), GameServiceUri);
        }

        /// <summary>
        /// Gets the root url for the instance
        /// </summary>
        /// <returns></returns>
        public string GetServerInstanceUrl()
        {
            return string.Format("{0}/{1}", GetRootUrl(), InstanceName);
            //return string.Format("http://{0}:19701/instances/{1}", ServerName, InstanceName);
        }

        public string GetServerInstanceGameServiceUrl()
        {
            return string.Format("{0}/{1}", GetServerInstanceUrl(), ConnectionString.GameServiceUri);
        }


Mein Service


    public class GameService : IGameService, IClientAccessPolicy
    {
        public GameService()
        { 
        
        }

        /////////////////////////////////////////////////////////////////
        // IGameService
        /////////////////////////////////////////////////////////////////

        //[OperationContract]
        public GameDefinition GetDefinition()
        {
            return new GameDefinition()
            {
                
            };
        }

        public int Add(int a, int b)
        {
            return a + b;
        }


        public Stream GetResource(string name)
        {
            return null;
        }

        /////////////////////////////////////////////////////////////////
        // IClientAccessPolicy
        /////////////////////////////////////////////////////////////////

        [OperationBehavior]
        public Stream GetClientAccessPolicy()
        {
            if (WebOperationContext.Current != null)
                WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml";
            return new MemoryStream(GameService.ClientAccessPolicyBytes);
        }

        [OperationBehavior]
        public Stream GetCrossDomainPolicy()
        {
            if (WebOperationContext.Current != null)
                WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml";
            return new MemoryStream(GameService.CrossDomainPolicyBytes);
        }

        public static byte[] ClientAccessPolicyBytes = Encoding.UTF8.GetBytes(
@"<?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>");

        public static byte[] CrossDomainPolicyBytes = 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-http-request-headers-from domain=\"*\" headers=\"*\"/>" +
"</cross-domain-policy>");
    }


D
Desert Fox Themenstarter:in
33 Beiträge seit 2010
vor 12 Jahren

Ok ich habe einen IErrorHandler hinzugefügt, das hat folgendes ergeben:

Fehlermeldung:
{System.ServiceModel.FaultException: Die Nachricht mit Action "urn:IGameService/Add" kann aufgrund einer fehlenden ContractFilter-Übereinstimmung beim EndpointDispatcher nicht verarbeitet werden. Mögliche Ursachen: Vertragskonflikt (keine Action-Übereinstimmung zwischen Sender und Empfänger) oder ein Bindung/Sicherheit-Konflikt zwischen dem Sender und dem Empfänger. Stellen Sie sicher, dass Sender und Empfänger über den gleichen Vertrag und die gleiche Bindung verfügen (einschließlich Sicherheitsanforderungen, z. B. "Message", "Transport", "None").
bei System.ServiceModel.Dispatcher.ErrorBehavior.ThrowAndCatch(Exception e, Message message)}

Lösung des Problems war, ich habe zwei klassen für die service definition erstellt (eine zum hosten und eine zweite asyncrone für den silverlight zugriff) und bei der einen hatte ich Namespace auf "" gesetzt und bei der anderen nicht.