Ejemplo n.º 1
0
 public static TResult ParseContentDelegate <TResult>(string key, IFormCollection formData,
                                                      ParameterInfo parameterInfo, IApplication httpApp,
                                                      Func <object, TResult> onParsed,
                                                      Func <string, TResult> onFailure)
 {
     return(ParseContentDelegate(key, formData,
                                 (strValue) =>
     {
         return httpApp.Bind(strValue, parameterInfo,
                             (value) =>
         {
             return onParsed(value);
         },
                             why => onFailure(why));
     },
                                 formFile =>
     {
         return httpApp.Bind(formFile, parameterInfo,
                             (value) =>
         {
             return onParsed(value);
         },
                             why => onFailure(why));
     },
                                 onFailure: onFailure));
 }
        protected override CastDelegate GetFileNameCastDelegate(
            IHttpRequest request, IApplication httpApp, string[] componentsMatched, out string[] pathKeys)
        {
            pathKeys = PathComponents(request)
                       .Skip(componentsMatched.Length + 1)
                       .ToArray();
            var          paths = pathKeys;
            CastDelegate fileNameCastDelegate =
                (paramInfo, onParsed, onFailure) =>
            {
                if (!paths.Any())
                {
                    return(onFailure("No URI filename value provided."));
                }
                if (paths.Length > 1)
                {
                    return(onFailure($"More than 1 path key `{paths.Join(',')}` not supported."));
                }
                return(httpApp.Bind(paths.First(), paramInfo,
                                    v => onParsed(v),
                                    (why) => onFailure(why)));
            };

            return(fileNameCastDelegate);
        }
Ejemplo n.º 3
0
 public static TResult Bind <TProvider, TResult>(this IApplication application,
                                                 TProvider provider, MemberInfo propertyOrFieldInfo,
                                                 Func <object, TResult> onParsed,
                                                 Func <string, TResult> onFailureToBind)
 {
     return(propertyOrFieldInfo
            .GetAttributesInterface <IBindApiPropertyOrField <TProvider> >()
            .First(
                (propBinder, next) =>
     {
         return propBinder.Bind <TResult>(propertyOrFieldInfo, provider,
                                          application,
                                          onParsed,
                                          (why) =>
         {
             return next();
         },
                                          (why) => onFailureToBind(why));
     },
                () =>
     {
         var type = propertyOrFieldInfo.GetPropertyOrFieldType();
         return application.Bind(provider, type,
                                 onParsed,
                                 onFailureToBind);
     }));
 }
Ejemplo n.º 4
0
            public async Task <T> BindFromByte <T>()
            {
                var bytes = await content.OpenReadStream().ToBytesAsync();

                var result = application.Bind(bytes, typeof(T),
                                              (v) => (T)v,
                                              why => throw new Exception(why));

                return(result);
            }
Ejemplo n.º 5
0
        public TResult ParseContentDelegate <TResult>(JContainer contentJContainer,
                                                      string contentString, Serialization.BindConvert bindConvert,
                                                      ParameterInfo paramInfo,
                                                      IApplication httpApp, IHttpRequest request,
                                                      Func <object, TResult> onParsed,
                                                      Func <string, TResult> onFailure)
        {
            if (contentJContainer is JObject)
            {
                var contentJObject = contentJContainer as JObject;

                var key = this.GetKey(paramInfo);
                return(ParseJsonContentDelegate(contentJObject,
                                                contentString, bindConvert,
                                                key, paramInfo,
                                                httpApp, request,
                                                onParsed,
                                                onFailure));
            }

            if (contentJContainer is JArray)
            {
                var contentJArray = contentJContainer as JArray;
                var paramType     = paramInfo.ParameterType;
                var key           = this.GetKey(paramInfo);
                if (paramType.IsArray)
                {
                    var elementType = paramType.GetElementType();
                    var arrayOfType = contentJArray
                                      .Select(
                        contentJToken =>
                    {
                        if (contentJToken is JObject)
                        {
                            var contentJObject = (JObject)contentJToken;
                            if (!contentJObject.TryGetValue(key, out JToken valueToken))
                            {
                                return(elementType.GetDefault());
                            }
                            return(httpApp.Bind(valueToken, elementType,
                                                obj => obj,
                                                why => elementType.GetDefault()));
                        }
                        return(elementType.GetDefault());
                    })
                                      .CastArray(elementType);
                    return(onParsed(arrayOfType));
                }
            }

            return(onFailure($"JSON Content is {contentJContainer.Type} and non-array properties can only be parsed from objects."));
        }
