Silverlight 4 WCF The server did not provide a meaningful reply - wcf

I'm getting the notorious, "The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error" in my project. It's a WCF PollingDuplex Service, consumed by a Silverlight 4 project.
I'm requesting a document with the service, so I can display it in a viewer in my SL application.
Here is the Server Web Config XML:
<system.serviceModel>
<extensions>
<bindingExtensions>
<add name="pollingDuplex" type="System.ServiceModel.Configuration.PollingDuplexHttpBindingCollectionElement,System.ServiceModel.PollingDuplex, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</bindingExtensions>
</extensions>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
<behaviors>
<serviceBehaviors>
<behavior name="PortalOnlineBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<pollingDuplex>
<binding name="SLPollingDuplex" duplexMode="MultipleMessagesPerPoll" />
</pollingDuplex>
</bindings>
<services>
<service name="Online.Web.PortalOnline" behaviorConfiguration="PortalOnlineBehavior">
<endpoint address="" binding="pollingDuplex" bindingConfiguration="SLPollingDuplex"
contract="Notification.IPortalOnline" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://portalonline.com/PortalOnline/IPortalOnline" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
Here is the Object I'm trying to return to SL via this WCF service
Imports System.ServiceModel
Imports System.Runtime.Serialization
Imports DocCave.Common
Imports System.Xml
Imports System.IO
<DataContract(NAMESPACE:=DataStore.NAMESPACE)>
Public Class PortalDocument
<DataMember()>
Public Property DataSource As Byte()
<DataMember()>
Public Property FileName As String
<DataMember()>
Public Property FileType As String
End Class
Here's the WCF Method that is being called:
Public Function GetDocument(sessionUserMeta As Common.UserMetaData, docId As System.Guid) As Notification.PortalDocument Implements Notification.IPortalOnline.GetDocument
Dim doc As Documents.Document = Documents.Document.GetDocument(docId, sessionUserMeta)
Dim portalDoc As New PortalDocument
portalDoc.DataSource = doc.DataSource
portalDoc.FileName = doc.QueryPackage.DocumentName
portalDoc.FileType = doc.QueryPackage.Type
Return portalDoc
End Function
Further Details:
This works perfectly for one or two document request, and the gives me the above mentioned error. For instance, I can load a default document when the SL application is loaded using this method with this service, and it populates perfectly. I can then go to a tree view I have, and select a document, and it works perfect for the first document... but after that, error. Also, I've noticed sometimes it will only work once, if I select certain pdfs that are a bit larger (250kb or so..) ... oh, and I forgot... here's the code in my SL application that is connecting to the WCF service. I'm using the "GetBaseWebAddress()" because I'm using dynamic sub domains, so part of the address can be different each time...
Private Sub LoadClient()
Dim bind As New PollingDuplexHttpBinding(PollingDuplexMode.MultipleMessagesPerPoll)
Dim endpoint As New EndpointAddress(GetBaseWebAddress() & "PortalOnline/PortalOnline.svc")
Me.client = New PortalOnline.PortalOnlineClient(bind, endpoint)
AddHandlers()
End Sub
I've struggled with this for a while, so any help would be greatly appreciated...

Related

crossdomain.xml on WCF Service hosted by Windows Service

