未在使用“添加服务引用”的代理类中创建构造函数

时间:2013-10-18 11:32:24

标签: asp.net-mvc constructor servicestack service-reference

我已经使用ServiceStack创建了一个Web服务,它返回List <SyncUserDTO>。 它有更多的属性,但我把它简化为一个字段,Timestamp。

[DataContract]
public class SyncUserDTO
{
    public SyncUserDTO()
    {
        Timestamp = new TimestampDTO();
    }

    [DataMember(Order = 1)]
    public TimestampDTO Timestamp { get; set; }
}

[DataContract]
public class TimestampDTO
{
    [DataMember]
    public bool DataValid { get; set; }
    [DataMember]
    public DateTime? Value { get; set; }
}

该服务似乎完美(与其他测试),但是当我创建客户端控制台应用程序和添加服务引用时,SyncUserDTO没有构造函数,这意味着这不起作用:

static void SendUsersServiceReference()
{
    var users = new List<SyncUserDTO>();
    for (var i = 0; i < 5; i++) 
    {
        var user = new SyncUserDTO();

        user.Timestamp.Value = DateTime.Now;  // NullReferenceException, 
        user.Timestamp.DataValid = true;      //   as Timestamp is null
    }
}

在SyncUserDTO上按F12时,我似乎无法在Reference.cs中找到任何Constructor方法,解释了为什么上述方法不起作用。

但是为什么构造函数不是在客户端应用程序的代理类中创建的?

我需要在客户端自己做“构建”,然后才能工作:

       var user = new SyncUserDTO() { Timestamp = new TimestampDTO() };

原因是,我不希望消耗我服务的人必须自己创建。他们应该注意关注底层的TimestampDTO。构造函数应该这样做。

顺便说一句,我在Google和SO上搜索了“使用和不使用ServiceStack”在“使用添加服务参考的代理类中创建的构造函数”这样的术语,没有任何结果可以帮助我完成此任务......

Ps,裸露在我身边,这是我的第一个问题:)请告诉我在这个问题上有什么改进。

PPS。 Demis(ServiceStack),如果你正在读这篇文章,那么SOAP正在逐渐消失,REST是新的黑色 - 但我想支持两者,这似乎是ServiceStack所做的,这真的很棒。我喜欢ServiceStack:D

3 个答案:

答案 0 :(得分:1)

尝试在您访问它时实例化您的属性,我知道这是一种解决方法,但在您的方案中可能很方便。

private TimestampDTO  _timestamp;
public TimestampDTO Timestamp 
{
    get
    {
       if(_timestamp==null) _timestamp=new TimestampDTO();
       return _timestamp;
    }
    set
    {
       _Timestamp=value;
     }
}

答案 1 :(得分:1)

这是我的解决方案(暂时):

我在我的服务中创建了一个新的服务方法,客户端获得了一个包含所有字段的新UserDTO。这样,构造函数就在服务器上运行。我敢打赌,我的表现非常受欢迎,但这并不重要(现在......)。

服务DTO:

[DataContract]
public class ReturnNewEmptyUser : IReturn<ReturnNewEmptyUserResponse> {}
[DataContract]
public class ReturnNewEmptyUserResponse
{
    [DataMember]
    public SyncUserDTO User { get; set; }
}

服务:

public class SyncService : Service
{
    public ReturnNewEmptyUserResponse Any(ReturnNewEmptyUser request)
    {
        var user = new ReturnNewEmptyUserResponse { User = new SyncUserDTO() };
        return user;
    }
}

在客户端:

    static void SendUsersServiceReference()
    {
        var webservice = new ServiceReference1.SyncReplyClient();

        var users = new List<User>();
        for (var i = 0; i < 5; i++)
        {
            var userResponse = webservice.ReturnNewEmptyUser(new ReturnNewEmptyUser());
            var user = userResponse.User;

            user.Timestamp.Value = DateTime.Now;
            user.Timestamp.DataValid = true;
            // Continue with field population...

            users.Add(user);
        }

        // Send users with webservice method
        // ...
    }

我们想知道以这种方式公开字段是否是一种糟糕的方式。这很好,因为客户端可以使用自动完成并确切地知道所使用的类型 - 但最好是强制客户端以特定格式创建XML / JSON。

这应该是另一个问题 - 我猜这个问题已经得到解答:添加服务引用/代理类不包含方法(包括类型的构造函数),只包含类型。如果您确实需要构造函数,请让它运行然后在服务器上公开,然后从客户端使用它。就像工厂里的东西一样,正如亚当在这里写的那样:Class constructor (from C# web service) won't auto-implement properties in C# MVC

Btw - 这个设计有任何安全问题吗?用户通过url-credentials登录(可能应该是头部身份验证),只有少数系统可以访问它。

答案 2 :(得分:0)

代理类不会像构造函数那样保留实现细节。它只是一个DTO。只有通过共享项目共享类才能执行此操作。

考虑一下servicestack只是告诉客户端它需要哪些属性及其类型..实现取决于客户端。