Ejemplo n.º 6
0
        internal static TResult ContentToType <TResult>(IApplication httpApp, ParameterInfo paramInfo,
                                                        MultipartContentTokenParser tokenReader,
                                                        Func <object, TResult> onParsed,
                                                        Func <string, TResult> onFailure)
        {
            var type = paramInfo.ParameterType;

            return(ContentToType(httpApp, type, tokenReader,
                                 onParsed,
                                 strValue =>
            {
                return httpApp.Bind(strValue, paramInfo,
                                    (value) =>
                {
                    return onParsed(value);
                },
                                    why => onFailure(why));
            }));
        }
Ejemplo n.º 7
0
        public static TResult ParseJsonContentDelegate <TResult>(JObject contentJObject,
                                                                 string contentString, Serialization.BindConvert bindConvert,
                                                                 string key, ParameterInfo paramInfo,
                                                                 IApplication httpApp, IHttpRequest request,
                                                                 Func <object, TResult> onParsed,
                                                                 Func <string, TResult> onFailure)
        {
            if (!contentJObject.TryGetValue(key, out JToken valueToken))
            {
                return(onFailure($"Key[{key}] was not found in JSON"));
            }

            try
            {
                //var tokenParser = new Serialization.JsonTokenParser(valueToken);
                return(httpApp.Bind(valueToken, paramInfo,
                                    obj => onParsed(obj),
                                    (why) =>
                {
                    // TODO: Get BindConvert to StandardJTokenBindingAttribute
                    if (valueToken.Type == JTokenType.Object || valueToken.Type == JTokenType.Array)
                    {
                        try
                        {
                            var value = Newtonsoft.Json.JsonConvert.DeserializeObject(
                                valueToken.ToString(), paramInfo.ParameterType, bindConvert);
                            return onParsed(value);
                        }
                        catch (Newtonsoft.Json.JsonSerializationException)
                        {
                            throw;
                        }
                    }
                    return onFailure(why);
                }));
            }
            catch (Exception ex)
            {
                return(onFailure(ex.Message));
            }
        }
Ejemplo n.º 8
0
        public TResult ParseContentDelegate <TResult>(XmlDocument xmlDoc, string rawContent,
                                                      ParameterInfo parameterInfo, IApplication httpApp, IHttpRequest request,
                                                      Func <object, TResult> onParsed,
                                                      Func <string, TResult> onFailure)
        {
            if (parameterInfo.ParameterType.IsAssignableFrom(typeof(XmlDocument)))
            {
                return(onParsed(xmlDoc));
            }

            var mgr = new XmlNamespaceManager(xmlDoc.NameTable);

            if (NSPrefix.HasBlackSpace())
            {
                mgr.AddNamespace(NSPrefix, NSUri);
            }
            var key  = this.GetKey(parameterInfo);
            var node = xmlDoc.SelectSingleNode(key, mgr);

            if (parameterInfo.ParameterType.IsAssignableFrom(typeof(XmlNode)))
            {
                return(onParsed(node));
            }

            if (parameterInfo.ParameterType.IsAssignableFrom(typeof(XmlNode[])))
            {
                if (node.IsDefaultOrNull())
                {
                    return(onParsed(new XmlNode[] { }));
                }
                return(onParsed(
                           XmlContent
                           .Enumerate(node.ChildNodes)
                           .AsArray()));
            }

            return(httpApp.Bind(node, parameterInfo,
                                onParsed,
                                onFailure));
        }
