/// <summary> /// Initializes all service actions in the provider. /// </summary> /// <param name="operationContext">The operation context instance of the request.</param> private void InitializeServiceActions(DataServiceOperationContext operationContext) { if (operationContext == null) { throw new DataServiceException("operationContext must not be null!"); } var actionInfos = Interlocked.Exchange(ref this.serviceActionInfos, new Dictionary <string, DSPServiceActionInfo>()); if (actionInfos.Count > 0) { IDataServiceMetadataProvider metadataProvider = (IDataServiceMetadataProvider)operationContext.GetService(typeof(IDataServiceMetadataProvider)); if (metadataProvider == null) { throw new DataServiceException("DataServiceOperationContext.GetService(typeof(IDataServiceMetadataProvider)) must return a valid instance of the IDataServiceMetadataProvider."); } foreach (var entry in actionInfos) { DSPServiceActionInfo actionInfo = entry.Value; DSPActionAttribute actionAttribute = actionInfo.ActionAttribute; MethodInfo actionMethodInfo = actionInfo.Method; ResourceType returnType = DSPActionProvider.GetResourceTypeFromType(metadataProvider, actionInfo.Method.ReturnType, actionAttribute.ReturnElementTypeName); var parameters = DSPActionProvider.GetServiceActionParameters(metadataProvider, actionAttribute, actionMethodInfo); ServiceAction action; if (!string.IsNullOrEmpty(actionAttribute.ReturnSetPath)) { if (actionAttribute.OperationParameterBindingKind != OperationParameterBindingKind.Always && actionAttribute.OperationParameterBindingKind != OperationParameterBindingKind.Sometimes) { throw new DataServiceException("DSPActionAttribute.IsBindable must be true when DSPActionAttribute.ReturnSetPath is not null."); } ResourceSetPathExpression pathExpression = new ResourceSetPathExpression(actionAttribute.ReturnSetPath); action = new ServiceAction(actionMethodInfo.Name, returnType, OperationParameterBindingKind.Sometimes, parameters, pathExpression); } else { ResourceSet returnSet = null; if (!string.IsNullOrEmpty(actionAttribute.ReturnSet)) { metadataProvider.TryResolveResourceSet(actionAttribute.ReturnSet, out returnSet); } action = new ServiceAction(actionMethodInfo.Name, returnType, returnSet, actionAttribute.OperationParameterBindingKind, parameters); } action.CustomState = actionInfo; action.SetReadOnly(); this.serviceActions.Add(actionMethodInfo.Name, action); } } }
/// <summary> /// Creates the service action parameters for the given action method info. /// </summary> /// <param name="metadataProvider">An instance of the IDataServiceMetadataProvider.</param> /// <param name="actionAttribute">DSPActionAttribute instance for the action.</param> /// <param name="actionMethodInfo">MethodInfo for the action.</param> /// <returns></returns> private static IEnumerable <ServiceActionParameter> GetServiceActionParameters(IDataServiceMetadataProvider metadataProvider, DSPActionAttribute actionAttribute, MethodInfo actionMethodInfo) { ParameterInfo[] parameterInfos = actionMethodInfo.GetParameters(); if (actionAttribute.ParameterTypeNames.Length != parameterInfos.Length) { throw new InvalidOperationException(string.Format("Mismatch parameter count between the DSPActionAttribute and the MethodInfo for the Action '{0}'.", actionMethodInfo.Name)); } for (int idx = 0; idx < parameterInfos.Length; idx++) { ParameterInfo parameterInfo = parameterInfos[idx]; ResourceType parameterResourceType = DSPActionProvider.GetResourceTypeFromType(metadataProvider, parameterInfo.ParameterType, actionAttribute.ParameterTypeNames[idx]); yield return(new ServiceActionParameter(parameterInfo.Name, parameterResourceType)); } }