1

我使用返回 List 的 ServiceStack 创建了一个 Web 服务<SyncUserDTO>。它有更多属性,但我将其简化为一个字段,时间戳。

[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”,没有任何结果可以帮助我完成这个任务......

pps。Demis (ServiceStack),如果你正在阅读这篇文章,是的,SOAP 即将淘汰,REST 是新的黑色——但我想同时支持这两者,看起来 ServiceStack 确实如此,这真的很棒。我喜欢 ServiceStack :D

4

3 回答 3

1

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

private TimestampDTO  _timestamp;
public TimestampDTO Timestamp 
{
    get
    {
       if(_timestamp==null) _timestamp=new TimestampDTO();
       return _timestamp;
    }
    set
    {
       _Timestamp=value;
     }
}
于 2013-10-18T13:52:05.387 回答
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 会更好。

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

顺便说一句 - 这种设计有任何安全问题吗?用户通过 url-credentials 登录(应该是 header 认证),只有少数系统可以访问它。

于 2013-10-25T08:23:37.113 回答
0

代理类不保留实现细节,如构造函数。它只是一个 DTO。只有通过共享项目共享课程才能做到这一点。

想想那个 servicestack 只是告诉客户端它需要哪些属性,以及它们的类型.. 实现取决于客户端。

于 2013-10-22T13:11:00.963 回答