I have the following code:
[ServiceContract(Name = "Save{0}")]
public ISave<T> where T : BusinessObject
{
[OperationContract(Name = "Save")]
void Save(T obj);
}
public class SaveCustomer : ISave<Customer>
{
public void Save(Customer obj) { ... }
}
The problem I have is that my WCF app using IIS/WAS does not like the name I gave. It doesn't automatically fill it in. I saw this stackoverflow question, which has answers as to why the names don't automatically format. Instead of waiting for Microsoft to allow for formatted names, I was seeing if I could replace the functionality that gets the name with my own.
I'm just unsure of which class I need to extend (ServiceHost
, ServiceHostFactory
, DataContractSerializer
, etc.), or even what method I have to override to get a more friendly name. Also, since I don't even know what class I have to create, I have no idea where I could tell my app to use it (Global.asax member? svc file? attribute?).
The answer seems to be that this is not really needed. It appears that service names are created by convention. If you change your code accordingly:
[ServiceContract] // No use of the 'Name' property
public ISave<T> where T : BusinessObject
{
[OperationContract(Name="Save")]
void Save(T obj);
}
public class SaveCustomer : ISave<Customer>
{
public void Save(Customer obj) { /* Do stuff here */ }
}
then the resulting configuration should be similar to the following in the web.config
file (assuming a basicHttpBinding
):
<service name="SaveCustomer">
<endpoint
address="http://localhost:8001/SaveCustomer/"
binding="basicHttpBinding"
contract="ISave`1[[FullyQualifiedNamespaceTo.Customer, AssemblyName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=....]]"
/>
</service>
I found this here in the comments to the accepted answer. Obviously, you need to provide your own Assembly Name, Version, Culture, and PublicKeyToken. If you don't have a PublicKeyToken, I believe you can leave it off.
So, it appears that by declaring the ServiceContractAttribute
on your ISave<T>
interface, then implementing that interface in a class called SaveCustomer
results in a service named SaveCustomer
(which is what I believe you were after). Though you may have to fiddle with the syntax used for generic types when specified in web.config
files.
So, if you had another service class, e.g.:
public class SaveOrder : ISave<Order>
{
public void Save(Order obj) { /* Do stuff here */ }
}
then you should end up with another service endpoint configuration:
<service name="SaveOrder">
<endpoint
address="http://localhost:8001/SaveOrder/"
binding="basicHttpBinding"
contract="ISave`1[[FullyQualifiedNamespaceTo.Order, AssemblyName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=....]]"
/>
</service>
HTH.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With