.net WCF:公开不带集合的只读DataMember属性?
我有一个服务器端类,可以通过[DataContract]在客户端使用它。这个类有一个只读字段,我想通过属性使其可用。但是,我无法这样做,因为似乎不允许我在没有get和set的情况下添加[DataMember]属性 那么-有没有一种不使用setter就拥有[DataMember]属性的方法.net WCF:公开不带集合的只读DataMember属性?,.net,wcf,readonly,datacontract,datamember,.net,Wcf,Readonly,Datacontract,Datamember,我有一个服务器端类,可以通过[DataContract]在客户端使用它。这个类有一个只读字段,我想通过属性使其可用。但是,我无法这样做,因为似乎不允许我在没有get和set的情况下添加[DataMember]属性 那么-有没有一种不使用setter就拥有[DataMember]属性的方法 [DataContract] class SomeClass { private readonly int _id; public SomeClass() { .. } [Data
[DataContract]
class SomeClass
{
private readonly int _id;
public SomeClass() { .. }
[DataMember]
public int Id { get { return _id; } }
[DataMember]
public string SomeString { get; set; }
}
或者该解决方案将使用[DataMember]作为字段-(如图所示)?也尝试过这样做,但似乎不关心字段是否为只读
编辑:这是通过这样的黑客攻击来创建只读属性的唯一方法吗?(不-我不想这样做…)
在使用类实现契约之前定义服务契约(接口)。将DataMember属性放在字段而不是属性上 记住,WCF不知道封装。封装是一个OOP术语,而不是SOA术语 也就是说,请记住,该字段对于使用您的类的人是只读的-任何使用该服务的人都可以完全访问该字段。您的“服务器端”类实际上不会“提供给”客户端 发生的情况是:基于数据契约,客户机将从服务的XML模式中创建一个新的独立类。它本身不能使用服务器端类 它将根据XML模式定义重新创建一个新类,但该模式不包含任何特定于.NET的内容,如可见性或访问修饰符—毕竟,它只是一个XML模式。客户端类的创建方式将使其在线路上具有相同的“封装外形”——例如,它基本上序列化为相同的XML格式 无法通过标准的基于SOAP的服务“传输”.NET特定的类专有技术-毕竟,您传递的都是序列化消息-没有类 勾选“SOA的四个原则”(由微软的Don Box定义):
请参阅第3点-服务共享模式和契约,而不是类-您只共享数据契约的接口和XML模式-仅此而已-没有.NET类。我想将服务层中的类中的一些属性传递给Silverlight。我不想创建一个全新的类 不是真正的“推荐”,但这似乎是将
Total
属性传递给silverlight(仅用于可视化数据绑定)的两个缺点中较小的一个
有一种方法可以实现这一点。但请注意,它直接违反了本节中引用的以下原则: 3.服务共享架构和协定,而不是类 如果这一违规行为与您无关,您可以这样做:
SomeService.Contracts
)这是定义不可变的[DataContract]
类的方式:
namespace SomeService.Contracts
{
[DataContract]
public sealed class Foo
{
public Foo(int x)
{
this.x = x;
}
public int X
{
get
{
return x;
}
}
[DataMember] // NB: applied to the backing field, not to the property!
private readonly int x;
}
}
请注意,[DataMember]
应用于支持字段,而不是相应的只读属性SomeService.Web
)和客户机项目(我的称为SomeService.client
)中引用合同程序集。这可能会导致解决方案中存在以下项目依赖关系:
SomeService.Contracts
)将包含在以下内容中:
Foo
类型,而是从您的合约程序集中重用不可变的Foo
类型
最后一个警告:您已经偏离了中引用的服务原则。但是不要再迷路了。您可能会开始向数据契约类添加(业务)逻辑;不要。它们应该尽可能地靠近哑数据传输对象(DTO)。啊,是的-正如我所说的,我尝试将字段设置为DataMember,但在客户端它没有显示为只读。但是没有办法让它在客户端成为只读的吗?没有。只读是一个C#术语,而不是SOA。您不能使XML成为ReadOnlyTanks的一部分。这似乎是除了创建特定于数据的类之外的最佳选择。。。对于小型应用程序来说,这就是太多的额外代码。你是什么意思?DataMember位于通过DataContract可用的DTO类中。我也有一份服务合同,但这在这里并没有真正的关系-是吗?这是一份数据合同,而不是一份解释得很好的服务合同。谢谢你的澄清!这些信息很好,但我不认为它直接回答了问题。所有这些都说明了目前的情况是多么荒谬。既然服务器端类只用于生成契约,为什么需要setter?如果不是因为DataContractSerializer是prissy,服务器上的实例可以在没有它们的情况下对客户端进行序列化。只有相反的情况才会导致问题。同意@atoumey。Marc,你能详细说明一下OP问题的可能解决方案吗?我在这个解决方案中看到的问题是,因为不能同时使用ISerializable和DataContract,DataContract还定义了序列化。如果您尝试序列化此对象,它将在反序列化期间引发异常。因此,与抛出异常相比,黑客明智地选择no op似乎是唯一的选择。在这种情况下,将“Total”实现为扩展方法效果很好(我知道扩展方法可能没有
public class PricingSummary
{
public int TotalItemCount { get; set; } // doesnt ideally belong here but used by top bar when out of store area
public decimal SubTotal { get; set; }
public decimal? Taxes { get; set; }
public decimal Discount { get; set; }
public decimal? ShippingTotal { get; set; }
public decimal Total
{
get
{
return + SubTotal
+ (ShippingTotal ?? 0)
+ (Taxes ?? 0)
- Discount;
}
set
{
throw new ApplicationException("Cannot be set");
}
}
}
namespace SomeService.Contracts
{
[DataContract]
public sealed class Foo
{
public Foo(int x)
{
this.x = x;
}
public int X
{
get
{
return x;
}
}
[DataMember] // NB: applied to the backing field, not to the property!
private readonly int x;
}
}