Ejemplo n.º 9
0
        protected virtual CastDelegate GetFileNameCastDelegate(
            IHttpRequest request, IApplication httpApp, string [] componentsMatched, out string [] pathKeys)
        {
            pathKeys = PathComponents(request)
                       .Skip(componentsMatched.Length)
                       .ToArray();
            var          path = pathKeys;
            CastDelegate fileNameCastDelegate =
                (paramInfo, onParsed, onFailure) =>
            {
                if (!path.Any())
                {
                    return(onFailure("No URI filename value provided."));
                }
                var fileName = path.First();
                return(httpApp.Bind(fileName, paramInfo,
                                    v => onParsed(v),
                                    (why) => onFailure(why)));
            };

            return(fileNameCastDelegate);
        }
Ejemplo n.º 10
0
        protected virtual CastDelegate GetQueryCastDelegate(
            IHttpRequest request, IApplication httpApp, out string[] queryKeys)
        {
            var queryParameters = request.RequestUri.ParseQuery()
                                  .Select(kvp => kvp.Key.ToLower().PairWithValue(kvp.Value))
                                  .ToDictionary();

            queryKeys = queryParameters.SelectKeys().ToArray();

            var          queryParameterCollections = GetCollectionParameters(httpApp, queryParameters).ToDictionary();
            CastDelegate queryCastDelegate         =
                (paramInfo, onParsed, onFailure) =>
            {
                var queryKey = paramInfo
                               .GetAttributeInterface <IBindApiValue>()
                               .GetKey(paramInfo)
                               .ToLower();
                var type = paramInfo.ParameterType;
                if (!queryParameters.ContainsKey(queryKey))
                {
                    if (!queryParameterCollections.ContainsKey(queryKey))
                    {
                        return(onFailure($"Missing query parameter `{queryKey}`"));
                    }
                    return(queryParameterCollections[queryKey](
                               type,
                               vs => onParsed(vs),
                               why => onFailure(why)));
                }
                var queryValueString = queryParameters[queryKey];
                return(httpApp.Bind(queryValueString, paramInfo,
                                    v => onParsed(v),
                                    (why) => onFailure(why)));
            };

            return(queryCastDelegate);
        }
