internal static object[] BindParameter(IDictionary<string, object> environment, IIMOwinOptions options, ValueProvider valueProvider, ParameterInfoSlim[] arguments) { var methodParameters = new object[arguments.Length]; for (var i = 0; i < arguments.Length; i++) { var item = arguments[i]; var _values = valueProvider.GetValue(item.Name); var value = _values as string; var values = _values as List<string>; var isEmpty = _values == null; if (isEmpty && !item.ParameterTypeIsArray) { if (item.IsOptional) { methodParameters[i] = item.DefaultValue; continue; } if (!item.ParameterTypeIsString && (item.ParameterTypeIsClass || item.ParameterTypeIsNullable)) { methodParameters[i] = null; continue; } environment.EmitBadRequest(); return null; } if (!item.ParameterTypeIsArray) { var conv = TypeBinder.GetConverter(item.ParameterType); if (conv == null) throw new InvalidOperationException("critical:register code is broken"); object pValue; if (value != null && conv(value, out pValue)) { methodParameters[i] = pValue; continue; } if (item.IsOptional) { methodParameters[i] = item.DefaultValue; continue; } if (!item.ParameterTypeIsString && (item.ParameterTypeIsClass || item.ParameterTypeIsNullable)) { methodParameters[i] = null; continue; } environment.EmitBadRequest(); return null; } var arrayConv = TypeBinder.GetArrayConverter(item.ParameterType); if (arrayConv == null) throw new InvalidOperationException("critical:register code is broken"); methodParameters[i] = arrayConv(values ?? ((value != null) ? new[] { value } : (IList<string>)new string[0])); } return methodParameters; }
public async Task ProcessRequest(IDictionary<string, object> environment) { MemoryStream bufferedRequestStream = null; var originalRequestStream = environment.AsRequestBody(); if (!originalRequestStream.CanSeek) { bufferedRequestStream = new MemoryStream(); if (this._options.StreamWriteOption == StreamWriteOption.BufferAndAsynchronousWrite) // keep context await originalRequestStream.CopyToAsync(bufferedRequestStream); else originalRequestStream.CopyTo(bufferedRequestStream); bufferedRequestStream.Position = 0; environment[OwinConstants.RequestBody] = bufferedRequestStream; } try { AcceptVerbs verb; var handler = SelectHandler(environment.AsRequestPath(), environment, out verb); if (handler == null) return; // parameter binding var valueProvider = new ValueProvider(environment, verb); var methodParameters = ParameterBinder.BindParameter(environment, _options, valueProvider, handler.Arguments); if (methodParameters == null) return; var contentFormatter = _options.ContentFormatter; try { var context = new OperationContext(environment, handler.ClassName, handler.MethodName) { Parameters = methodParameters, ParameterNames = handler.ParameterNames, Attributes = handler.AttributeLookup, ContentFormatter = contentFormatter, }; // invoker await handler.Execute(_options, context).ConfigureAwait(false); } catch (Exception ex) { if (IsRethrowOrEmitException(_options, environment, ex)) throw; } } finally { if (bufferedRequestStream != null) bufferedRequestStream.Dispose(); environment[OwinConstants.RequestBody] = originalRequestStream; } }