I'm developing a WCF Rest Service and I have this on my ServiceContract:
[OperationContract]
[WebInvoke(Method = "POST",
UriTemplate = "/users",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare)]
User AddOrUpdateUser(User user);
[OperationContract]
[WebInvoke(Method = "PUT",
UriTemplate = "/users",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare)]
User AddOrUpdateUser(User user);
I'm going to use User AddOrUpdateUser(User user); to POST and PUT:
public User AddOrUpdateUser(User user)
{
if (user == null)
throw new ArgumentNullException("user", "AddOrUpdateUser: user is null");
using (var context = new AdnLineContext())
{
context.Entry(user).State = user.UserId == 0 ?
EntityState.Added :
EntityState.Modified;
context.SaveChanges();
}
return user;
}
I'm following this pattern to do it.
But, I get an error:
The type 'MyCompanyWCFService.IMyCompanyService' already contains a definition for
'AddOrUpdateUser' with the same parameters
How can I fix this problem?
You cannot have two methods with the same signature - that's a C# issue, not a WCF one. You have basically two choices to go here. The first is to have two different methods, and have one call the other, or have a third method called by both):
public interface ITest
{
[OperationContract]
[WebInvoke(Method = "POST",
UriTemplate = "/users",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare)]
User AddUser(User user);
[OperationContract]
[WebInvoke(Method = "PUT",
UriTemplate = "/users",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare)]
User UpdateUser(User user);
}
And the implementation:
public class Service
{
public User AddUser(User user) { return AddOrUpdateUser(user); }
public User UpdateUser(User user) { return AddOrUpdateUser(user); }
private User AddOrUpdateUser(User user)
{
if (user == null)
throw new ArgumentNullException("user", "AddOrUpdateUser: user is null");
using (var context = new AdnLineContext())
{
context.Entry(user).State = user.UserId == 0 ?
EntityState.Added :
EntityState.Modified;
context.SaveChanges();
}
return user;
}
}
Another alternative would be to have one single method which accepts multiple HTTP methods; you can do that by specifying Method = "*" on the WebInvoke attribute. But if you go that route you should validate, within the operation, that the incoming HTTP verb is one of those you expect:
public interface ITest
{
[OperationContract]
[WebInvoke(Method = "*",
UriTemplate = "/users",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare)]
User AddOrUpdateUser(User user);
}
And the implementation:
public class Service
{
public User AddOrUpdateUser(User user)
{
var method = WebOperationContext.Current.IncomingRequest.Method.ToUpperInvariant();
if (method != "POST" || method != "PUT")
{
throw new WebFaultException(HttpStatusCode.MethodNotAllowed);
}
if (user == null)
throw new ArgumentNullException("user", "AddOrUpdateUser: user is null");
using (var context = new AdnLineContext())
{
context.Entry(user).State = user.UserId == 0 ?
EntityState.Added :
EntityState.Modified;
context.SaveChanges();
}
return user;
}
}
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