本文介绍了操作带有所需参数的合同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
正如约翰·桑德斯(John Saunders)(MVP)所建议的那样,我以不同的方式重新发布了我原来的问题/问题/增强请求.已经开始使用我们的WCF服务(通过wsHttpBinding/basicHttpBinding公开)的客户抱怨:为什么在大多数情况下,所有服务中的所有参数实际上都不是可选的?"例如,假设有一个这样的服务:
As suggested by John Saunders (MVP), I'm reposting my original problem/question/enhancement-request in a different way. Our customers who have started using our WCF services (exposed via wsHttpBinding/basicHttpBinding) complain, "Why are all parameters in all of your services declared as optional when most of the times they really aren't?" For example, let's say there is a service like this:
推荐答案
public class Post_e707ed20_c09c_4e26_927a_7c3071d74ed7
{
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)]
public class RequiredDataParameterAttribute : Attribute { }
[ServiceContract]
public interface ITest
{
[OperationContract]
int Transfer(
[RequiredDataParameter] int SourceAccount,
[RequiredDataParameter] int TargetAccount,
[RequiredDataParameter] double Amount);
}
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class Service : ITest
{
public int Transfer(int SourceAccount, int TargetAccount, double Amount)
{
return 1;
}
}
class MyParamInspector : IParameterInspector
{
private bool[] required;
private string[] paramNames;
public MyParamInspector(OperationDescription operationDescription)
{
MethodInfo method = operationDescription.SyncMethod;
ParameterInfo[] parameters = method.GetParameters();
this.required = new bool[parameters.Length];
this.paramNames = new string[parameters.Length];
for (int i = 0; i < this.required.Length; i++)
{
this.paramNames[i] = parameters[i].Name;
object[] attrs = parameters[i].GetCustomAttributes(typeof(RequiredDataParameterAttribute), true);
this.required[i] = attrs != null && attrs.Length > 0;
}
}
public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState)
{
}
public object BeforeCall(string operationName, object[] inputs)
{
Debug.Assert(this.required.Length == inputs.Length);
for (int i = 0; i < this.required.Length; i++)
{
if (this.required[i] && inputs[i] == null)
{
throw new ArgumentException("Required parameter " + this.paramNames[i] + " is not present in the request");
}
}
return null;
}
}
class MyOperationBehavior : IOperationBehavior
{
public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters) { }
public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation) { }
public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
{
dispatchOperation.ParameterInspectors.Add(new MyParamInspector(operationDescription));
}
public void Validate(OperationDescription operationDescription) { }
}
static Binding GetBinding()
{
BasicHttpBinding result = new BasicHttpBinding();
return result;
}
public static void Test()
{
string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(ITest), GetBinding(), "");
foreach (OperationDescription operation in endpoint.Contract.Operations)
{
operation.Behaviors.Add(new MyOperationBehavior());
}
host.Open();
Console.WriteLine("Host opened");
ChannelFactory<ITest> factory = new ChannelFactory<ITest>(GetBinding(), new EndpointAddress(baseAddress));
ITest proxy = factory.CreateChannel();
Console.WriteLine(proxy.Transfer(1, 2, 23.45));
((IClientChannel)proxy).Close();
factory.Close();
Console.Write("Press ENTER to close the host");
Console.ReadLine();
host.Close();
}
}
这篇关于操作带有所需参数的合同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!