I am trying to make my Windows Service, which hosts a WCF service cross-domain compatible.
After hours and hours of searching I was told that I needed to create another service which will load the crossdomain.xml and clientaccesspolicy.xml files so that the Windows hosted WCF service can be run on any domain.
This is my main service :
Namespace UmbrellaMobileService
<RunInstaller(True)> _
Public Class ProjectInstaller
Inherits Installer
Private process As ServiceProcessInstaller
Private service As ServiceInstaller
Private components As System.ComponentModel.Container
Public Sub New()
process = New ServiceProcessInstaller()
process.Account = ServiceAccount.LocalSystem
service = New ServiceInstaller()
service.ServiceName = "UmbrellaMobileService"
service.DisplayName = "Umbrella Mobile Service"
service.Description = "Handels Umbrella Mobile Requests."
Installers.Add(process)
Installers.Add(service)
End Sub
End Class
<ServiceBehavior(InstanceContextMode:=InstanceContextMode.PerSession)> _
Public Class UmbrellaMobileService
Inherits ServiceBase
Public serviceHost As ServiceHost = Nothing
Public CrossDomainServiceHost As ServiceHost = Nothing
Public Shared Sub Main()
ServiceBase.Run(New UmbrellaMobileService())
End Sub
Public Sub New()
ServiceName = "UmbrellaMobileService"
End Sub
'Start the Windows service.
Protected Overloads Overrides Sub OnStart(ByVal args As String())
If serviceHost IsNot Nothing Then
serviceHost.Close()
End If
serviceHost = New WebServiceHost(GetType(UmbrellaService), New Uri("http://localhost/UmbrellaMobileService"))
serviceHost.AddServiceEndpoint(GetType(IUmbrellaMobileService), New WebHttpBinding(), "http://localhost/UmbrellaMobileService")
CrossDomainServiceHost = New ServiceHost(GetType(CrossDomainService))
Else
System.Diagnostics.EventLog.WriteEntry("Umbrella Mobile Service", objIniFile.ErrorMessage, EventLogEntryType.Error)
serviceHost.Close()
CrossDomainServiceHost.Close()
End If
serviceHost.Open()
CrossDomainServiceHost.Open()
End Sub
' Stop the Windows service.
Protected Overloads Overrides Sub OnStop()
If serviceHost IsNot Nothing Then
serviceHost.Close()
CrossDomainServiceHost.Close()
serviceHost = Nothing
End If
End Sub
End Class
<AspNetCompatibilityRequirements(Requirementsmode:=AspNetCompatibilityRequirementsMode.Allowed)> _
Public Class UmbrellaService
Inherits System.Web.Services.WebService
Implements IUmbrellaMobileService
Function GetCustomers() As Stream Implements IUmbrellaMobileService.GetCustomers
'Function Logic
End Function
End Class
End Namespace
This is my Implementation of my main service:
Namespace UmbrellaMobileService
<ServiceContract()> _
Public Interface IUmbrellaMobileService
<OperationContract()> _
<WebInvoke(Method:="GET", BodyStyle:=WebMessageBodyStyle.Bare, ResponseFormat:=WebMessageFormat.Json, RequestFormat:=WebMessageFormat.Json)> _
Function GetCustomers() As Stream
End Interface
End Namespace
This is the 'Cross Domain Service' I was advised to add:
Namespace UmbrellaMobileService
Public Class CrossDomainService
Implements ICrossDomainService
Public Function ProvidePolicyFile() As System.ServiceModel.Channels.Message Implements ICrossDomainService.ProvidePolicyFile
Dim filestream As FileStream = File.Open("ClientAccessPolicy.xml", FileMode.Open)
' Either specify ClientAccessPolicy.xml file path properly
' or put that in \Bin folder of the console application
Dim reader As XmlReader = XmlReader.Create(filestream)
Dim result As System.ServiceModel.Channels.Message = Message.CreateMessage(MessageVersion.None, "", reader)
Return result
End Function
End Class
End Namespace
And here is its Implementation :
Namespace UmbrellaMobileService
<ServiceContract()> _
Public Interface ICrossDomainService
<OperationContract(), WebGet(UriTemplate:="ClientAccessPolicy.xml")> _
Function ProvidePolicyFile() As Message
End Interface
End Namespace
My config file looks like this :
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="CrossDomainServiceBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="MyServiceBehavior" name="UmbrellaMobileService.UmbrellaMobileService">
<endpoint address="" binding="basicHttpBinding" contract="UmbrellaMobileService.IUmbrellaMobileService">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8731/UmbrellaMobileService"/>
</baseAddresses>
</host>
</service>
<service name="UmbrellaMobileService.CrossDomainService">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8731/"/>
</baseAddresses>
</host>
<endpoint address="" binding="webHttpBinding" contract="UmbrellaMobileService.ICrossDomainService" behaviorConfiguration="CrossDomainServiceBehavior"/>
</service>
</services>
</system.serviceModel>
<system.web>
<compilation debug="true"/></system.web></configuration>
Now, I get this error when I attempt to run this service:
Service cannot be started. System.InvalidOperationException: Service has zero application (non-infrastructure) endpoints.
This might be because no configuration file was found for your application,
or because no service element matching the service name could be found in the configuration file, or because no endpoints were defined in the service element.
I have searched and searched and still do not know what to do, can anyone give me some advice?
I had the same issue and here is how I fixed it.
First, create a new service class that will serve up the clientaccesspolicy.xml when a client requests it:
[ServiceContract]
public class CrossDomainPolicyService
{
private Stream StringToStream(string result)
{
WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml";
return new MemoryStream(Encoding.UTF8.GetBytes(result));
}
[OperationContract, WebGet(UriTemplate = "/clientaccesspolicy.xml")]
public Stream GetClientAccessPolicy()
{
string result = #"<?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>";
return StringToStream(result);
}
}
Next, modify your app.config file to expose the new service:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="policyBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<services>
<service name="MyNamespace.MyService">
<endpoint address="" binding="basicHttpBinding" contract="MyNamespace.IMyService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:9876/MyService/" />
</baseAddresses>
</host>
</service>
<service name="MyNamespace.CrossDomainPolicyService">
<endpoint address="" binding="webHttpBinding" contract="MyNamespace.CrossDomainPolicyService" behaviorConfiguration="policyBehavior">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<host>
<baseAddresses>
<!-- Root Domain where the other service is hosted -->
<add baseAddress="http://localhost:9876/" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
... and that should do it!

