【问题标题】:Using the same method to PUT and POST使用相同的方法来 PUT 和 POST
【发布时间】:2013-08-03 04:28:43
【问题描述】:

我正在开发 WCF 休息服务,我的 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);

我将使用User AddOrUpdateUser(User user);POSTPUT

    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;
    }

我正在关注这个pattern 来做这件事。

但是,我得到一个错误:

The type 'MyCompanyWCFService.IMyCompanyService' already contains a definition for 
'AddOrUpdateUser' with the same parameters

我该如何解决这个问题?

【问题讨论】:

标签: c# wcf


【解决方案1】:

您不能有两个具有相同签名的方法 - 这是 C# 问题,而不是 WCF 问题。你基本上有两个选择去这里。第一种是有两个不同的方法,一个调用另一个,或者两个都调用第三种方法):

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);
}

以及实现:

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;
    }
}

另一种选择是使用一个接受多个 HTTP 方法的单一方法;您可以通过在 WebInvoke 属性上指定 Method = "*" 来做到这一点。但是如果你走这条路,你应该在操作中验证传入的 HTTP 动词是你期望的动词之一:

public interface ITest
{
    [OperationContract]
    [WebInvoke(Method = "*",
        UriTemplate = "/users",
        RequestFormat = WebMessageFormat.Json,
        ResponseFormat = WebMessageFormat.Json,
        BodyStyle = WebMessageBodyStyle.Bare)]
    User AddOrUpdateUser(User user);
}

以及实现:

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;
    }
}

【讨论】:

    猜你喜欢
    • 2018-02-20
    • 1970-01-01
    • 2015-02-13
    • 1970-01-01
    • 2017-02-17
    • 1970-01-01
    • 1970-01-01
    • 2017-11-08
    • 1970-01-01
    相关资源
    最近更新 更多