private object GetArgumentValueFromUrlEncodedString(ArgumentBindingContext <FromBodyAttribute> context) { string data; using (var reader = new StreamReader(context.Request.Body)) { data = reader.ReadToEnd(); } context.Request.Body.Seek(0, SeekOrigin.Begin); if (data.Length <= 2) { return(null); } data = "&" + data; string parameterName = GetParameterName(context); string template = String.Format("&{0}=(?<Value>[^&]+)", Regex.Escape(parameterName)); MatchCollection matches = Regex.Matches(data, template); return(matches.Count == 0 ? null : _converterProvider.ConvertToCollection( matches.Cast <Match>().Select(match => HttpUtility.UrlDecode(match.Groups["Value"].Value)), context.Parameter.ParameterType, context.Request)); }
private object GetArgumentValueFromMultipartFormDataBody(ArgumentBindingContext <FromBodyAttribute> context) { RequestInfo[] parts = context.MultipartBodies[context.Request]; string parameterName = GetParameterName(context); var part = (from item in parts let contentDisposition = item.Headers[Header.ContentDisposition] where contentDisposition != null from value in contentDisposition.Values where value.Value == "form-data" from param in value.Parameters where (param.Name == "name") && (param.Value is string) && (String.Compare((string)param.Value, parameterName, true) == 0) select item).FirstOrDefault(); if (part == null) { return(null); } context.Success = true; return(GetArgumentValue(new ArgumentBindingContext <FromBodyAttribute>( part, context.RequestMapping, context.Parameter, context.Index, context.ParameterSource, context.MultipartBodies))); }
private object GetArgumentValueFromMultipartBody(ArgumentBindingContext <FromBodyAttribute> context) { var contentType = context.Request.Headers[Header.ContentType].Values.First(value => value.Value.StartsWith("multipart/")); var boundary = contentType.Parameters[HeaderParameter.Boundary]; if ((boundary == null) || (String.IsNullOrEmpty(boundary.Value as string))) { throw new InvalidOperationException("Cannot process multipart body without a boundary marker."); } if (!context.MultipartBodies.ContainsKey(context.Request)) { context.MultipartBodies[context.Request] = ParseMultipartMessage( context.Request.Method, context.Request.Url, new StreamReader(context.Request.Body).ReadToEnd(), (string)boundary.Value); context.Request.Body.Seek(0, SeekOrigin.Begin); } if (contentType.Value == "multipart/form-data") { return(GetArgumentValueFromMultipartFormDataBody(context)); } return(!context.Success ? GetArgumentValueFromMultipartMixedBody(context) : null); }
/// <inheritdoc /> public object GetArgumentValue(ArgumentBindingContext <FromQueryStringAttribute> context) { if (context == null) { throw new ArgumentNullException("context"); } if ((!context.Request.Url.HasQuery) || (context.Request.Url.Query.Count == 0)) { return(null); } string parameterName = context.Parameter.Name; var variableMatch = UriTemplateBuilder.VariableTemplateRegex.Match(context.ParameterSource.UrlTemplate); if ((!variableMatch.Success) || (!variableMatch.Groups["ExpansionType"].Success)) { variableMatch = Regex.Match(context.ParameterSource.UrlTemplate, "[?&]*(<ParameterName>[^=]+)="); } parameterName = (variableMatch.Success ? variableMatch.Groups["ParameterName"].Value : parameterName); var values = context.Request.Url.Query.GetValues(parameterName); return(!values.Any() ? null : _converterProvider.ConvertToCollection(values, context.Parameter.ParameterType, context.Request)); }
private string GetParameterName(ArgumentBindingContext <FromBodyAttribute> context) { return(!String.IsNullOrEmpty(context.ParameterSource.Name) ? context.ParameterSource.Name : context.RequestMapping.Operation.UnderlyingMethod.GetParameters() .Where(argument => argument == context.Parameter) .Select(argument => argument.Name).First()); }
/// <inheritdoc /> public object GetArgumentValue(ArgumentBindingContext <FromUrlAttribute> context) { if (context == null) { throw new ArgumentNullException("context"); } if (System.TypeExtensions.IsEnumerable(context.Parameter.ParameterType)) { throw new InvalidOperationException(String.Format("Cannot bind types based on '{0}' to uri segments.", typeof(IEnumerable))); } string url = MakeUri(context.Parameter, context.RequestMapping.MethodRoute, context.RequestMapping.Operation); string template = UriTemplateBuilder.VariableTemplateRegex.Replace(url, "(?<Value>[^/\\?]+)"); Match match = Regex.Match(context.Request.Url.AsRelative.ToString(), template); return(match.Success ? _converterProvider.ConvertTo(match.Groups["Value"].Value, context.Parameter.ParameterType, context.Request) : null); }
private object GetArgumentValueFromMultipartMixedBody(ArgumentBindingContext <FromBodyAttribute> context) { RequestInfo[] parts = context.MultipartBodies[context.Request]; int partIndex = context.RequestMapping.Operation.UnderlyingMethod.GetParameters() .TakeWhile(argument => argument != context.Parameter) .Select(argument => argument.GetCustomAttribute <ParameterSourceAttribute>(true)).OfType <FromBodyAttribute>().Count(); if (partIndex < parts.Length) { return(GetArgumentValue(new ArgumentBindingContext <FromBodyAttribute>( parts[partIndex], context.RequestMapping, context.Parameter, context.Index, context.ParameterSource, context.MultipartBodies))); } return(null); }
private object BindArgument(RequestInfo request, IRequestMapping requestMapping, ArgumentInfo parameter, int index, IDictionary <RequestInfo, RequestInfo[]> multipartBodies) { Type parameterSourceArgumentBinderType = typeof(IParameterSourceArgumentBinder <>).MakeGenericType(parameter.Source.GetType()); IParameterSourceArgumentBinder argumentBinder = (from binder in _parameterSourceArgumentBinders where (parameterSourceArgumentBinderType.IsInstanceOfType(binder)) || (binder.GetType().GetInterfaces().Any(type => parameterSourceArgumentBinderType.IsAssignableFrom(type))) select binder).FirstOrDefault(); if (argumentBinder == null) { return(null); } var arguments = new object[] { request, (RequestMapping)requestMapping, parameter.Parameter, index, parameter.Source, multipartBodies }; ArgumentBindingContext context = (ArgumentBindingContext)typeof(ArgumentBindingContext <>) .MakeGenericType(parameter.Source.GetType()) .GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) .First() .Invoke(arguments); try { return(argumentBinder.GetArgumentValue(context)); } catch (Exception exception) { throw new ArgumentException(String.Format("Could not convert argument '{0}'.", parameter.VariableName), exception); } }
/// <inheritdoc /> public object GetArgumentValue(ArgumentBindingContext <FromBodyAttribute> context) { if (context == null) { throw new ArgumentNullException("context"); } var contentType = context.Request.Headers[Header.ContentType]; if (contentType != null) { if (contentType.Value.StartsWith("multipart/")) { return(GetArgumentValueFromMultipartBody(context)); } IConverter xWwwUrlEncodedConverter; if ((contentType.Value == XWwwUrlEncodedConverter.ApplicationXWwwUrlEncoded) && (((xWwwUrlEncodedConverter = _converterProvider.FindBestInputConverter(context.Parameter.ParameterType, context.Request)) == null) || ((xWwwUrlEncodedConverter.CanConvertTo(context.Parameter.ParameterType, context.Request) & CompatibilityLevel.TypeMatch) == CompatibilityLevel.None))) { return(GetArgumentValueFromUrlEncodedString(context)); } } var converter = _converterProvider.FindBestInputConverter(context.Parameter.ParameterType, context.Request); if (converter == null) { return(null); } object result = converter.ConvertTo(context.Parameter.ParameterType, context.Request); context.Request.Body.Seek(0, SeekOrigin.Begin); return(result); }
/// <inheritdoc /> public object GetArgumentValue(ArgumentBindingContext context) { return(GetArgumentValue(context as ArgumentBindingContext <FromBodyAttribute>)); }