Unable to resolve WCF "Metadata publishing for this service is currently disabled" error

I'm branching out into .Net web services and unfortunately am a newbie at it. I've decided to build WCF service instead of asp.net service because of online recommendations. My ultimate goal is to learn iOS and other mobile programming. I'm familiar with vb.net and c# standard and web applications.
I'm receiving a "Metadata publishing for this service is currently disabled" error when trying to test from a URL. I've research and tried implementing "fixes" for this issue, but still come up short. Can someone please look at my code and see what I'm doing wrong?
Webconfig file
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" strict="false"
explicit="true" targetFramework="4.0" />
<customErrors mode="Off"/>
</system.web>
<connectionStrings>
</connectionStrings>
<system.serviceModel>
<services>
<services>
<service name="CCT_Main_SRV.Service1" behaviorConfiguration="BehConfig">
<endpoint address="" binding="webHttpBinding" contract="CCT_Main_SRV.Service1" behaviorConfiguration="web">
</endpoint>
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="BehConfig">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true">
</serviceHostingEnvironment>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
.VB File
Imports System.ServiceModel
Imports System
Namespace CCT_Main_SRV.Service1
<ServiceContract()>
Public Interface CCT_Main_SRV
<OperationContract()>
<WebGet(UriTemplate:="Get_Device_Authenication", _
RequestFormat:=WebMessageFormat.Json, _
ResponseFormat:=WebMessageFormat.Json, _
BodyStyle:=WebMessageBodyStyle.Wrapped)>
Function Authenicate_Device_Manager(ByVal Device_Name As String, _
ByVal Auth_Key As String) _
As List(Of Device_Authenication)
<WebGet()>
<OperationContract()>
Function Authenicate_Device_Manager_Non_JSON(ByVal Device_Name As String, _
ByVal Auth_Key As String) _
As List(Of Device_Authenication)
End Interface
<DataContract()>
Public Class Device_Authenication
<DataMember()>
Public Property Device_Name As String
<DataMember()>
Public Property Active As Boolean
<DataMember()>
Public Property Return_String As String
End Class
svc.vb file
Imports System.ServiceModel
Imports System.Web.Script.Serialization
Imports System.ServiceModel.Activation
Imports System.ServiceModel.Web
Imports System.ServiceModel.Description
Namespace CCT_Main_SRV.Service1
Public Class Service1
Implements CCT_Main_SRV
Dim host As WebServiceHost = New WebServiceHost(GetType(Service1), New Uri("http://pmh-vmutility-1/cct_web_srv_test/:8000/"))
Dim ep As ServiceEndpoint = host.AddServiceEndpoint(GetType(CCT_Main_SRV), New WebHttpBinding(), "")
Public Function Authenicate_Device_Manager(ByVal Device_Name As String, _
ByVal Auth_Key As String) _
As List(Of Device_Authenication) _
Implements CCT_Main_SRV.Authenicate_Device_Manager
End Function
End Class
End Namespace
service name="CCT_Main_SRV.Service1"
Should be:
service name="Service1"
Or if it resides in a Web Application:
service name="ProjectName.Web.Service1"
It should match the fully qualified name of your service
{namespace}.{class} yours does not have a namespace.

WCF service is not accessible outside of local computer

