所以其他人是对的,属性本身没有任何作用。它只是您必须在服务调用生命周期中的某个时间点有意获取的元数据。
最好的方法是添加检查器和服务行为,它是自动完成的,并不总是直接在每个操作中完成。最初设置的工作量更大,但它可以从您的直接操作代码中获取,并可以使其应用于任何操作以检查该自定义属性。
基本上你有这样的属性:
namespace MyCustomExtensionService
{
public class UserAccessAttribute : System.Attribute
{
private string _userRole;
public UserAccessAttribute(string userRole)
{
_userRole = userRole;
//you could also put your role validation code in here
}
public string GetUserRole()
{
return _userRole;
}
}
}
然后你设置你的参数检查器(注意你可以使用其他检查器):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.Web;
namespace MyCustomExtensionService
{
public class MyParameterInspector : IParameterInspector
{
public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState)
{
//throw new NotImplementedException();
}
public object BeforeCall(string operationName, object[] inputs)
{
MethodInfo method = typeof(Service1).GetMethod(operationName);
Attribute[] attributes = Attribute.GetCustomAttributes(method, typeof(UserAccessAttribute), true);
var attr = (UserAccessAttribute)attributes.First();
if (attributes.Any())
{
var userHasProperAuthorization = true;
if (attr.GetUserRole() == "Residents" && userHasProperAuthorization)
{
//everything is good, continue to operation
}
else
{
throw new FaultException("You do not have the right security role!");
}
}
return null;
}
}
}
然后设置端点行为(您可以使用其他行为):
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.Web;
namespace MyCustomExtensionService
{
public class MyCustomAttributeBehavior : IEndpointBehavior
{
public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
//throw new NotImplementedException();
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
{
foreach (ClientOperation clientOperation in clientRuntime.Operations)
{
clientOperation.ParameterInspectors.Add(
new MyParameterInspector());
}
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
{
foreach (DispatchOperation dispatchOperation in endpointDispatcher.DispatchRuntime.Operations)
{
dispatchOperation.ParameterInspectors.Add(
new MyParameterInspector());
}
}
public void Validate(ServiceEndpoint endpoint)
{
//throw new NotImplementedException();
}
}
}
然后你创建你的行为部分:
using System.Linq;
using System.ServiceModel.Configuration;
using System.Web;
namespace MyCustomExtensionService
{
public class MyBehaviorSection : BehaviorExtensionElement
{
protected override object CreateBehavior()
{
return new MyCustomAttributeBehavior();
}
public override Type BehaviorType
{
get { return typeof(MyCustomAttributeBehavior); }
}
}
}
然后设置配置以使用新行为:
<system.serviceModel>
<services>
<service name ="MyCustomExtensionService.Service1">
<endpoint address="" behaviorConfiguration="MyCustomAttributeBehavior"
binding="basicHttpBinding" contract="MyCustomExtensionService.IService1">
</endpoint>
</service>
</services>
<extensions>
<behaviorExtensions>
<add name="Validator" type="MyCustomExtensionService.MyBehaviorSection, MyCustomExtensionService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</behaviorExtensions>
</extensions>
<behaviors>
<endpointBehaviors>
<behavior name="MyCustomAttributeBehavior">
<Validator />
</behavior>
</endpointBehaviors>
这是服务界面 - 一项操作将起作用,另一项操作因用户访问权限错误而失败
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace MyCustomExtensionService
{
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetData(int value);
[OperationContract]
string GetDataUsingWrongUserAccess(int value);
}
}
以及服务运营:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace MyCustomExtensionService
{
public class Service1 : IService1
{
[UserAccess("Residents")]
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
[UserAccess("Admin")]
public string GetDataUsingWrongUserAccess(int value)
{
return string.Format("You entered: {0}", value);
}
}
}
有关详细信息,请参阅 MSDN http://msdn.microsoft.com/en-us/library/ms730137.aspx
也适用于检查员:https ://github.com/geersch/WcfParameterInspectors