Ejemplo n.º 11
0
        public static IEnumerable <KeyValuePair <string, ParseContentDelegate <SelectParameterResult> > > GetCollectionParameters(IApplication httpApp, IEnumerable <KeyValuePair <string, string> > queryParameters)
        {
            // Convert parameters into Collections if necessary
            return(queryParameters
                   .SelectOptional <KeyValuePair <string, string>, MultipartParameter>(
                       (param, select, skip) => param.Key.MatchRegexInvoke(
                           @"(?<key>[a-zA-Z0-9]+)\[(?<value>[a-zA-Z0-9]+)\]",
                           (string key, string value) => new KeyValuePair <string, string>(key, value),
                           (kvps) =>
            {
                if (!kvps.Any())
                {
                    return skip();
                }

                var kvp = kvps.First();
                var multipartParam = new MultipartParameter
                {
                    index = kvp.Key,
                    key = kvp.Value,
                    fetchValue = (type, onSuccess, onFailure) =>
                                 httpApp.Bind(param.Value, type,
                                              v => onSuccess(v),
                                              why => onFailure(why))
                                 .AsTask(),
                };
                return select(multipartParam);
            }))
                   .GroupBy(collectionParameter => collectionParameter.index)
                   .Select(
                       collectionParameterGrp =>
                       collectionParameterGrp.Key.ToLower()
                       .PairWithValue <string, ParseContentDelegate <SelectParameterResult> >(
                           (collectionType, onParsed, onFailure) =>
            {
                if (collectionType.IsGenericType)
                {
                    var genericArgs = collectionType.GenericTypeArguments;
                    if (genericArgs.Length == 1)
                    {
                        // It's an array
                        var typeToCast = genericArgs.First();
                        var lookup = collectionParameterGrp
                                     .SelectOptional <MultipartParameter, object>(
                            (collectionParameter, next, skip) => (EastFive.Linq.EnumerableExtensions.ISelected <object>)collectionParameter.fetchValue(typeToCast,
                                                                                                                                                       v => next(v),
                                                                                                                                                       (why) => skip()))
                                     .ToArray();
                        return onParsed(lookup);
                    }
                    if (genericArgs.Length == 2)
                    {
                        // It's an dictionary
                        var typeToCast = genericArgs[1];
                        var kvpCreateMethod = typeof(FunctionViewControllerAttribute).GetMethod("KvpCreate", BindingFlags.Static | BindingFlags.NonPublic);
                        var correctGenericKvpCreate = kvpCreateMethod.MakeGenericMethod(genericArgs);
                        var lookup = collectionParameterGrp
                                     .FlatMap(
                            (collectionParameter, next, skip) =>
                            (object[])collectionParameter.fetchValue(typeToCast,
                                                                     v => next(correctGenericKvpCreate.Invoke(null, new object[] { collectionParameter.key, v })),
                                                                     (why) => skip()),
                            (IEnumerable <object> lookupInner) => lookupInner.ToArray());

                        var castMethod = typeof(FunctionViewControllerAttribute).GetMethod("CastToKvp", BindingFlags.Static | BindingFlags.NonPublic);
                        var correctKvpsCast = castMethod.MakeGenericMethod(genericArgs);
                        var kvpsOfCorrectTypes = correctKvpsCast.Invoke(null, lookup.AsArray());

                        var dictCreateMethod = typeof(FunctionViewControllerAttribute).GetMethod("DictionaryCreate", BindingFlags.Static | BindingFlags.NonPublic);
                        var correctGenericDictCreate = dictCreateMethod.MakeGenericMethod(genericArgs);
                        var dictionaryOfCorrectTypes = correctGenericDictCreate.Invoke(null, kvpsOfCorrectTypes.AsArray());
                        return onParsed(dictionaryOfCorrectTypes);
                    }
                    return onFailure($"Cannot parse collection of type {collectionType.FullName}");
                }
                if (typeof(Enumerable).IsAssignableFrom(collectionType))
                {
                    // It's an array
                    var typeToCast = typeof(object);
                    var values = collectionParameterGrp
                                 .Select(
                        (collectionParameter) =>
                        (SelectedValue?)collectionParameter.fetchValue(typeToCast,
                                                                       v => new SelectedValue {
                        value = v
                    },
                                                                       (why) => default(SelectedValue?)))
                                 .SelectWhereHasValue()
                                 .Select(v => v.value);
                    return onParsed(values);
                }
                if (typeof(System.Collections.DictionaryBase).IsAssignableFrom(collectionType))
                {
                    // It's an dictionary
                    var typeToCast = typeof(object);
                    var dictionary = collectionParameterGrp
                                     .FlatMap(
                        (collectionParameter, next, skip) => (Dictionary <string, object>)collectionParameter.fetchValue(typeToCast,
                                                                                                                         v => next(collectionParameter.key.PairWithValue(v)),
                                                                                                                         (why) => skip()),
                        (IEnumerable <KeyValuePair <string, object> > lookups) => lookups.ToDictionary());
                    return onParsed(dictionary);
                }
                return onFailure($"Cannot parse collection of type {collectionType.FullName}");
            })));
        }
