static bool WebAttributesOCEExtender (MethodBase method, object[] customAttributes, ref OperationContractAttribute oca) { int caLength = customAttributes == null ? 0 : customAttributes.Length; if (method == null && caLength == 0) return false; if (caLength == 0) { customAttributes = method.GetCustomAttributes (false); if (customAttributes.Length == 0) return false; } bool foundWebAttribute = false; foreach (object o in customAttributes) { if (o is WebInvokeAttribute || o is WebGetAttribute) { foundWebAttribute = true; break; } } if (!foundWebAttribute) return false; // LAMESPEC: .NET allows for contract methods decorated only with // Web{Get,Invoke}Attribute and _without_ the OperationContractAttribute. if (oca == null) oca = new OperationContractAttribute (); return true; }
public void CreatesCustomOperationContractAttributeWithNoDecoratedMethod() { OperationContractAttribute oca1 = new OperationContractAttribute(); oca1.Name = "MySomeMethod"; se.ObjectName = "CreatesCustomOperationContractAttributeWithNoDecoratedMethod"; se.TargetName = "service"; se.MemberAttributes.Add("SomeMethod", oca1); se.AfterPropertiesSet(); Type proxyType = se.GetObject() as Type; Assert.IsNotNull(proxyType); MethodInfo method = proxyType.GetMethod("SomeMethod"); Assert.IsNotNull(method); object[] attrs = method.GetCustomAttributes(typeof(OperationContractAttribute), true); Assert.IsNotEmpty(attrs); Assert.AreEqual(1, attrs.Length); OperationContractAttribute oca2 = attrs[0] as OperationContractAttribute; Assert.AreEqual(oca1.Name, oca2.Name); }
public static MessageDescription CreateMessageDescription ( OperationContractAttribute oca, ParameterInfo[] plist, string name, string defaultNamespace, string action, bool isRequest, bool isCallback, Type retType, ICustomAttributeProvider retTypeAttributes) { var dir = isRequest ^ isCallback ? MessageDirection.Input : MessageDirection.Output; MessageDescription md = new MessageDescription (action, dir) { IsRequest = isRequest }; MessageBodyDescription mb = md.Body; mb.WrapperName = name + (isRequest ? String.Empty : "Response"); mb.WrapperNamespace = defaultNamespace; if (oca.HasProtectionLevel) md.ProtectionLevel = oca.ProtectionLevel; // Parts int index = 0; foreach (ParameterInfo pi in plist) { // AsyncCallback and state are extraneous. if (oca.AsyncPattern && pi.Position == plist.Length - 2) break; // They are ignored: // - out parameter in request // - neither out nor ref parameter in reply if (isRequest && pi.IsOut) continue; if (!isRequest && !pi.IsOut && !pi.ParameterType.IsByRef) continue; MessagePartDescription pd = CreatePartCore (GetMessageParameterAttribute (pi), pi.Name, defaultNamespace); pd.Index = index++; pd.Type = MessageFilterOutByRef (pi.ParameterType); mb.Parts.Add (pd); } // ReturnValue if (!isRequest) { MessagePartDescription mp = CreatePartCore (GetMessageParameterAttribute (retTypeAttributes), name + "Result", mb.WrapperNamespace); mp.Index = 0; mp.Type = retType; mb.ReturnValue = mp; } // FIXME: fill properties. return md; }
static MessageDescription GetMessage ( OperationDescription od, MethodInfo mi, OperationContractAttribute oca, bool isRequest, bool isCallback, Type asyncReturnType) { ContractDescription cd = od.DeclaringContract; ParameterInfo [] plist = mi.GetParameters (); Type messageType = null; string action = isRequest ? oca.Action : oca.ReplyAction; MessageContractAttribute mca; Type retType = asyncReturnType; if (!isRequest && retType == null) retType = mi.ReturnType; // If the argument is only one and has [MessageContract] // then infer it as a typed messsage if (isRequest) { int len = mi.Name.StartsWith ("Begin", StringComparison.Ordinal) ? 3 : 1; mca = plist.Length != len ? null : GetMessageContractAttribute (plist [0].ParameterType); if (mca != null) messageType = plist [0].ParameterType; } else { mca = GetMessageContractAttribute (retType); if (mca != null) messageType = retType; } if (action == null) action = String.Concat (cd.Namespace, cd.Namespace.Length == 0 ? "urn:" : cd.Namespace.EndsWith ("/") ? "" : "/", cd.Name, "/", od.Name, isRequest ? String.Empty : "Response"); if (mca != null) return CreateMessageDescription (messageType, cd.Namespace, action, isRequest, isCallback, mca); return CreateMessageDescription (oca, plist, od.Name, cd.Namespace, action, isRequest, isCallback, retType, mi.ReturnTypeCustomAttributes); }
static OperationDescription GetOrCreateOperation ( ContractDescription cd, MethodInfo mi, MethodInfo serviceMethod, OperationContractAttribute oca, Type asyncReturnType, bool isCallback) { string name = oca.Name ?? (oca.AsyncPattern ? mi.Name.Substring (5) : mi.Name); OperationDescription od = cd.Operations.FirstOrDefault (o => o.Name == name); if (od == null) { od = new OperationDescription (name, cd); od.IsOneWay = oca.IsOneWay; if (oca.HasProtectionLevel) od.ProtectionLevel = oca.ProtectionLevel; od.Messages.Add (GetMessage (od, mi, oca, true, isCallback, null)); if (!od.IsOneWay) od.Messages.Add (GetMessage (od, mi, oca, false, isCallback, asyncReturnType)); foreach (ServiceKnownTypeAttribute a in cd.ContractType.GetCustomAttributes (typeof (ServiceKnownTypeAttribute), false)) foreach (Type t in a.GetTypes ()) od.KnownTypes.Add (t); foreach (ServiceKnownTypeAttribute a in serviceMethod.GetCustomAttributes (typeof (ServiceKnownTypeAttribute), false)) foreach (Type t in a.GetTypes ()) od.KnownTypes.Add (t); foreach (FaultContractAttribute a in mi.GetCustomAttributes (typeof (FaultContractAttribute), false)) { var fname = a.Name ?? a.DetailType.Name + "Fault"; var fns = a.Namespace ?? cd.Namespace; var fd = new FaultDescription (a.Action ?? cd.Namespace + cd.Name + "/" + od.Name + fname) { DetailType = a.DetailType, Name = fname, Namespace = fns }; #if !NET_2_1 if (a.HasProtectionLevel) fd.ProtectionLevel = a.ProtectionLevel; #endif od.Faults.Add (fd); } cd.Operations.Add (od); } else if (oca.AsyncPattern && od.BeginMethod != null && od.BeginMethod != mi || !oca.AsyncPattern && od.SyncMethod != null && od.SyncMethod != mi) throw new InvalidOperationException (String.Format ("contract '{1}' cannot have two operations for '{0}' that have the identical names and different set of parameters.", name, cd.Name)); if (oca.AsyncPattern) od.BeginMethod = mi; else od.SyncMethod = mi; od.IsInitiating = oca.IsInitiating; od.IsTerminating = oca.IsTerminating; if (mi != serviceMethod) foreach (object obj in mi.GetCustomAttributes (typeof (IOperationBehavior), true)) od.Behaviors.Add ((IOperationBehavior) obj); if (serviceMethod != null) { foreach (object obj in serviceMethod.GetCustomAttributes (typeof(IOperationBehavior),true)) od.Behaviors.Add ((IOperationBehavior) obj); } #if !NET_2_1 if (od.Behaviors.Find<OperationBehaviorAttribute>() == null) od.Behaviors.Add (new OperationBehaviorAttribute ()); #endif // FIXME: fill KnownTypes, Behaviors and Faults. if (isCallback) od.InCallbackContract = true; else od.InOrdinalContract = true; return od; }
internal ContractMethodInfo(ContractType declaringType, OperationInfo operationInfo) { if (declaringType == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("declaringType"); } if (operationInfo == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("operationInfo"); } if (string.IsNullOrEmpty(operationInfo.Name)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("operationInfo", SR2.GetString(SR2.Error_OperationNameNotSpecified)); } this.declaringType = declaringType; this.name = operationInfo.Name; this.methodAttributes = MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual; SortedList<int, ContractMethodParameterInfo> localParameters = new SortedList<int, ContractMethodParameterInfo>(); foreach (OperationParameterInfo operationParameterInfo in operationInfo.Parameters) { ContractMethodParameterInfo parameterInfo = new ContractMethodParameterInfo(this, operationParameterInfo); if (parameterInfo.Position == -1) { this.returnParam = parameterInfo; } else { localParameters.Add(parameterInfo.Position, parameterInfo); } } this.parameters = new ParameterInfo[localParameters.Count]; foreach (ContractMethodParameterInfo paramInfo in localParameters.Values) { this.parameters[paramInfo.Position] = paramInfo; } if (this.returnParam == null) { OperationParameterInfo returnParameterInfo = new OperationParameterInfo(); returnParameterInfo.Position = -1; returnParameterInfo.ParameterType = typeof(void); this.returnParam = new ContractMethodParameterInfo(this, returnParameterInfo); } OperationContractAttribute operationContract = new OperationContractAttribute(); if (operationInfo.HasProtectionLevel && operationInfo.ProtectionLevel != null) { operationContract.ProtectionLevel = (ProtectionLevel) operationInfo.ProtectionLevel; } operationContract.IsOneWay = operationInfo.IsOneWay; this.attributes = new Attribute[] { operationContract }; declaringType.AddMethod(this); }
static OperationDescription GetOrCreateOperation ( ContractDescription cd, MethodInfo mi, MethodInfo serviceMethod, OperationContractAttribute oca, Type asyncReturnType) { string name = oca.Name ?? (oca.AsyncPattern ? mi.Name.Substring (5) : mi.Name); OperationDescription od = null; foreach (OperationDescription iter in cd.Operations) { if (iter.Name == name) { od = iter; break; } } if (od == null) { od = new OperationDescription (name, cd); od.IsOneWay = oca.IsOneWay; if (oca.HasProtectionLevel) od.ProtectionLevel = oca.ProtectionLevel; od.Messages.Add (GetMessage (od, mi, oca, true, null)); if (!od.IsOneWay) od.Messages.Add (GetMessage (od, mi, oca, false, asyncReturnType)); foreach (ServiceKnownTypeAttribute a in cd.ContractType.GetCustomAttributes (typeof (ServiceKnownTypeAttribute), false)) foreach (Type t in a.GetTypes ()) od.KnownTypes.Add (t); foreach (ServiceKnownTypeAttribute a in serviceMethod.GetCustomAttributes (typeof (ServiceKnownTypeAttribute), false)) foreach (Type t in a.GetTypes ()) od.KnownTypes.Add (t); foreach (FaultContractAttribute a in serviceMethod.GetCustomAttributes (typeof (FaultContractAttribute), false)) od.Faults.Add (new FaultDescription (a.Action) { DetailType = a.DetailType, Name = a.Name, Namespace = a.Namespace }); cd.Operations.Add (od); } else if (oca.AsyncPattern && od.BeginMethod != null || !oca.AsyncPattern && od.SyncMethod != null) throw new InvalidOperationException ("A contract cannot have two operations that have the identical names and different set of parameters."); if (oca.AsyncPattern) od.BeginMethod = mi; else od.SyncMethod = mi; od.IsInitiating = oca.IsInitiating; od.IsTerminating = oca.IsTerminating; if (mi != serviceMethod) foreach (object obj in mi.GetCustomAttributes (typeof (IOperationBehavior), true)) od.Behaviors.Add ((IOperationBehavior) obj); if (serviceMethod != null) { foreach (object obj in serviceMethod.GetCustomAttributes (typeof(IOperationBehavior),true)) od.Behaviors.Add ((IOperationBehavior) obj); } #if !NET_2_1 if (od.Behaviors.Find<OperationBehaviorAttribute>() == null) od.Behaviors.Add (new OperationBehaviorAttribute ()); #endif // FIXME: fill KnownTypes, Behaviors and Faults. return od; }