Contract requires Duplex, but Binding 'BasicHttpBinding' doesn't support it or isn't configured properly to support it - wcf

my project is silverlight and use Ria service.
I want to create a WCF Service,
this is my code
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class MessageDuplex : IServiceSide
{
public void Attach(string s)
{
}
}
[ServiceContract]
interface IClientSide
{
[OperationContract(IsOneWay = true)]
void SendMessage(string s);
}
[ServiceContract(CallbackContract = typeof(IClientSide))]
interface IServiceSide
{
[OperationContract(IsOneWay = true)]
void Attach(string s);
}
When i defined IServiceSide without CallbackContract this is add to silverlight project correctly, but when i use CallbackContract this error raise when add Service Referense :
"Contract requires Duplex, but Binding 'BasicHttpBinding' doesn't support it or isn't configured properly to support it."

BasicHttpBinding doesn't support duplex services. You must use PollingDuplexHttpBinding.

Related

Provide multiple interface in a single service

I want to separate my service contracts from their properties.
Example:
IWirelessService
IWiredService
I want my IWirelessService implemented in IRasadService, but when i add wsdl into the wcf test client, it gives following error:
Failed to add a service. Service metadata may not be accessible. Make sure your service is running and exposing metadata.
I want to only provide IRasadService as my main webservice. How can i do this?
Relevant Code:
[ServiceContract]
public interface IWirelessService
{
[OperationContract]
void AddUser();
}
public class WirelessService : IWirelessService
{
UserProvider userProvider;
#region User Operations
public void AddUser()
{
throw new NotImplementedException();
}
}
[ServiceContract]
public interface IRasadService :IWirelessService
{
[OperationContract]
BoxRasadWCFReturn GetDataUsingDataContract(CompositeType composite);
// TODO: Add your service operations here
}

using class interface as a parameter in wcf service

I Have WCF Service Contract and Using a class interface as a parameter as follow :
[ServiceContract(Name = "IFrameworkBaseService", CallbackContract = typeof(IFrameworkBaseServiceCallback))]
public interface IFrameworkBaseService
{
[OperationContract]
void InitializeConnection(IClientID clientID);
}
but I get the following error :
The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state
Can anyone help me by this problem
Thanks
Afshin
I think the concret object you passed in for the IClientID is just unknown to the service.
You have to add it with KnownType-Attribute
[ServiceContract(Name = "IFrameworkBaseService", CallbackContract = typeof(IFrameworkBaseServiceCallback))]
[KnownType(typeof(MyClientId))]
public interface IFrameworkBaseService
{
[OperationContract]
void InitializeConnection(IClientID clientID);
}

401 error on jsdebug file when changing WCF service to use an interface

Scenario. I add an "AJAX-enabled WCF Service" to my ASP.NET application (webforms). This results in the following (long namespaces truncated):
[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class MyService
{
// To use HTTP GET, add [WebGet] attribute. (Default ResponseFormat is WebMessageFormat.Json)
// To create an operation that returns XML,
// add [WebGet(ResponseFormat=WebMessageFormat.Xml)],
// and include the following line in the operation body:
// WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml";
[OperationContract]
public void DoWork()
{
// Add your operation implementation here
return;
}
// Add more operations here and mark them with [OperationContract]
}
I change
[ServiceContract(Namespace = "")]
to
[ServiceContract(Namespace = "http://domain.com/services")]
To my page I add:
<asp:ScriptManagerProxy ID="ScriptManagerProxy1" runat="server">
<Services>
<asp:ServiceReference path="~/Services/MyService.svc" />
</Services>
</asp:ScriptManagerProxy>
I also add a javascript function so I can call the service:
function callDoWork(){
domain.com.services.MyService.DoWork();
}
The website is run with Windows authentication. When I run the page, the jsdebug file is generated, found, and domain.com.services.MyService.DoWork(); works with no problem. This is confirmed with FireBug. So my next step is to create an interface and have the service class implement it. So now I have:
[ServiceContract(Namespace = "http://domain.com/services")]
public interface IMyService
{
[OperationContract]
void DoWork();
}
and
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class MyService : IMyService
{
public void DoWork()
{
// Add your operation implementation here
return;
}
}
and change the web.config to say contract="Namespace.IMyService"
Now, I get a 401 error on the jsdebug file. Anyone ever seen this?
Thanks for your help.
This was a red herring. For whatever reason, also having a mex endpoint on the service caused this to occur. I take the mex endpoint off, and the 401 goes away. Not that this is a solution, but at least I get past my error.

Importing ASMX Web Service metadata to WCF Endpoint

I am interested in impersonating well-known Web Services and Wcf Services for integration test purposes. To this end, I would like to capture service metadata, auto-generate service stubs, and host service stubs in a self-hosted environment.
Following this article here, I am able to obtain remote Wcf Service metadata and generate contracts. However, I am having some difficulty doing the same for remote Asmx Web Services.
I have a set of mickey-mouse solutions for vetting this out.
My Asmx solution contains a default "Hello World" web service, found below
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class SimpleAsmxService : System.Web.Services.WebService
{
[WebMethod]
public string HelloWorld () { return "Hello World"; }
}
My Wcf solution contains a default "Hello World" service, also found below
[ServiceContract]
public interface ISimpleWcfService
{
[OperationContract]
string GetData(int value);
[OperationContract]
CompositeType GetDataUsingDataContract(CompositeType composite);
}
[DataContract]
public class CompositeType
{
[DataMember]
public bool BoolValue { get; set; }
[DataMember]
public string StringValue { get; set; }
}
public class SimpleWcfService : ISimpleWcfService
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
public CompositeType GetDataUsingDataContract(CompositeType composite)
{
if (composite.BoolValue)
{
composite.StringValue += "Suffix";
}
return composite;
}
}
Finally, the little console-that-could looks like
class Program
{
public const string UrlWcf =
"http://localhost:8731/Design_Time_Addresses/SimpleWcfService/mex";
public const string UrlAsmx =
"http://localhost:1803/SimpleAsmxService.asmx?WSDL";
static void Main(string[] args)
{
EndpointAddress mexAddress = new EndpointAddress (UrlWcf);
MetadataExchangeClient mexClient =
new MetadataExchangeClient (mexAddress);
mexClient.ResolveMetadataReferences = true;
// NOTE: blows up if we use UrlAsmx
MetadataSet metaSet = mexClient.GetMetadata ();
WsdlImporter importer = new WsdlImporter (metaSet);
Collection<ContractDescription> contracts =
importer.ImportAllContracts();
}
}
It seems to me that I should be able to pull Wsdl from a well-known Asmx Web Service and generate contracts [and from contracts to code], but cannot seem to contort the preceding sample to do so. Any help would be much appreciated,
Thanks!
NOTE: the error generated when invoking MetadataSet metaSet = mexClient.GetMetadata(); above is a System.InvalidOperationException with message of
Metadata contains a reference that cannot be resolved : 'http://localhost:1803/SimpleAsmxService.asmx?WSDL'
With a System.InvalidOperationException inner exception with message of
<?xml version="1.0" encoding="utf-16"?>
<Fault xmlns="http://www.w3.org/2003/05/soap-envelope">
<Code>
<Value>Sender</Value>
</Code>
<Reason>
<Text xml:lang="en">
System.Web.Services.Protocols.SoapException: Unable to handle request without a valid action parameter. Please supply a valid soap action.
at System.Web.Services.Protocols.Soap12ServerProtocolHelper.RouteRequest()
at System.Web.Services.Protocols.SoapServerProtocol.RouteRequest(SoapServerMessage message)
at System.Web.Services.Protocols.SoapServerProtocol.Initialize()
at System.Web.Services.Protocols.ServerProtocol.SetContext(Type type, HttpContext context, HttpRequest request, HttpResponse response)
at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing)
</Text>
</Reason>
</Fault>
The way to get it to work with an ASMX web service is to specify the MetadataExchangeClientMode
...
MetadataExchangeClient mexClient =
new MetadataExchangeClient (new Uri(), MetadataExchangeClientMode.HttpGet);
...
using MetadataExchangeClientMode.HttpGet for your ASMX services
and MetadataExchangeClientMode.MetadataExchange for your WCF services.