I deployed WCF service (.NET 3.5) to IIS 5.1 (WinXP) and it's accessible from local computer. But, it's not accessible outside of local computer.
Here's my web.config file:
<system.serviceModel>
<serviceHostingEnvironment>
<baseAddressPrefixFilters>
<add prefix="http://222.22.22.222:8072/"/>
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
<behaviors>
<serviceBehaviors>
<behavior name="Parus.ServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpGetUrl="http://111.1.11.111:8072/AsurReceiveData/Service.svc"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<MyInspector />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="Parus.ServiceBehavior" name="Parus.Service">
<endpoint address="http://222.22.22.222:8072/AsurReceiveData/Service.svc" binding="basicHttpBinding" contract="Parus.IService">
</endpoint>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/>
</service>
</services>
<extensions>
<behaviorExtensions>
<add name="MyInspector" type="Parus.MessageInspectorExtension, Parus, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</behaviorExtensions>
</extensions>
</system.serviceModel>
The computer's local IP address is: 111.1.11.111:8072.
The computer's public IP address is: 222.22.22.222:8072.
What I did? I've added new TCP port in IIS 5.1 (Default Web Site Properties -> Web Site tab -> click Advanced button -> click Add button and add new port: 8072).
The project URL looks as following:
http://111.1.11.111:8072/ServiceFolder
The service looks as follows:
public class Service : IService
{
public const string ReplyAction = "http://222.22.22.222:8072/AsurReceiveData/Message_ReplyAction";
public const string RequestAction = "http://222.22.22.222:8072/AsurReceiveData/Message_RequestAction";
public Message SetData(Message requestXml)
{
using (StreamWriter writer = File.CreateText(#"Path\Body.xml"))
{
writer.WriteLine(requestXml.ToString());
}
Message response = Message.CreateMessage(MessageVersion.Default, ReplyAction, requestXml.ToString());
return response;
}
}
I'm not sure if I use local and public IP addresses properly. Maybe it's something else...
I appreciate any help.
You have a firewall on you computer which blocks all incoming calls. You should turn off the firewall or open the 8072 port to be able to communicatie from other computers with you wcf service.

How to use a WCF service with HTTP Get (within Visual studio 2010)

We've tried to use a very very simple WCF service with a HTTp Get and we can't get it work.
We've followed those "guide" but it doesn't work
http://msdn.microsoft.com/en-us/library/bb412178.aspx
http://www.dotnetfunda.com/articles/article779-simple-5-steps-to-expose-wcf-services-using-rest-style-.aspx
When we call our service with the following url, we get a page not found error:
http://localhost:9999/Service1.svc/GetData/ABC
The base url (http://localhost:9999/Service1.svc) works fine and returns the wcf service information page correctly.
Those are the steps and code to reproduce our example.
In Visual Studio 2010, create a new "WCF Service Application" Project
Replace the IService interface with this code
[ServiceContract()]
public interface IService1
{
[OperationContract()]
[WebInvoke(Method = "GET",
BodyStyle = WebMessageBodyStyle.Bare,
UriTemplate = "GetData/{value}")]
string GetData(string value);
}
Replace the Service class with this code
public class Service1 : IService1
{
public string GetData(string value)
{
return string.Format("You entered: {0}", value);
}
}
The web.config look like this
<system.web>
<compilation debug="true" strict="false" explicit="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="Service1">
<endpoint address="" binding="webHttpBinding" contract="IService1" behaviorConfiguration="WebBehavior1">
</endpoint>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="WebBehavior1">
<webHttp helpEnabled="True"/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
Press Run and try to call the Get method
If someone get this or something similar working, it would be very kind if you could reply information about the working example.
Thank you very much
I recreated your sample - works like a charm.
One point: do your service contract (public interface IService1) and service implementation (public class Service1 : IService1) exist inside a .NET namespace??
If so, you need to change your *.svc and your web.config to include:
<services>
<service name="Namespace.Service1">
<endpoint address="" binding="webHttpBinding"
contract="Namespace.IService1"
behaviorConfiguration="WebBehavior1">
</endpoint>
</service>
</services>
The <service name="..."> attribute and the <endpoint contract="..."> must include the .NET namespace for this to work.

How to declaratively implement custom IAuthorizationPolicy in WCF?

I have a WCF service that is hosted in IIS. I want to use my own IAuthorizationPolicy, and have it configured in the web.config file on the server. I have my auth policy:
namespace MyLib.WCF
{
public class CustomAuthorizationPolicy : IAuthorizationPolicy
{
public CustomAuthorizationPolicy()
{
this.Id = Guid.NewGuid().ToString();
}
public bool Evaluate(EvaluationContext evaluationContext, ref object state)
{
throw new ApplicationException("Testing custom auth");
}
...
}
}
And in my web.config:
<service behaviorConfiguration="Behavior" name="MyService">
<endpoint address="" binding="wsHttpBinding" contract="IMyService"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
<serviceBehaviors>
<behavior name="Behavior">
<serviceAuthorization principalPermissionMode="Custom">
<authorizationPolicies>
<add policyType="MyLib.WCF.CustomAuthorizationPolicy, MyLib.WCF, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</authorizationPolicies>
</serviceAuthorization>
</behavior>
</serviceBehaviors>
But my CustomAuthorizationPolicy.Evaluate() method never fires. What am I missing?
Well, the obvious (silly) question is: in your <service>, do you actually reference your behavior configuration??
I.e. do you have:
<system.serviceModel>
....
<service name="YourService" behaviorConfiguration="Behavior">
....
</service>
....
</system.serviceModel>
Just defining all your stuff is nice and well - but unless you've actually referenced it, it won't do you any good (been there, done that myself, too! :-) )
Second (almost as silly) question would be: what binding and security config do you use?? Have you even turned on security at all? If you have <security mode="None">, then your service authorization will obviously never be used, either (since no credentials are being passed to the service at all).
Marc