Reputation: 15282
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?).
Upvotes: 6
Views: 335
Reputation: 4234
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.
Upvotes: 1