Ejemplo n.º 12
0
        public TResult Bind <TResult>(Type type,
                                      IFormFile content,
                                      IApplication application,
                                      Func <object, TResult> onParsed,
                                      Func <string, TResult> onDidNotBind,
                                      Func <string, TResult> onBindingFailure)
        {
            if (type.IsAssignableFrom(typeof(Stream)))
            {
                var streamValue = content.OpenReadStream();
                return(onParsed((object)streamValue));
            }
            if (type.IsAssignableFrom(typeof(Func <Task <Stream> >)))
            {
                Func <Task <Stream> > callbackValue = () =>
                {
                    var streamValue = content.OpenReadStream();
                    return(streamValue.AsTask());
                };
                return(onParsed((object)callbackValue));
            }
            if (type.IsAssignableFrom(typeof(byte[])))
            {
                var stream = content.OpenReadStream();
                var bytes  = new byte[content.Length];
                stream.Read(bytes, 0, (int)content.Length);
                return(onParsed((object)bytes));
            }
            if (type.IsAssignableFrom(typeof(Func <Task <byte[]> >)))
            {
                Func <Task <byte[]> > callbackValue = () =>
                {
                    var stream = content.OpenReadStream();
                    var bytes  = new byte[content.Length];
                    stream.Read(bytes, 0, (int)content.Length);
                    return(bytes.AsTask());
                };
                return(onParsed((object)callbackValue));
            }
            if (type.IsAssignableFrom(typeof(MediaTypeWithQualityHeaderValue)))
            {
                var header = new MediaTypeWithQualityHeaderValue(content.ContentType);
                return(onParsed(header));
            }
            if (type.IsAssignableFrom(typeof(ContentDispositionHeaderValue)))
            {
                if (ContentDispositionHeaderValue.TryParse(content.ContentDisposition,
                                                           out ContentDispositionHeaderValue header))
                {
                    return(onParsed((object)header));
                }
            }
            if (type.IsSubClassOfGeneric(typeof(ReadRequestBodyDelegateAsync <>)))
            {
                var data            = new Data(content, application);
                var requestDelegate = InvokeHelper(data.BindFromByte <object>, type, data);
                return(onParsed(requestDelegate));
            }
            var bytesGeneric = content.OpenReadStream().ToBytesAsync().Result;

            return(application.Bind(bytesGeneric, type,
                                    (v) => onParsed(v),
                                    why => onDidNotBind(why)));
            //return onDidNotBind(
            //    $"{type.FullName} is not supported from Form Data. Consider wrapping it as a ReadRequestBodyDelegateAsync<>");
        }
Ejemplo n.º 13
0
 public static TResult Bind <TProvider, TResult>(this IApplication application,
                                                 TProvider provider, ParameterInfo parameter,
                                                 Func <object, TResult> onParsed,
                                                 Func <string, TResult> onFailureToBind)
 {
     return(parameter
            .GetAttributesInterface <IBindApiParameter <TProvider> >()
            .First(
                (paramBinder, next) =>
     {
         return paramBinder.Bind(parameter, provider,
                                 application,
                                 onParsed,
                                 (why) =>
         {
             return next();
         },
                                 (why) => onFailureToBind(why));
     },
                () =>
     {
         return application.GetType()
         .GetAttributesInterface <IBindApiParameter <TProvider> >(true)
         .First(
             (paramBinder, next) =>
         {
             return paramBinder.Bind(parameter, provider,
                                     application,
                                     onParsed,
                                     (why) =>
             {
                 return next();
             },
                                     (why) => onFailureToBind(why));
         },
             () =>
         {
             var parameterType = parameter.ParameterType;
             return parameterType
             .GetAttributesInterface <IBindApiParameter <TProvider> >(inherit: true)
             .First(
                 (paramBinder, next) =>
             {
                 return paramBinder.Bind(parameter, provider,
                                         application,
                                         onParsed,
                                         (why) =>
                 {
                     return next();
                 },
                                         (why) => onFailureToBind(why));
             },
                 () =>
             {
                 return application.Bind(provider, parameterType,
                                         onParsed,
                                         onFailureToBind);
             });
         });
     }));
 }