Injecting an unrelated contract into the WSDL created by WCF's MEX provider

I am implementing a WCF service (Contract A) that will eventually make calls to a standalone service (Contract B) hosted by the client. At design-time when the client queries my service's WSDL to build its proxy, I'd like to include the WSDL for Contract B so the client can build its service around that. Unfortunately, I can't figure out how to inject Contract B into the WSDL emitted by the service. Since the contract is an interface and doesn't have the [DataContract] attribute I can't add it as a known type. Is there any other way to inject a contract into emitted WSDL?
Here's an example:
[ServiceContract]
public interface IServerService
{
[OperationContract]
void GiveTheServerMyServiceUri(string uri);
[OperationContract]
void TellAllClientsSomething(string message);
}
// THIS IS THE INTERFACE I WANT TO INCLUDE IN THE WSDL
[ServiceContract]
public interface IClientService
{
[OperationContract]
void ReceiveMessageFromServer(string message);
}
public class ServerService : IServerService
{
private List<string> knownClients;
public void GiveTheServerMyServiceUri(string uri)
{
knownClients.Add(uri);
}
public void TellAllClientsSomething(string message)
{
foreach (string clientUri in knownClients)
{
// 1. Create instance of ClientServiceProxy using client's uri
// 2. Call proxy.ReceiveMessageFromServer(message)
}
}
}
At first it seems that this is a textbook example of a duplex contract. However, for this particular application, for a variety of reasons, I need a bit more separation between client and server so I was hoping to just give the client an interface to implement (via the WSDL), let it host its own service, then just tell me the service's url.
I don't see that this makes sense. Unless your service is implementing the service contract of the other service, then don't do this.
On the other hand, your service can implement the other service contract, and become a client to the other service. It can then delegate calls to the other service contract to that other service.
I just tried this to make sure. I created a new WCF Service library project. This created a Service1 implementing IService1, with two operations. I modified the [ServiceContract] attribute to use a specific namespace (http://localhost/service1).
I then added a new service, which gave me Service2, implementing IService2, with a single operation (DoWork). I updated the [ServiceContract] to use http://localhost/service2/.
I then updated Service1 to implement IService2 as well as IService1, and to delegate IService2.DoWork to the Service2 service. I did also have to add a new endpoint implementing IService2, and I had to specify a relative address, so that the two would not conflict (since they were in the same project). Here's the result:
using System;
namespace WcfServiceLibrary1
{
public class Service1 : IService1, IService2
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
public CompositeType GetDataUsingDataContract(CompositeType composite)
{
if (composite.BoolValue)
{
composite.StringValue += "Suffix";
}
return composite;
}
public void DoWork()
{
Service2Reference.IService2 svc = null;
try
{
svc = new Service2Reference.Service2Client();
svc.DoWork();
}
finally
{
if (svc != null)
{
((IDisposable)svc).Dispose();
}
}
}
}
}