WCF:在许多方法上都是相同的

WCF:在许多方法上都是相同的,wcf,operationcontract,faultcontract,Wcf,Operationcontract,Faultcontract,以一个项目为例,每个项目有10个服务和20个方法 所有服务都继承自具有安全检查的基本服务。每个方法做的第一件事是调用安全检查。如果出现问题,将引发安全异常 问题是:我是否需要在每个方法(OperationContract)上指定一个FaultContract,还是可以在一个中心定义中指定一次?在每个操作契约上都指定一个FaultContract?否,您需要在每个方法上都指定一个FaultContract-WCF非常挑剔,几乎所有内容都需要显式设置(我相信这最终确实是件好事) Marc您可以通过创

以一个项目为例,每个项目有10个服务和20个方法

所有服务都继承自具有安全检查的基本服务。每个方法做的第一件事是调用安全检查。如果出现问题,将引发安全异常


问题是:我是否需要在每个方法(OperationContract)上指定一个FaultContract,还是可以在一个中心定义中指定一次?

在每个操作契约上都指定一个FaultContract?

否,您需要在每个方法上都指定一个FaultContract-WCF非常挑剔,几乎所有内容都需要显式设置(我相信这最终确实是件好事)


Marc

您可以通过创建自定义属性来实现

实现IContractBehavior并将故障添加到Validate方法上的每个操作中

void IContractBehavior.Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
{
   foreach (OperationDescription od in contractDescription.Operations)
      od.Add(yourFault);
}
下面详细介绍了如何实现这一点。下面是实际使用的代码:

[AttributeUsage(AttributeTargets.Interface, AllowMultiple = false, Inherited = true)]
public class StandardFaultsAttribute : Attribute, IContractBehavior
{
    // this is a list of our standard fault detail classes.
    static Type[] Faults = new Type[]
    {
        typeof(AuthFailure),
        typeof(UnexpectedException),
        typeof(UserFriendlyError)
    };

    public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
    }

    public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
    }

    public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
    {
    }

    public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
    {
        foreach (OperationDescription op in contractDescription.Operations)
        {
            foreach (Type fault in Faults)
            {
                op.Faults.Add(MakeFault(fault));
            }
        }
    }

    private FaultDescription MakeFault(Type detailType)
    {
        string action = detailType.Name;
        DescriptionAttribute description = (DescriptionAttribute)                Attribute.GetCustomAttribute(detailType, typeof(DescriptionAttribute));

        if (description != null)
            action = description.Description;
        FaultDescription fd = new FaultDescription(action);
        fd.DetailType = detailType;
        fd.Name = detailType.Name;
        return fd;
    }
}

你肯定会同意,应该可以以正交的方式实现交叉关注点,如安全性。我觉得奇怪的是,我可以以解耦的方式实现一个漂亮的
ServiceAuthorizationManager
,但如果我想抛出一个自定义的安全错误,我必须用重复的垃圾来散布我的合同。我同意,我也在寻找一种自动处理重复垃圾的方法。你可以编写一些T4来从XML(或其他)文件生成所有合同,并使用自定义逻辑来定义全局错误。codeplex上还有一个项目,它使用合同设计器并生成客户机/服务器代码(这是一个相当繁重的工具).1这确实有帮助。通过这种方式,1属性可以应用于ServiceContract接口级别,而不是应用于接口中的每个单独方法。我同意,这应该被标记为答案。这对我来说非常有用,至少对于一个也使用WCF的客户来说是如此。