Is it necessary for me to write [OperationContract] over every method in my WCF Service? - wcf

For example, is this correct?
[OperationContract]
bool IsHappy(string userID);
bool IsSad(string userID);
bool IsHungry(string userID);
Is that a valid body of operations for a WCF ServiceContract or do I have to do it this way:
[OperationContract]
bool IsHappy(string userID);
[OperationContract]
bool IsSad(string userID);
[OperationContract]
bool IsHungry(string userID);

You must denote every method that you want to expose from the service with [OperationContract]. You are free to have methods without this attribute in your service class but those methods will not be exposed in the service metadata and will not be accessible to the client.
If all three methods are part of the service contract then all three must have an [OperationContract] attribute - your second example is correct.

Related

2 Names the Same in WCF Not possible?

I'm trying to create a RESTful WCF service. I get a runtime error saying you can't have 2 of the same method names in your service class:
[OperationContract, WebGet]
...
string Get();
[OperationContract, WebGet]
...
string Get(int id);
Why in the world can't you! they are both different signatures. If I'm to get this to work like REST like I want, which is to be able to overload stuff like this, then that would suck and WCF is not for me.
Has anyone been able to have 2 of the same method names in your so-called attempt to make WCF restful?
you can override service method by using OperationContract name property with define separate routes.Your service interface should look like
[OperationContract(Name = "GetemployeeName")]
string Get(string param);
[OperationContract(Name = "GetemployeeAge")]
bool Get(long sysID);

Calling a Web Service using WCF channel Factory.Is it possible?

In the project I am working on I need to call webservices (asmx).I would like to call them using wcf and using the channelfactory(No adding service Reference).
Some might have an interface(contract)many dont.
Is there an end to end example how to do it?
var service=ChannelFactory<?>... How do I get the webserviceContract.
Surely this must be a common scenario to be able to call a webservice (asmx)
Thanks for your time
To expand upon my comment, you should be able to create an interface that has methods that match the web service methods in the asmx service. For example:
Web Service Methods
string GetMessage()
void SendMessage(string message)
int AddNumbers(int x, int y)
Service Contract
[ServiceContract]
public interface IServiceName
{
[OperationContract]
string GetMessage();
[OperationContract]
void SendMessage(string message);
[OperationContract]
int AddNumbers(int x, int y)
}
ChannelFactory
ChannelFactory<IServiceName> serviceFactory =
new ChannelFactory<IServiceName>(new BasicHttpBinding(),
"http://www.services.com/Service.asmx");
Not 100% sure this will work, but it would be easy to try out. Also, you'd probably want to set the namespace on the service contract ([ServiceContract(Namespace = "somenamespace")]) to match the legacy asmx service, otherwise the messages might not get processed.

WCF "Avoid property-like operations" rule

The Juval Löwy's "Programing WCF Services" book contains a "WCF Coding Standard" appendix with General Design Guidelines for WCF Services.
One of the guidelines is Avoid property-like operations:
//Avoid property-like operations:
[ServiceContract]
interface IMyContract
{
[OperationContract]
string GetName();
[OperationContract]
void SetName(string name);
}
Could anybody explain what's wrong with having the string GetName(); operation? What if a string value is all I need from an operation?
If a string value is what you need and you will not need anything more then it is absolutely correct. Probably the better example of the anti-pattern is:
[ServiceContract]
interface IMyContract
{
[OperationContract]
void SetFirstName(string firstName);
[OperationContract]
void SetLastName(string lastName);
}
And client calling:
proxy.SetFirstName("Test");
proxy.SetLastName("Test");
This is completely wrong. You should have single operation accepting first and last name.
Generally you should avoid chatty interfaces and reduce number of roundtrips between service and client. So if you know that you will need only name let expose only operation returning the name. But if you know that you will in the same client's business operation need also email expose the operation which will return name and email.

WCF Additional Proxy Classes

I have a WCF webservice that has the following service contract
[ServiceContract(Namespace = "http://example.org")]
public interface IEquinoxWebservice
{
[OperationContract]
Guid Init();
[OperationContract]
List<Message> Dequeue(Guid instanceId);
[OperationContract]
void Enqueue(Guid instanceId, Message message);
[OperationContract]
void Dispose(string instanceId);
}
Message class is an abstract class that is implemented by a bunch of concrete message classes.
I want to make all the concrete message classes available in the client proxy that is generated. Not just the message class.
Is there any way to make them available as types in the webservice so the standard Visual Studio proxy generator will create them?
You need to specify those types. See Data Contract Known Types.

RESTful WCF service that can respond in both JSON(P) and XML and still be used as SOAP web service?

Given a contract such as:
[ServiceContract] public interface IService
{
[OperationContract]
[WebGet(UriTemplate = "GetData/{id}.{format}")]
ResponseData GetData(string id, string format);
}
Is there a way to get the service to respond with json when requested as:
/GetData/1234.json, xml when requested as /GetData/1234.xml and still be available as a proper soap service at some other url, with a strongly typed wsdl contract?
Using a Stream as the return value for GetData is not workable, as though it fufills the first two requirements, wcf can't create a full wsdl specification as it has no idea what the contents of the resultant Stream will be.
You should have two separate methods which take id and format (and they would call a shared implementation that returns ResponseData) which have different WebGet attributes:
[ServiceContract]
public interface IService
{
[OperationContract]
[WebGet(UriTemplate = "GetData/{id}.{format}.xml",
ResponseFormat=WebMessageFormat.Xml)]
ResponseData GetDataXml(string id, string format);
[OperationContract]
[WebGet(UriTemplate = "GetData/{id}.{format}.json",
ResponseFormat=WebMessageFormat.Json)]
ResponseData GetDataJson(string id, string format);
}
For the SOAP endpoint, you should be able to call either method, but you are going to have to have a separate ServiceHost instance hosting the implementation of the contract.