我已经使用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
答案 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只是告诉客户端它需要哪些属性及其类型..实现取决于客户端。