I have created a WCF service and my interface looks like below:-
[ServiceContract]
public interface IService1
{
[OperationContract(Action = "GetData")]
CompositeType GetDataUsingDataContract(CompositeType composite);
}
here i am using Action name and when i am generating WSDL from this service i am getting operation name like below :
but when i am using wildcard for action like below :
[ServiceContract]
public interface IService1
{
[OperationContract(Action = "*")]
CompositeType GetDataUsingDataContract(CompositeType composite);
}
here i am not getting operation name in my WSDL.
My question is that how can i use wildcard by generating operation name in WSDL. Please help me to solve this issue or give me suggestions for achieving this.
You can only use [OperationContract(Action = "*")] if your service operation takes a Message object and returns a Message object or void.
See the MSDN documentation for OperationContractAttribute.Action Property
Related
I have a very strange and obscure issue with WCF services that I was hoping to get some insight on:
I am working a WCF service that we are building to replace one that we no longer have source code for. For some reason, in the new WCF service, everything is forced through a single paramater called "request". Using the WCF test client, this is what it looks like
On the "correct" service, this is what it looks like:
Is there any reason why this would be happening? I've defined all of the requests as follows:
[ServiceContract]
public interface IMyService
{
[OperationContract]
string SomeRequest();
}
Which seems correct, but there may be something I've overlooked that is causing this.
In your original WCF service, there is a request function parameter, and it has a definition similar to the following:
[ServiceContract]
public interface IMyService
{
[OperationContract]
Request SomeRequest(Request request);
}
[DataContract]
public class Request
{
string documentId;
[DataMember]
public string DocumentId
{
get { return documentId; }
set { documentId = value; }
}
}
In the new wcf service:
[ServiceContract]
public interface IMyService
{
[OperationContract]
string SomeRequest(string documentId);
}
So this is because the function parameters are different. Originally your parameter was class, but later changed to string, so the display in WCFTestClient is different.
My interface look like this:
[ServiceContract]
public interface IMyService
{
[OperationContract]
myConnectedService.SomeComplexResponseType someMethod(myConnectedService.SomeComplexRequestType request);
}
My implementation look like this:
public class MyService : IMyService
{
myConnectedService_client client = new myConnectedService_client();
public myConnectedService.SomeComplexResponseType someMethod(myConnectedService.SomeComplexRequestType request)
{
myConnectedService.SomeComplexResponseType response = client.connectedServiceMethod(request);
return response ;
}
}
The error i get when i am trying to run my service:
Failed to add a service. Service metadata may not be accessible. Make sure your service is running and exposing metadata.
and
error CS0644: 'System.ComponentModel.PropertyChangedEventHandler' cannot derive from special class 'System.MulticastDelegate'
Is there any way to restrict Operation to only available to REST consumers and not to SOAP consumers?
For example:
[OperationContract]
List<Response> GetResponses(int orderID);
[OperationContract]
[WebGet(UriTemplate = "{orderID}/responses",
ResponseFormat = WebMessageFormat.Json)]
List<Response> GetResponses(string orderID);
While REST consumers can only tackle second method, SOAP consumers see both methods, but in any case they should use first method. So I want to show first method to SOAP consumers only and second to REST consumers only. Can I achieve my goal without creating new service?
What you can do is to separate contracts, one for the SOAP exposed, second for the REST exposed, and then make your service implement both :
SOAP contract
[ServiceContract]
public interface IDummySoap
{
[OperationContract]
List<Response> GetResponses(int orderID);
}
REST contract
[ServiceContract]
public interface IDummyRest
{
[OperationContract]
[WebGet(UriTemplate = "{orderID}/responses",
ResponseFormat = WebMessageFormat.Json)]
List<Response> GetResponses(string orderID);
}
Service implementation
public class DummyService : IDummySoap, IDummyRest
{
public List<Response> GetResponses(int orderID)
{
// Implementation
}
public List<Response> GetResponses(string orderID)
{
// Implementation
}
}
Then those who want to call your service by SOAP will use the SOAP contract and the others the REST contract.
I have a strange problem I have been pulling my hair out over. I am trying to create a TFS event handler service in WCF, and part of the requirement is to generate a SOAP 1.2 envelope with specific namespaces and actions.
The basic interface looks like this:
[ServiceContract(Namespace="http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03")]
public interface ITfsNotificationService
{
[OperationContract(Action="http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03/Notify", ReplyAction="*")]
[XmlSerializerFormat(Style = OperationFormatStyle.Document)]
void Notify(string eventXml, string tfsIdentityXml, SubscriptionInfo SubscriptionInfo);
}
However, when I attempt to access this service with the WcfTestClient I get an error, as well as no Methods show up in the interface:
The contract 'ITfsNotificationService' in client configuration does not
match the name in service contract, or there is no valid method in this
contract.
However, if I remove the action property from the operation contract, it runs fine (but will have the wrong Action method, which includes the interface name) and without any error. Clearly the error is referring to the second half of the message (Or there is no valid method in this contract)
When I look at the generated WSDL, there are no operation elements generated when using the action property, but there is when I just specify an empty [OperationContract].
Any clues as to what I'm doing wrong here?
FYI, this is based on the sample here: http://www.ewaldhofman.nl/post/2010/08/02/how-to-use-wcf-to-subscribe-to-the-tfs-2010-event-service-rolling-up-hours.aspx
I was curious about this, so I've tried here and worked.
Here is what I did:
[ServiceContract(Namespace = "http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03")]
public interface ITfsNotificationService
{
[OperationContract(Action = "http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03/Notify", Name = "Notify", ReplyAction = "http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03/ResponstToNotify")]
[XmlSerializerFormat(Style = OperationFormatStyle.Document)]
void Notify(string eventXml, string tfsIdentityXml, SubscriptionInfo SubscriptionInfo);
}
[ServiceBehavior(Namespace = "http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03")]
public class Service1 : ITfsNotificationService
{
public void Notify(string eventXml, string tfsIdentityXml, SubscriptionInfo SubscriptionInfo)
{
throw new NotImplementedException();
}
}
Hope it helps.
I am writing a WCF client and am using a ChannelFactory to create my proxy to my Service:
[ServiceContract]
interface Service {
[OperationContract]
void Operation();
}
var proxy = ChannelFactory<MyServiceInterface>.CreateChannel(
new BasicHttpBinding(),
new EndpointAddress("http://localhost:8000/"));
How would I go about getting the SessionID? The proxy only has the basic Object methods as well as the ones defined in MyServiceInterface.
Thank you in advance.
Try this:
In your WCF Service file (.svc) add the following:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class Service1 : IService1
{
public string SessionId()
{
return OperationContext.Current.SessionId;
}
}
In your WCF Service interface add the following:
[ServiceContract(SessionMode = SessionMode.Required)]
public interface IService1
{
[OperationContract]
string SessionId();
}
In your client, do the following:
ChannelFactory<IService1> factory = new ChannelFactory<IService1>(
new WSHttpBinding(), new EndpointAddress("http://localhost:4213/Service1.svc"));
IService1 proxy = factory.CreateChannel();
Console.WriteLine(proxy.SessionId());
((IClientChannel)proxy).Close();
factory.Close();
Console.Read();
By doing this you can get the proxy session created at service side. Just to know, when ((IClientChannel)proxy).Close(); and factory.Close(); were invoked, then proxy will get new session.
It wasn't what I was looking for to make the SessionId() an OperationContract. If, instead of using the ChannelFactory, I created my own proxy by extending ClientBase<>, and that gave me access to the InnerChannel.SessionId property.