WCF: тот же Faultcontract для многих методов
возьмите, например, проект с 10 службами и 20 методами для каждой службы.
все службы наследуются от базовых служб, которые имеют проверку безопасности. Первое, что делает каждый метод, это сделать вызов проверки безопасности. Это бросает исключение безопасности, если есть проблема.
вопрос: нужно ли указывать FaultContract для каждого метода (OperationContract), или я могу сделать это один раз в Центральном определении?
3 ответов
нет, вам нужно сделать это на каждом методе - WCF довольно придирчив и требует явных настроек в значительной степени для всего (что действительно хорошо, я убежден).
Марк
вы можете сделать это, создав пользовательский атрибут.
реализуйте 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;
}
}