public async Task <IQueryable> ExecuteOperationAsync( OperationContext context, CancellationToken cancellationToken) { // Authorization check await InvokeAuthorizers(context, cancellationToken); // model build does not support operation with same name // So method with same name but different signature is not considered. MethodInfo method = context.ImplementInstance.GetType().GetMethod( context.OperationName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy); if (method == null) { throw new NotImplementedException(Resources.OperationNotImplemented); } var parameterArray = method.GetParameters(); var model = context.GetApiService <IEdmModel>(); // Parameters of method and model is exactly mapped or there is parsing error var parameters = new object[parameterArray.Length]; int paraIndex = 0; if (context.BindingParameterValue != null) { // Add binding parameter which is first parameter of method parameters[0] = PrepareBindingParameter(parameterArray[0].ParameterType, context.BindingParameterValue); paraIndex = 1; } for (; paraIndex < parameterArray.Length; paraIndex++) { var parameter = parameterArray[paraIndex]; var currentParameterValue = context.GetParameterValueFunc(parameter.Name); object convertedValue = null; if (context.IsFunction) { var parameterTypeRef = parameter.ParameterType.GetTypeReference(model); // Change to right CLR class for collection/Enum/Complex/Entity convertedValue = DeserializationHelpers.ConvertValue( currentParameterValue, parameter.Name, parameter.ParameterType, parameterTypeRef, model, context.Request, context.ServiceProvider); } else { convertedValue = DeserializationHelpers.ConvertCollectionType( currentParameterValue, parameter.ParameterType); } parameters[paraIndex] = convertedValue; } context.ParameterValues = parameters; // Invoke preprocessing on the operation execution PerformPreEvent(context, cancellationToken); var result = await InvokeOperation(context.ImplementInstance, method, parameters, model); // Invoke preprocessing on the operation execution PerformPostEvent(context, cancellationToken); return(result); }
/// <summary> /// Asynchronously executes an operation. /// </summary> /// <param name="context"> /// The operation context. /// </param> /// <param name="cancellationToken"> /// A cancellation token. /// </param> /// <returns> /// A task that represents the asynchronous /// operation whose result is a operation result. /// </returns> public async Task <IQueryable> ExecuteOperationAsync(OperationContext context, CancellationToken cancellationToken) { Ensure.NotNull(context, nameof(context)); // Authorization check #pragma warning disable CA1062 // Validate arguments of public methods. JWS: Ensure.NotNull is there. Spurious warning. await InvokeAuthorizers(context, cancellationToken).ConfigureAwait(false); #pragma warning restore CA1062 // Validate arguments of public methods. // model build does not support operation with same name // So method with same name but different signature is not considered. var method = context.Api.GetType().GetMethod(context.OperationName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy); if (method == null) { throw new NotImplementedException(Resources.OperationNotImplemented); } var parameterArray = method.GetParameters(); var model = await context.Api.GetModelAsync(cancellationToken).ConfigureAwait(false); // Parameters of method and model is exactly mapped or there is parsing error var parameters = new object[parameterArray.Length]; var paraIndex = 0; if (context.BindingParameterValue != null) { // Add binding parameter which is first parameter of method parameters[0] = PrepareBindingParameter(parameterArray[0].ParameterType, context.BindingParameterValue); paraIndex = 1; } for (; paraIndex < parameterArray.Length; paraIndex++) { var parameter = parameterArray[paraIndex]; var currentParameterValue = context.GetParameterValueFunc(parameter.Name); object convertedValue = null; if (context.IsFunction) { var parameterTypeRef = parameter.ParameterType.GetTypeReference(model); // Change to right CLR class for collection/Enum/Complex/Entity convertedValue = DeserializationHelpers.ConvertValue( currentParameterValue, parameter.Name, parameter.ParameterType, parameterTypeRef, model, context.Request, context.Request.GetRequestContainer()); // JWS: As long as OData requires the ServiceProvder, // we have to provide it. DI abuse smell. } else { convertedValue = DeserializationHelpers.ConvertCollectionType( currentParameterValue, parameter.ParameterType); } parameters[paraIndex] = convertedValue; } context.ParameterValues = parameters; // Invoke preprocessing on the operation execution await PerformPreEvent(context, cancellationToken).ConfigureAwait(false); var result = await InvokeOperation(context.Api, method, parameters, model).ConfigureAwait(false); // Invoke preprocessing on the operation execution await PerformPostEvent(context, cancellationToken).ConfigureAwait(false); return(result); }