C# 为什么可以在WCF服务中公开私有方法?
为什么我们可以将[C# 为什么可以在WCF服务中公开私有方法?,c#,wcf,.net-4.5,C#,Wcf,.net 4.5,为什么我们可以将[OperationContract]属性放在wcf服务中的私有方法上。从我开始编程的那天起,我就被教会了一些私人方法,这些方法在课堂外是无法使用的。现在在WCF服务中,您可以公开私有方法 [ServiceContract] public class MyServices { [OperationContract] private int add(int a,int b) { retu
OperationContract
]属性放在wcf服务中的私有方法上。从我开始编程的那天起,我就被教会了一些私人方法,这些方法在课堂外是无法使用的。现在在WCF服务中,您可以公开私有方法
[ServiceContract]
public class MyServices
{
[OperationContract]
private int add(int a,int b)
{
return a + b;
}
}
不知道为什么它是这样设计的,但如果你检查来源,第336行说
internal const BindingFlags ServiceModelBindingFlags=BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance代码>
请特别注意非公开标志。然后,当WCF使用反射来确定要公开哪些方法时,将在第678行使用此选项:
static List<MethodInfo> GetMethodsInternal(Type interfaceType)
{
List<MethodInfo> methods = new List<MethodInfo>();
foreach (MethodInfo mi in interfaceType.GetMethods(ServiceModelBindingFlags))
{
if (GetSingleAttribute<OperationContractAttribute>(mi) != null)
{
methods.Add(mi);
}
...
静态列表GetMethodsInternal(类型interfaceType)
{
列表方法=新列表();
foreach(interfaceType.GetMethods(ServiceModelBindingFlags)中的MethodInfo mi)
{
如果(GetSingleAttribute(mi)!=null)
{
方法:添加(mi);
}
...
我同意你的看法,这是一个奇怪的决定,但WCF开发者明确决定通过加入非公开标志来实现这一点
发现它可以工作很有趣。当然,您可以使用私有访问修饰符来拒绝类的使用者访问标记的成员。但是WCF将您标记为OperationContract
属性的每个方法公开给public。正如Robert Levy所发现的,它是以这种方式实现的。类似地,您可以在这方面找到一些信息,特别是嗯
当您检查时,您可能会注意到他们在私有方法上使用OperationContract属性。但这似乎是一个输入错误,因为类必须实现其接口的方法
无论如何,对于开发人员来说,最安全的方法是在服务类接口中使用ServiceContract
和OperationContract
属性,例如:
[ServiceContract]
public interface IMyService
{
[OperationContract]
string GetData();
}
public class MyService : IMyService
{
public string GetData() { ... }
private string ComputeData() { ... } // this one is not visible to clients
}
2美分:
WCF使用的SOAP不遵循C#的OOPs概念。另一个“异常”是方法重载,这是一个非常有用且广泛使用的C#特性。虽然我们可以重载服务类中的方法,但我们不能有两个同名的OperationContract(即使签名不同),这意味着我们不能在SOAP上公开重载方法。这样,它将表明,由于作用域说明符不是SOAP特性,WCF将忽略它,并通过OperationContract和DataMember属性来决定契约
以下内容也将作为DataContract的DataMember公开:
[DataMember]
private int _personAge;
您可以使用此属性标记您的方法,但它对服务客户端不可见。您是否确认该属性实际上可以通过WCF调用?(可能是-我没有尝试过)。从根本上说,不能说“此属性只能应用于公共成员”@JohnSaunders是的,没错。我刚刚创建了新的WCF服务项目,删除了IService1接口,并将所有协定属性移动到类定义中。然后我添加了新的私有方法,并将其标记为OperationContract。然后我创建了新的控制台应用程序,向我的WCF服务添加了服务引用,私有方法也被发现我成功地从控制台应用程序调用了私有方法。WCF服务托管在本地IIS Express上。问题可能不是你为什么可以这样做,而是你为什么要这样做。你是程序员,只是不要在你的私有方法上使用该属性。除了Patrick说的,你应该使用using服务协定接口并将属性放置在接口方法上。创建没有接口的服务会强制您使用有其自身问题的服务引用Robert,对于那些问题不明显的人,您应该解释WCF通过Reflection@JohnSaunders-作出调整