コード例 #1
0
 public void OnProcessInterrupt(ILightNodeOptions options, IDictionary <string, object> environment, InterruptReason reason, string detail)
 {
     MessageBroker.Publish(new InterruptMessage()
     {
         Reason = reason, Detail = detail
     });
 }
コード例 #2
0
#pragma warning restore 618

        public bool OnStartProcessRequest(ILightNodeOptions options, IDictionary <string, object> environment)
        {
            MessageBroker.Publish(new ProcessStartMessage()
            {
                Options = options, Environment = environment
            });
            return(true);
        }
コード例 #3
0
        public async Task <object> ExecuteOperation(ILightNodeOptions options, OperationContext context, Func <ILightNodeOptions, OperationContext, Task <object> > originalOperation)
        {
            if (MessageBroker == null || Timer == null)
            {
                return(await originalOperation(options, context));
            }
            var timer = Timer;

            object result;
            var    start = timer.Start();

            try
            {
                result = await originalOperation(options, context);

                var stop = timer.Stop(start);

                var message = new LightNodeExecuteResultMessage()
                {
                    ContractName         = context.ContractName,
                    OperationName        = context.OperationName,
                    Result               = result,
                    Environment          = context.Environment,
                    UsedContentFormatter = context.ContentFormatter,
                    Options              = options,
                    FromRequestStart     = timer.Point().Offset,
                    Phase = OperationPhase.Operation
                }
                .AsTimelineMessage(context.ToString(), OperationCategory)
                .AsTimedMessage(stop);
                MessageBroker.Publish(message);
                return(result);
            }
            catch (Exception ex)
            {
                var stop = timer.Stop(start);

                var message = new LightNodeExecuteResultMessage()
                {
                    ContractName         = context.ContractName,
                    OperationName        = context.OperationName,
                    Result               = ex.ToString(),
                    Environment          = context.Environment,
                    UsedContentFormatter = context.ContentFormatter,
                    Options              = options,
                    FromRequestStart     = timer.Point().Offset,
                    Phase = (ex is ReturnStatusCodeException) ? OperationPhase.ReturnStatusCode : OperationPhase.Exception
                }
                .AsTimelineMessage(context.ToString(), OperationCategory)
                .AsTimedMessage(stop);
                MessageBroker.Publish(message);

                throw;
            }
        }
コード例 #4
0
        public IReadOnlyList<LightNodeFilterAttribute> GetFilters(ILightNodeOptions options, OperationContext context, IReadOnlyList<LightNodeFilterAttribute> originalFilters)
        {
            if (MessageBroker == null || Timer == null) return originalFilters;
            MessageBroker.Publish(context);

            if (originalFilters.Count == 0) return originalFilters;

            var array = new LightNodeFilterAttribute[originalFilters.Count];
            for (int i = 0; i < originalFilters.Count; i++)
            {
                array[i] = new FilterWrapper(MessageBroker, Timer, originalFilters[i]);
            }

            return array;
        }
コード例 #5
0
        public LightNodeServerMiddleware(AppFunc next, ILightNodeOptions options, Assembly[] hostAssemblies)
        {
            this.next = next;
            this.engine = new LightNodeServer(options);

            var sw = Stopwatch.StartNew();
            var registeredHandler = this.engine.RegisterHandler(hostAssemblies);
            options.Logger.InitializeComplete(sw.Elapsed.TotalMilliseconds);

            lock (runningHandlerLock)
            {
                runningHandlers = runningHandlers.SelectMany(g => g, (g, xs) => new { g.Key, xs })
                    .Concat(new[] { new { Key = options.ServerEngineId, xs = new RegisteredHandlersInfo(options.ServerEngineId, options, registeredHandler) }})
                    .ToLookup(x => x.Key, x => x.xs);
            }
        }
コード例 #6
0
        public LightNodeServerMiddleware(AppFunc next, ILightNodeOptions options, Assembly[] hostAssemblies)
        {
            this.next   = next;
            this.engine = new LightNodeServer(options);

            var sw = Stopwatch.StartNew();
            var registeredHandler = this.engine.RegisterHandler(hostAssemblies);

            options.Logger.InitializeComplete(sw.Elapsed.TotalMilliseconds);

            lock (runningHandlerLock)
            {
                runningHandlers = runningHandlers.SelectMany(g => g, (g, xs) => new { g.Key, xs })
                                  .Concat(new[] { new { Key = options.ServerEngineId, xs = new RegisteredHandlersInfo(options.ServerEngineId, options, registeredHandler) } })
                                  .ToLookup(x => x.Key, x => x.xs);
            }
        }
コード例 #7
0
        internal void EmitCode(ILightNodeOptions options, IDictionary <string, object> environment)
        {
            environment[OwinConstants.ResponseStatusCode] = (int)StatusCode;
            if (ReasonPhrase != null)
            {
                environment[OwinConstants.ResponseReasonPhrase] = ReasonPhrase;
            }
            if (content != null)
            {
                contentFormatter = contentFormatter ?? options.DefaultFormatter;
                var encoding       = contentFormatter.Encoding;
                var responseHeader = environment.AsResponseHeaders();
                responseHeader["Content-Type"] = new[] { contentFormatter.MediaType + ((encoding == null) ? "" : "; charset=" + encoding.WebName) };

                if (environmentEmitter != null)
                {
                    environmentEmitter(environment);
                }

                var responseStream = environment.AsResponseBody();
                if (options.StreamWriteOption == StreamWriteOption.DirectWrite)
                {
                    contentFormatter.Serialize(new UnclosableStream(responseStream), content);
                }
                else
                {
                    using (var buffer = new MemoryStream())
                    {
                        contentFormatter.Serialize(new UnclosableStream(buffer), content);
                        responseHeader["Content-Length"] = new[] { buffer.Position.ToString() };
                        buffer.Position = 0;
                        if (options.StreamWriteOption == StreamWriteOption.BufferAndWrite)
                        {
                            buffer.CopyTo(responseStream); // not CopyToAsync
                        }
                        else
                        {
                            // EmitCode is void:)
                            buffer.CopyTo(responseStream);
                        }
                    }
                }
            }
        }
コード例 #8
0
        internal void EmitCode(ILightNodeOptions options, IDictionary<string, object> environment)
        {
            environment[OwinConstants.ResponseStatusCode] = (int)StatusCode;
            if (ReasonPhrase != null)
            {
                environment[OwinConstants.ResponseReasonPhrase] = ReasonPhrase;
            }
            if (content != null)
            {
                contentFormatter = contentFormatter ?? options.DefaultFormatter;
                var encoding = contentFormatter.Encoding;
                var responseHeader = environment.AsResponseHeaders();
                responseHeader["Content-Type"] = new[] { contentFormatter.MediaType + ((encoding == null) ? "" : "; charset=" + encoding.WebName) };

                if (environmentEmitter != null)
                {
                    environmentEmitter(environment);
                }

                var responseStream = environment.AsResponseBody();
                if (options.StreamWriteOption == StreamWriteOption.DirectWrite)
                {
                    contentFormatter.Serialize(new UnclosableStream(responseStream), content);
                }
                else
                {
                    using (var buffer = new MemoryStream())
                    {
                        contentFormatter.Serialize(new UnclosableStream(buffer), content);
                        responseHeader["Content-Length"] = new[] { buffer.Position.ToString() };
                        buffer.Position = 0;
                        if (options.StreamWriteOption == StreamWriteOption.BufferAndWrite)
                        {
                            buffer.CopyTo(responseStream); // not CopyToAsync
                        }
                        else
                        {
                            // EmitCode is void:)
                            buffer.CopyTo(responseStream);
                        }
                    }
                }
            }
        }
コード例 #9
0
        public IReadOnlyList <LightNodeFilterAttribute> GetFilters(ILightNodeOptions options, OperationContext context, IReadOnlyList <LightNodeFilterAttribute> originalFilters)
        {
            if (MessageBroker == null || Timer == null)
            {
                return(originalFilters);
            }
            MessageBroker.Publish(context);

            if (originalFilters.Count == 0)
            {
                return(originalFilters);
            }

            var array = new LightNodeFilterAttribute[originalFilters.Count];

            for (int i = 0; i < originalFilters.Count; i++)
            {
                array[i] = new FilterWrapper(MessageBroker, Timer, originalFilters[i]);
            }

            return(array);
        }
コード例 #10
0
        internal void EmitCode(ILightNodeOptions options, HttpContext httpContext)
        {
            httpContext.Response.StatusCode = (int)StatusCode;
   
            if (content != null)
            {
                contentFormatter = contentFormatter ?? options.DefaultFormatter;
                var encoding = contentFormatter.Encoding;
                var responseHeader = httpContext.Response.Headers;
                responseHeader["Content-Type"] = new[] { contentFormatter.MediaType + ((encoding == null) ? "" : "; charset=" + encoding.WebName) };

                contextEmitter?.Invoke(httpContext);

                var responseStream = httpContext.Response.Body;
                if (options.StreamWriteOption == StreamWriteOption.DirectWrite)
                {
                    contentFormatter.Serialize(new UnclosableStream(responseStream), content);
                }
                else
                {
                    using (var buffer = new MemoryStream())
                    {
                        contentFormatter.Serialize(new UnclosableStream(buffer), content);
                        responseHeader["Content-Length"] = new[] { buffer.Position.ToString() };
                        buffer.Position = 0;
                        if (options.StreamWriteOption == StreamWriteOption.BufferAndWrite)
                        {
                            buffer.CopyTo(responseStream); // not CopyToAsync
                        }
                        else
                        {
                            // EmitCode is void:)
                            buffer.CopyTo(responseStream);
                        }
                    }
                }
            }
        }
コード例 #11
0
        internal void EmitCode(ILightNodeOptions options, HttpContext httpContext)
        {
            httpContext.Response.StatusCode = (int)StatusCode;

            if (content != null)
            {
                contentFormatter = contentFormatter ?? options.DefaultFormatter;
                var encoding       = contentFormatter.Encoding;
                var responseHeader = httpContext.Response.Headers;
                responseHeader["Content-Type"] = new[] { contentFormatter.MediaType + ((encoding == null) ? "" : "; charset=" + encoding.WebName) };

                contextEmitter?.Invoke(httpContext);

                var responseStream = httpContext.Response.Body;
                if (options.StreamWriteOption == StreamWriteOption.DirectWrite)
                {
                    contentFormatter.Serialize(new UnclosableStream(responseStream), content);
                }
                else
                {
                    using (var buffer = new MemoryStream())
                    {
                        contentFormatter.Serialize(new UnclosableStream(buffer), content);
                        responseHeader["Content-Length"] = new[] { buffer.Position.ToString() };
                        buffer.Position = 0;
                        if (options.StreamWriteOption == StreamWriteOption.BufferAndWrite)
                        {
                            buffer.CopyTo(responseStream); // not CopyToAsync
                        }
                        else
                        {
                            // EmitCode is void:)
                            buffer.CopyTo(responseStream);
                        }
                    }
                }
            }
        }
コード例 #12
0
        static bool IsRethrowOrEmitException(IOperationCoordinator coordinator, ILightNodeOptions options, IDictionary <string, object> environment, Exception ex)
        {
            var exString = ex.ToString();

            coordinator.OnProcessInterrupt(options, environment, InterruptReason.ExecuteFailed, exString);
            switch (options.ErrorHandlingPolicy)
            {
            case ErrorHandlingPolicy.ReturnInternalServerError:
                environment.EmitInternalServerError();
                environment.EmitStringMessage("500 InternalServerError");
                return(false);

            case ErrorHandlingPolicy.ReturnInternalServerErrorIncludeErrorDetails:
                environment.EmitInternalServerError();
                environment.EmitStringMessage(exString);
                return(false);

            case ErrorHandlingPolicy.ThrowException:
            default:
                environment.EmitInternalServerError();
                return(true);
            }
        }
コード例 #13
0
        public OperationHandler(ILightNodeOptions options, Type classType, MethodInfo methodInfo)
        {
            this.ClassName  = classType.Name;
            this.MethodName = methodInfo.Name;
            this.Arguments  = methodInfo.GetParameters()
                              .Select(x => new ParameterInfoSlim(x))
                              .ToArray();
            this.ParameterNames = Arguments.Select(x => x.Name).ToList().AsReadOnly();
            this.ReturnType     = methodInfo.ReturnType;

            this.filters = options.Filters
                           .Concat(classType.GetCustomAttributes <LightNodeFilterAttribute>(true))
                           .Concat(methodInfo.GetCustomAttributes <LightNodeFilterAttribute>(true))
                           .OrderBy(x => x.Order)
                           .ToArray();

            var operationOption = methodInfo.GetCustomAttributes <OperationOptionAttribute>(true).FirstOrDefault()
                                  ?? classType.GetCustomAttributes <OperationOptionAttribute>(true).FirstOrDefault();

            this.AcceptVerb = (operationOption != null && operationOption.AcceptVerbs != null)
                ? operationOption.AcceptVerbs.Value
                : options.DefaultAcceptVerb;

            var verbSpecifiedAttr = methodInfo.GetCustomAttributes <HttpVerbAttribtue>(true);

            if (verbSpecifiedAttr.Any())
            {
                this.AcceptVerb = verbSpecifiedAttr.Aggregate((AcceptVerbs)0, (x, y) => x | y.AcceptVerbs);
            }

            this.ForceUseFormatter = (operationOption != null && operationOption.ContentFormatter != null)
                ? operationOption.ContentFormatter
                : null;
            var formatterChoiceBase = new[] { options.DefaultFormatter }.Concat(options.SpecifiedFormatters).Where(x => x != null).ToArray();

            this.optionFormatters           = formatterChoiceBase;
            this.formatterByExt             = formatterChoiceBase.SelectMany(x => (x.Ext ?? "").Split('|'), (fmt, ext) => new { fmt, ext }).ToLookup(x => x.ext, x => x.fmt, StringComparer.OrdinalIgnoreCase);
            this.formatterByMediaType       = formatterChoiceBase.ToLookup(x => x.MediaType, StringComparer.OrdinalIgnoreCase);
            this.formatterByContentEncoding = formatterChoiceBase.ToLookup(x => x.ContentEncoding, StringComparer.OrdinalIgnoreCase);

            this.AttributeLookup = classType.GetCustomAttributes(true)
                                   .Concat(methodInfo.GetCustomAttributes(true))
                                   .Cast <Attribute>()
                                   .ToLookup(x => x.GetType());

            foreach (var argument in this.Arguments)
            {
                if (!TypeBinder.IsAllowType(argument.ParameterType))
                {
                    throw new InvalidOperationException(string.Format("parameter is not allowed, class:{0} method:{1} paramName:{2} paramType:{3}",
                                                                      classType.Name, methodInfo.Name, argument.Name, argument.ParameterType.FullName));
                }
            }

            // prepare lambda parameters
            var envArg     = Expression.Parameter(typeof(IDictionary <string, object>), "environment");
            var envBind = Expression.Bind(typeof(LightNodeContract).GetProperty("Environment"), envArg);
            var args       = Expression.Parameter(typeof(object[]), "args");
            var parameters = methodInfo.GetParameters()
                             .Select((x, i) => Expression.Convert(Expression.ArrayIndex(args, Expression.Constant(i)), x.ParameterType))
                             .ToArray();

            // Task or Task<T>
            if (typeof(Task).IsAssignableFrom(this.ReturnType))
            {
                // (object[] args) => new X().M((T1)args[0], (T2)args[1])...
                var lambda = Expression.Lambda <Func <IDictionary <string, object>, object[], Task> >(
                    Expression.Call(
                        Expression.MemberInit(Expression.New(classType), envBind),
                        methodInfo,
                        parameters),
                    envArg, args);

                if (this.ReturnType.IsGenericType && this.ReturnType.GetGenericTypeDefinition() == typeof(Task <>))
                {
                    this.handlerBodyType     = HandlerBodyType.AsyncFunc;
                    this.methodAsyncFuncBody = lambda.Compile();

                    lock (taskResultExtractors)
                    {
                        if (!taskResultExtractors.ContainsKey(this.ReturnType))
                        {
                            // (object task) => (object)((Task<>).Result)
                            var taskParameter = Expression.Parameter(typeof(object), "task");
                            var resultLambda  = Expression.Lambda <Func <object, object> >(
                                Expression.Convert(
                                    Expression.Property(
                                        Expression.Convert(taskParameter, this.ReturnType),
                                        "Result"),
                                    typeof(object)),
                                taskParameter);

                            var compiledResultLambda = resultLambda.Compile();

                            taskResultExtractors[this.ReturnType] = compiledResultLambda;
                        }
                    }
                }
                else
                {
                    this.handlerBodyType       = HandlerBodyType.AsyncAction;
                    this.methodAsyncActionBody = lambda.Compile();
                }
            }
            else if (this.ReturnType == typeof(void)) // of course void
            {
                // (object[] args) => { new X().M((T1)args[0], (T2)args[1])... }
                var lambda = Expression.Lambda <Action <IDictionary <string, object>, object[]> >(
                    Expression.Call(
                        Expression.MemberInit(Expression.New(classType), envBind),
                        methodInfo,
                        parameters),
                    envArg, args);

                this.handlerBodyType  = HandlerBodyType.Action;
                this.methodActionBody = lambda.Compile();
            }
            else // return T
            {
                // (object[] args) => (object)new X().M((T1)args[0], (T2)args[1])...
                var lambda = Expression.Lambda <Func <IDictionary <string, object>, object[], object> >(
                    Expression.Convert(
                        Expression.Call(
                            Expression.MemberInit(Expression.New(classType), envBind),
                            methodInfo,
                            parameters)
                        , typeof(object)),
                    envArg, args);

                this.handlerBodyType = HandlerBodyType.Func;
                this.methodFuncBody  = lambda.Compile();
            }
        }
コード例 #14
0
 Task InvokeRecursive(int index, IReadOnlyList <LightNodeFilterAttribute> filters, ILightNodeOptions options, OperationContext context, IOperationCoordinator coordinator)
 {
     index += 1;
     if (filters.Count != index)
     {
         // chain next filter
         return(filters[index].Invoke(context, () => InvokeRecursive(index, filters, options, context, coordinator)));
     }
     else
     {
         // execute operation
         return(coordinator.ExecuteOperation(options, context, ExecuteOperation));
     }
 }
コード例 #15
0
        // Accept, Accept-Encoding flow
        internal IContentFormatter NegotiateFormat(IDictionary <string, object> environment, string ext, ILightNodeOptions options, IOperationCoordinator coorinator)
        {
            var requestHeader = environment["owin.RequestHeaders"] as IDictionary <string, string[]>;

            string[] accepts;
            if (ForceUseFormatter != null)
            {
                return(ForceUseFormatter);
            }
            if (!string.IsNullOrWhiteSpace(ext))
            {
                // Ext match -> ContentEncoding match
                var selectedFormatters = formatterByExt[ext] as ICollection <IContentFormatter> ?? formatterByExt[ext].ToArray();
                if (!selectedFormatters.Any())
                {
                    coorinator.OnProcessInterrupt(options, environment, InterruptReason.NegotiateFormatFailed, "Ext:" + ext);
                    options.Logger.NegotiateFormatFailed(OperationMissingKind.NegotiateFormatFailed, ext);
                    if (options.OperationMissingHandlingPolicy == OperationMissingHandlingPolicy.ThrowException)
                    {
                        throw new NegotiateFormatFailedException(OperationMissingKind.NegotiateFormatFailed, ext);
                    }
                    else
                    {
                        environment.EmitNotAcceptable();
                        if (options.OperationMissingHandlingPolicy == OperationMissingHandlingPolicy.ReturnErrorStatusCodeIncludeErrorDetails)
                        {
                            environment.EmitStringMessage("NegotiateFormat failed, ext:" + ext);
                        }
                    }
                    return(null);
                }

                return(SelectAcceptEncodingFormatter(requestHeader, selectedFormatters));
            }
            else if (requestHeader.TryGetValue("Accept", out accepts))
            {
                if (optionFormatters.Length == 1)
                {
                    return(options.DefaultFormatter);                              // optimize path, defaultFormatter only
                }
                // MediaType match -> ContentEncoding match
                var acceptsValues = GetDescendingQualityHeaderValues(accepts);
                var formatters    = acceptsValues.SelectMany(x => formatterByMediaType[x.Item3]).ToArray();

                if (formatters.Length == 0)
                {
                    // only accept-encoding
                    goto CONTENT_ENCODING_MATCH;
                }

                return(SelectAcceptEncodingFormatter(requestHeader, formatters));
            }

            // ContentEncoding match
CONTENT_ENCODING_MATCH:
            {
                if (optionFormatters.Length == 1)
                {
                    return(options.DefaultFormatter);                              // optimize path, defaultFormatter only
                }
                // ContentEncoding match
                string[] rawAcceptEncoding;
                if (!requestHeader.TryGetValue("Accept-Encoding", out rawAcceptEncoding))
                {
                    return(options.DefaultFormatter);
                }

                var acceptEncodings = GetDescendingQualityHeaderValues(rawAcceptEncoding);
                var formatter       = acceptEncodings
                                      .Select(kvp => formatterByContentEncoding[kvp.Item3].FirstOrDefault())
                                      .FirstOrDefault(x => x != null);

                if (formatter == null)
                {
                    return(options.DefaultFormatter);
                }
                return(formatter);
            }
        }
コード例 #16
0
 public void OnProcessInterrupt(ILightNodeOptions options, IDictionary<string, object> environment, InterruptReason reason, string detail)
 {
     MessageBroker.Publish(new InterruptMessage() { Reason = reason, Detail = detail });
 }
コード例 #17
0
 public virtual bool OnStartProcessRequest(ILightNodeOptions options, HttpContext httpContext)
 {
     return true;
 }
コード例 #18
0
 public virtual IReadOnlyList<LightNodeFilterAttribute> GetFilters(ILightNodeOptions options, OperationContext context, IReadOnlyList<LightNodeFilterAttribute> originalFilters)
 {
     return originalFilters;
 }
コード例 #19
0
 public virtual bool OnStartProcessRequest(ILightNodeOptions options, IDictionary <string, object> environment)
 {
     return(true);
 }
コード例 #20
0
 public virtual bool OnStartProcessRequest(ILightNodeOptions options, HttpContext httpContext)
 {
     return(true);
 }
コード例 #21
0
ファイル: LightNodeServer.cs プロジェクト: neuecc/LightNode
 static bool IsRethrowOrEmitException(IOperationCoordinator coordinator, ILightNodeOptions options, IDictionary<string, object> environment, Exception ex)
 {
     var exString = ex.ToString();
     coordinator.OnProcessInterrupt(options, environment, InterruptReason.ExecuteFailed, exString);
     switch (options.ErrorHandlingPolicy)
     {
         case ErrorHandlingPolicy.ReturnInternalServerError:
             environment.EmitInternalServerError();
             environment.EmitStringMessage("500 InternalServerError");
             return false;
         case ErrorHandlingPolicy.ReturnInternalServerErrorIncludeErrorDetails:
             environment.EmitInternalServerError();
             environment.EmitStringMessage(exString);
             return false;
         case ErrorHandlingPolicy.ThrowException:
         default:
             environment.EmitInternalServerError();
             return true;
     }
 }
コード例 #22
0
ファイル: LightNodeServer.cs プロジェクト: neuecc/LightNode
 public LightNodeServer(ILightNodeOptions options)
 {
     this.options = options;
 }
コード例 #23
0
        public async Task<object> ExecuteOperation(ILightNodeOptions options, OperationContext context, Func<ILightNodeOptions, OperationContext, Task<object>> originalOperation)
        {
            if (MessageBroker == null || Timer == null) return await originalOperation(options, context);
            var timer = Timer;

            object result;
            var start = timer.Start();
            try
            {
                result = await originalOperation(options, context);

                var stop = timer.Stop(start);

                var message = new LightNodeExecuteResultMessage()
                    {
                        ContractName = context.ContractName,
                        OperationName = context.OperationName,
                        Result = result,
                        Environment = context.Environment,
                        UsedContentFormatter = context.ContentFormatter,
                        Options = options,
                        FromRequestStart = timer.Point().Offset,
                        Phase = OperationPhase.Operation
                    }
                    .AsTimelineMessage(context.ToString(), OperationCategory)
                    .AsTimedMessage(stop);
                MessageBroker.Publish(message);
                return result;
            }
            catch (Exception ex)
            {
                var stop = timer.Stop(start);

                var message = new LightNodeExecuteResultMessage()
                    {
                        ContractName = context.ContractName,
                        OperationName = context.OperationName,
                        Result = ex.ToString(),
                        Environment = context.Environment,
                        UsedContentFormatter = context.ContentFormatter,
                        Options = options,
                        FromRequestStart = timer.Point().Offset,
                        Phase = (ex is ReturnStatusCodeException) ? OperationPhase.ReturnStatusCode : OperationPhase.Exception
                    }
                    .AsTimelineMessage(context.ToString(), OperationCategory)
                    .AsTimedMessage(stop);
                MessageBroker.Publish(message);

                throw;
            }
        }
コード例 #24
0
 public virtual void OnProcessInterrupt(ILightNodeOptions options, HttpContext httpContext, InterruptReason reason, string detail)
 {
 }
コード例 #25
0
 public virtual void OnProcessInterrupt(ILightNodeOptions options, IDictionary<string, object> environment, InterruptReason reason, string detail)
 {
 }
コード例 #26
0
 public virtual IReadOnlyList <LightNodeFilterAttribute> GetFilters(ILightNodeOptions options, OperationContext context, IReadOnlyList <LightNodeFilterAttribute> originalFilters)
 {
     return(originalFilters);
 }
コード例 #27
0
 public RegisteredHandlersInfo(string engineId, ILightNodeOptions options, IReadOnlyCollection <KeyValuePair <string, OperationInfo> > registeredHandlers)
 {
     this.EngineId           = engineId;
     this.Options            = options;
     this.RegisteredHandlers = registeredHandlers;
 }
コード例 #28
0
 public virtual Task<object> ExecuteOperation(ILightNodeOptions options, OperationContext context, Func<ILightNodeOptions, OperationContext, Task<object>> originalOperation)
 {
     return originalOperation(options, context);
 }
コード例 #29
0
 public virtual void OnProcessInterrupt(ILightNodeOptions options, HttpContext httpContext, InterruptReason reason, string detail)
 {
 }
コード例 #30
0
 public static IAppBuilder UseLightNode(this IAppBuilder app, ILightNodeOptions options)
 {
     return(app.Use(typeof(LightNodeServerMiddleware), options));
 }
コード例 #31
0
 public virtual void OnProcessInterrupt(ILightNodeOptions options, IDictionary <string, object> environment, InterruptReason reason, string detail)
 {
 }
コード例 #32
0
 public LightNodeServerMiddleware(AppFunc next, ILightNodeOptions options)
     : this(next, options, AppDomain.CurrentDomain.GetAssemblies())
 {
 }
コード例 #33
0
 public virtual Task <object> ExecuteOperation(ILightNodeOptions options, OperationContext context, Func <ILightNodeOptions, OperationContext, Task <object> > originalOperation)
 {
     return(originalOperation(options, context));
 }
コード例 #34
0
 public static IAppBuilder UseLightNode(this IAppBuilder app, ILightNodeOptions options, params Assembly[] hostAssemblies)
 {
     return app.Use(typeof(LightNodeServerMiddleware), options, hostAssemblies);
 }
コード例 #35
0
 public static IAppBuilder UseLightNode(this IAppBuilder app, ILightNodeOptions options, params Assembly[] hostAssemblies)
 {
     return(app.Use(typeof(LightNodeServerMiddleware), options, hostAssemblies));
 }
コード例 #36
0
#pragma warning restore 618

        public bool OnStartProcessRequest(ILightNodeOptions options, IDictionary<string, object> environment)
        {
            MessageBroker.Publish(new ProcessStartMessage() { Options = options, Environment = environment });
            return true;
        }
コード例 #37
0
 public LightNodeServerMiddleware(AppFunc next, ILightNodeOptions options)
     : this(next, options, AppDomain.CurrentDomain.GetAssemblies())
 {
 }
コード例 #38
0
 public static IApplicationBuilder UseLightNode(this IApplicationBuilder app, ILightNodeOptions options, params Assembly[] hostAssemblies)
 {
     return(app.UseMiddleware <LightNodeServerMiddleware>(options, hostAssemblies));
 }
コード例 #39
0
 public RegisteredHandlersInfo(string engineId, ILightNodeOptions options, IReadOnlyCollection<KeyValuePair<string, OperationInfo>> registeredHandlers)
 {
     this.EngineId = engineId;
     this.Options = options;
     this.RegisteredHandlers = registeredHandlers;
 }
コード例 #40
0
 public static IApplicationBuilder UseLightNode(this IApplicationBuilder app, ILightNodeOptions options, Assembly[] hostAssemblies)
 {
     return app.UseMiddleware<LightNodeServerMiddleware>(options, hostAssemblies);
 }
コード例 #41
0
 public static IAppBuilder UseLightNode(this IAppBuilder app, ILightNodeOptions options)
 {
     return app.Use(typeof(LightNodeServerMiddleware), options);
 }
コード例 #42
0
        // Accept, Accept-Encoding flow
        internal IContentFormatter NegotiateFormat(IDictionary<string, object> environment, string ext, ILightNodeOptions options, IOperationCoordinator coorinator)
        {
            var requestHeader = environment["owin.RequestHeaders"] as IDictionary<string, string[]>;

            string[] accepts;
            if (ForceUseFormatter != null) return ForceUseFormatter;
            if (!string.IsNullOrWhiteSpace(ext))
            {
                // Ext match -> ContentEncoding match
                var selectedFormatters = formatterByExt[ext] as ICollection<IContentFormatter> ?? formatterByExt[ext].ToArray();
                if (!selectedFormatters.Any())
                {
                    coorinator.OnProcessInterrupt(options, environment, InterruptReason.NegotiateFormatFailed, "Ext:" + ext);
                    options.Logger.NegotiateFormatFailed(OperationMissingKind.NegotiateFormatFailed, ext);
                    if (options.OperationMissingHandlingPolicy == OperationMissingHandlingPolicy.ThrowException)
                    {
                        throw new NegotiateFormatFailedException(OperationMissingKind.NegotiateFormatFailed, ext);
                    }
                    else
                    {
                        environment.EmitNotAcceptable();
                        if (options.OperationMissingHandlingPolicy == OperationMissingHandlingPolicy.ReturnErrorStatusCodeIncludeErrorDetails)
                        {
                            environment.EmitStringMessage("NegotiateFormat failed, ext:" + ext);
                        }
                    }
                    return null;
                }

                return SelectAcceptEncodingFormatter(requestHeader, selectedFormatters);
            }
            else if (requestHeader.TryGetValue("Accept", out accepts))
            {
                if (optionFormatters.Length == 1) return options.DefaultFormatter; // optimize path, defaultFormatter only

                // MediaType match -> ContentEncoding match
                var acceptsValues = GetDescendingQualityHeaderValues(accepts);
                var formatters = acceptsValues.SelectMany(x => formatterByMediaType[x.Item3]).ToArray();

                if (formatters.Length == 0)
                {
                    // only accept-encoding
                    goto CONTENT_ENCODING_MATCH;
                }

                return SelectAcceptEncodingFormatter(requestHeader, formatters);
            }

            // ContentEncoding match
            CONTENT_ENCODING_MATCH:
            {
                if (optionFormatters.Length == 1) return options.DefaultFormatter; // optimize path, defaultFormatter only

                // ContentEncoding match
                string[] rawAcceptEncoding;
                if (!requestHeader.TryGetValue("Accept-Encoding", out rawAcceptEncoding))
                {
                    return options.DefaultFormatter;
                }

                var acceptEncodings = GetDescendingQualityHeaderValues(rawAcceptEncoding);
                var formatter = acceptEncodings
                    .Select(kvp => formatterByContentEncoding[kvp.Item3].FirstOrDefault())
                    .FirstOrDefault(x => x != null);

                if (formatter == null) return options.DefaultFormatter;
                return formatter;
            }
        }
コード例 #43
0
 public LightNodeServer(ILightNodeOptions options)
 {
     this.options = options;
 }
コード例 #44
0
        public Task Execute(ILightNodeOptions options, OperationContext context, IOperationCoordinator coordinator)
        {
            var targetFilters = coordinator.GetFilters(options, context, filters);

            return InvokeRecursive(-1, targetFilters, options, context, coordinator);
        }
コード例 #45
0
        internal static object[] BindParameter(HttpContext httpContext, ILightNodeOptions options, IOperationCoordinator coordinator, ValueProvider valueProvider, ParameterInfoSlim[] arguments)
        {
            var methodParameters = new object[arguments.Length];

            for (int 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;
                    }
                    else if ((!item.ParameterTypeIsString || options.ParameterStringImplicitNullAsDefault) && (item.ParameterTypeIsClass || item.ParameterTypeIsNullable))
                    {
                        methodParameters[i] = null;
                        continue;
                    }
                    else
                    {
                        coordinator.OnProcessInterrupt(options, httpContext, InterruptReason.ParameterBindMissing, "Lack of Parameter:" + item.Name);
                        options.Logger.ParameterBindMissing(OperationMissingKind.LackOfParameter, item.Name);
                        if (options.OperationMissingHandlingPolicy == OperationMissingHandlingPolicy.ThrowException)
                        {
                            throw new ParameterMissingException(OperationMissingKind.LackOfParameter, item.Name);
                        }
                        else
                        {
                            httpContext.EmitBadRequest();
                            if (options.OperationMissingHandlingPolicy == OperationMissingHandlingPolicy.ReturnErrorStatusCodeIncludeErrorDetails)
                            {
                                httpContext.EmitStringMessage("Lack of Parameter:" + item.Name);
                            }
                            return(null);
                        }
                    }
                }
                else if (!item.ParameterTypeIsArray)
                {
                    var conv = TypeBinder.GetConverter(item.ParameterType, !options.ParameterEnumAllowsFieldNameParse);
                    if (conv == null)
                    {
                        throw new InvalidOperationException("critical:register code is broken");
                    }

                    object pValue;
                    if (conv(value ?? values[0], out pValue))
                    {
                        methodParameters[i] = pValue;
                        continue;
                    }
                    else if (item.IsOptional)
                    {
                        methodParameters[i] = item.DefaultValue;
                        continue;
                    }
                    else if ((!item.ParameterTypeIsString || options.ParameterStringImplicitNullAsDefault) && (item.ParameterTypeIsClass || item.ParameterTypeIsNullable))
                    {
                        methodParameters[i] = null;
                        continue;
                    }
                    else
                    {
                        coordinator.OnProcessInterrupt(options, httpContext, InterruptReason.ParameterBindMissing, "Mismatch ParameterType:" + item.Name);
                        options.Logger.ParameterBindMissing(OperationMissingKind.MissmatchParameterType, item.Name);
                        if (options.OperationMissingHandlingPolicy == OperationMissingHandlingPolicy.ThrowException)
                        {
                            throw new ParameterMissingException(OperationMissingKind.MissmatchParameterType, item.Name);
                        }
                        else
                        {
                            httpContext.EmitBadRequest();
                            if (options.OperationMissingHandlingPolicy == OperationMissingHandlingPolicy.ReturnErrorStatusCodeIncludeErrorDetails)
                            {
                                httpContext.EmitStringMessage("Mismatch ParameterType:" + item.Name);
                            }
                            return(null);
                        }
                    }
                }

                var arrayConv = TypeBinder.GetArrayConverter(item.ParameterType, !options.ParameterEnumAllowsFieldNameParse);
                if (arrayConv == null)
                {
                    throw new InvalidOperationException("critical:register code is broken");
                }

                methodParameters[i] = arrayConv((values != null) ? values : (value != null) ? new[] { value } : (IList <string>) new string[0]);
                continue;
            }

            return(methodParameters);
        }
コード例 #46
0
 Task InvokeRecursive(int index, IReadOnlyList<LightNodeFilterAttribute> filters, ILightNodeOptions options, OperationContext context, IOperationCoordinator coordinator)
 {
     index += 1;
     if (filters.Count != index)
     {
         // chain next filter
         return filters[index].Invoke(context, () => InvokeRecursive(index, filters, options, context, coordinator));
     }
     else
     {
         // execute operation
         return coordinator.ExecuteOperation(options, context, ExecuteOperation);
     }
 }
コード例 #47
0
        public Task Execute(ILightNodeOptions options, OperationContext context, IOperationCoordinator coordinator)
        {
            var targetFilters = coordinator.GetFilters(options, context, filters);

            return(InvokeRecursive(-1, targetFilters, options, context, coordinator));
        }
コード例 #48
0
        async Task<object> ExecuteOperation(ILightNodeOptions options, OperationContext context)
        {
            // prepare
            var handler = this;
            var environment = context.Environment;
            var methodParameters = (object[])context.Parameters;

            bool isVoid = true;
            object result = null;
            switch (handler.handlerBodyType)
            {
                case HandlerBodyType.Action:
                    handler.methodActionBody(environment, methodParameters);
                    break;
                case HandlerBodyType.Func:
                    isVoid = false;
                    result = handler.methodFuncBody(environment, methodParameters);
                    break;
                case HandlerBodyType.AsyncAction:
                    var actionTask = handler.methodAsyncActionBody(environment, methodParameters);
                    await actionTask.ConfigureAwait(false);
                    break;
                case HandlerBodyType.AsyncFunc:
                    isVoid = false;
                    var funcTask = handler.methodAsyncFuncBody(environment, methodParameters);
                    await funcTask.ConfigureAwait(false);
                    var extractor = taskResultExtractors[FindTaskType(funcTask.GetType())];
                    result = extractor(funcTask);
                    break;
                default:
                    throw new InvalidOperationException("critical:register code is broken");
            }

            if (!isVoid)
            {
                // append header
                var responseHeader = environment["owin.ResponseHeaders"] as IDictionary<string, string[]>;
                var encoding = context.ContentFormatter.Encoding;
                responseHeader["Content-Type"] = new[] { context.ContentFormatter.MediaType + ((encoding == null) ? "" : "; charset=" + encoding.WebName) };
                if (!string.IsNullOrWhiteSpace(context.ContentFormatter.ContentEncoding))
                {
                    responseHeader["Content-Encoding"] = new[] { context.ContentFormatter.ContentEncoding };
                }
                environment.EmitOK();

                var responseStream = environment["owin.ResponseBody"] as Stream;
                if (options.StreamWriteOption == StreamWriteOption.DirectWrite)
                {
                    context.ContentFormatter.Serialize(new UnclosableStream(responseStream), result);
                }
                else
                {
                    using (var buffer = new MemoryStream())
                    {
                        context.ContentFormatter.Serialize(new UnclosableStream(buffer), result);
                        responseHeader["Content-Length"] = new[] { buffer.Position.ToString() };
                        buffer.Position = 0;
                        if (options.StreamWriteOption == StreamWriteOption.BufferAndWrite)
                        {
                            buffer.CopyTo(responseStream); // not CopyToAsync
                        }
                        else
                        {
                            await buffer.CopyToAsync(responseStream).ConfigureAwait(false);
                        }
                    }
                }

                return result;
            }
            else
            {
                environment.EmitNoContent();
                return null;
            }
        }
コード例 #49
0
        async Task <object> ExecuteOperation(ILightNodeOptions options, OperationContext context)
        {
            // prepare
            var handler          = this;
            var environment      = context.Environment;
            var methodParameters = (object[])context.Parameters;

            bool   isVoid = true;
            object result = null;

            switch (handler.handlerBodyType)
            {
            case HandlerBodyType.Action:
                handler.methodActionBody(environment, methodParameters);
                break;

            case HandlerBodyType.Func:
                isVoid = false;
                result = handler.methodFuncBody(environment, methodParameters);
                break;

            case HandlerBodyType.AsyncAction:
                var actionTask = handler.methodAsyncActionBody(environment, methodParameters);
                await actionTask.ConfigureAwait(false);

                break;

            case HandlerBodyType.AsyncFunc:
                isVoid = false;
                var funcTask = handler.methodAsyncFuncBody(environment, methodParameters);
                await funcTask.ConfigureAwait(false);

                var extractor = taskResultExtractors[FindTaskType(funcTask.GetType())];
                result = extractor(funcTask);
                break;

            default:
                throw new InvalidOperationException("critical:register code is broken");
            }

            if (!isVoid)
            {
                // append header
                var responseHeader = environment["owin.ResponseHeaders"] as IDictionary <string, string[]>;
                var encoding       = context.ContentFormatter.Encoding;
                responseHeader["Content-Type"] = new[] { context.ContentFormatter.MediaType + ((encoding == null) ? "" : "; charset=" + encoding.WebName) };
                if (!string.IsNullOrWhiteSpace(context.ContentFormatter.ContentEncoding))
                {
                    responseHeader["Content-Encoding"] = new[] { context.ContentFormatter.ContentEncoding };
                }
                environment.EmitOK();

                var responseStream = environment["owin.ResponseBody"] as Stream;
                if (options.StreamWriteOption == StreamWriteOption.DirectWrite)
                {
                    context.ContentFormatter.Serialize(new UnclosableStream(responseStream), result);
                }
                else
                {
                    using (var buffer = new MemoryStream())
                    {
                        context.ContentFormatter.Serialize(new UnclosableStream(buffer), result);
                        responseHeader["Content-Length"] = new[] { buffer.Position.ToString() };
                        buffer.Position = 0;
                        if (options.StreamWriteOption == StreamWriteOption.BufferAndWrite)
                        {
                            buffer.CopyTo(responseStream); // not CopyToAsync
                        }
                        else
                        {
                            await buffer.CopyToAsync(responseStream).ConfigureAwait(false);
                        }
                    }
                }

                return(result);
            }
            else
            {
                environment.EmitNoContent();
                return(null);
            }
        }
コード例 #50
0
        public OperationHandler(ILightNodeOptions options, Type classType, MethodInfo methodInfo)
        {
            this.ClassName = classType.Name;
            this.MethodName = methodInfo.Name;
            this.Arguments = methodInfo.GetParameters()
                .Select(x => new ParameterInfoSlim(x))
                .ToArray();
            this.ParameterNames = Arguments.Select(x => x.Name).ToList().AsReadOnly();
            this.ReturnType = methodInfo.ReturnType;

            this.filters = options.Filters
                .Concat(classType.GetCustomAttributes<LightNodeFilterAttribute>(true))
                .Concat(methodInfo.GetCustomAttributes<LightNodeFilterAttribute>(true))
                .OrderBy(x => x.Order)
                .ToArray();

            var operationOption = methodInfo.GetCustomAttributes<OperationOptionAttribute>(true).FirstOrDefault()
                               ?? classType.GetCustomAttributes<OperationOptionAttribute>(true).FirstOrDefault();
            this.AcceptVerb = (operationOption != null && operationOption.AcceptVerbs != null)
                ? operationOption.AcceptVerbs.Value
                : options.DefaultAcceptVerb;

            var verbSpecifiedAttr = methodInfo.GetCustomAttributes<HttpVerbAttribtue>(true);
            if (verbSpecifiedAttr.Any())
            {
                this.AcceptVerb = verbSpecifiedAttr.Aggregate((AcceptVerbs)0, (x, y) => x | y.AcceptVerbs);
            }

            this.ForceUseFormatter = (operationOption != null && operationOption.ContentFormatter != null)
                ? operationOption.ContentFormatter
                : null;
            var formatterChoiceBase = new[] { options.DefaultFormatter }.Concat(options.SpecifiedFormatters).Where(x => x != null).ToArray();
            this.optionFormatters = formatterChoiceBase;
            this.formatterByExt = formatterChoiceBase.SelectMany(x => (x.Ext ?? "").Split('|'), (fmt, ext) => new { fmt, ext }).ToLookup(x => x.ext, x => x.fmt, StringComparer.OrdinalIgnoreCase);
            this.formatterByMediaType = formatterChoiceBase.ToLookup(x => x.MediaType, StringComparer.OrdinalIgnoreCase);
            this.formatterByContentEncoding = formatterChoiceBase.ToLookup(x => x.ContentEncoding, StringComparer.OrdinalIgnoreCase);

            this.AttributeLookup = classType.GetCustomAttributes(true)
                .Concat(methodInfo.GetCustomAttributes(true))
                .Cast<Attribute>()
                .ToLookup(x => x.GetType());

            foreach (var argument in this.Arguments)
            {
                if (!TypeBinder.IsAllowType(argument.ParameterType))
                {
                    throw new InvalidOperationException(string.Format("parameter is not allowed, class:{0} method:{1} paramName:{2} paramType:{3}",
                        classType.Name, methodInfo.Name, argument.Name, argument.ParameterType.FullName));
                }
            }

            // prepare lambda parameters
            var envArg = Expression.Parameter(typeof(IDictionary<string, object>), "environment");
            var envBind = Expression.Bind(typeof(LightNodeContract).GetProperty("Environment"), envArg);
            var args = Expression.Parameter(typeof(object[]), "args");
            var parameters = methodInfo.GetParameters()
                .Select((x, i) => Expression.Convert(Expression.ArrayIndex(args, Expression.Constant(i)), x.ParameterType))
                .ToArray();

            // Task or Task<T>
            if (typeof(Task).IsAssignableFrom(this.ReturnType))
            {
                // (object[] args) => new X().M((T1)args[0], (T2)args[1])...
                var lambda = Expression.Lambda<Func<IDictionary<string, object>, object[], Task>>(
                    Expression.Call(
                        Expression.MemberInit(Expression.New(classType), envBind),
                        methodInfo,
                        parameters),
                    envArg, args);

                if (this.ReturnType.IsGenericType && this.ReturnType.GetGenericTypeDefinition() == typeof(Task<>))
                {
                    this.handlerBodyType = HandlerBodyType.AsyncFunc;
                    this.methodAsyncFuncBody = lambda.Compile();

                    lock (taskResultExtractors)
                    {
                        if (!taskResultExtractors.ContainsKey(this.ReturnType))
                        {
                            // (object task) => (object)((Task<>).Result)
                            var taskParameter = Expression.Parameter(typeof(object), "task");
                            var resultLambda = Expression.Lambda<Func<object, object>>(
                                Expression.Convert(
                                    Expression.Property(
                                        Expression.Convert(taskParameter, this.ReturnType),
                                        "Result"),
                                    typeof(object)),
                                taskParameter);

                            var compiledResultLambda = resultLambda.Compile();

                            taskResultExtractors[this.ReturnType] = compiledResultLambda;
                        }
                    }
                }
                else
                {
                    this.handlerBodyType = HandlerBodyType.AsyncAction;
                    this.methodAsyncActionBody = lambda.Compile();
                }
            }
            else if (this.ReturnType == typeof(void)) // of course void
            {
                // (object[] args) => { new X().M((T1)args[0], (T2)args[1])... }
                var lambda = Expression.Lambda<Action<IDictionary<string, object>, object[]>>(
                    Expression.Call(
                        Expression.MemberInit(Expression.New(classType), envBind),
                        methodInfo,
                        parameters),
                    envArg, args);

                this.handlerBodyType = HandlerBodyType.Action;
                this.methodActionBody = lambda.Compile();
            }
            else // return T
            {
                // (object[] args) => (object)new X().M((T1)args[0], (T2)args[1])...
                var lambda = Expression.Lambda<Func<IDictionary<string, object>, object[], object>>(
                    Expression.Convert(
                        Expression.Call(
                            Expression.MemberInit(Expression.New(classType), envBind),
                            methodInfo,
                            parameters)
                    , typeof(object)),
                    envArg, args);

                this.handlerBodyType = HandlerBodyType.Func;
                this.methodFuncBody = lambda.Compile();
            }
        }
コード例 #51
0
ファイル: ParameterBinder.cs プロジェクト: neuecc/LightNode
        internal static object[] BindParameter(IDictionary<string, object> environment, ILightNodeOptions options, IOperationCoordinator coordinator, ValueProvider valueProvider, ParameterInfoSlim[] arguments)
        {
            var methodParameters = new object[arguments.Length];
            for (int 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;
                var byteArray = _values as byte[];

                // TODO:Experimental support
                if (byteArray != null && item.ParameterTypeIsArray && item.ParameterType == typeof(byte[]))
                {
                    methodParameters[i] = byteArray;
                    continue;
                }

                if (isEmpty && !item.ParameterTypeIsArray)
                {
                    if (item.IsOptional)
                    {
                        methodParameters[i] = item.DefaultValue;
                        continue;
                    }
                    else if ((!item.ParameterTypeIsString || options.ParameterStringImplicitNullAsDefault) && (item.ParameterTypeIsClass || item.ParameterTypeIsNullable))
                    {
                        methodParameters[i] = null;
                        continue;
                    }
                    else
                    {
                        coordinator.OnProcessInterrupt(options, environment, InterruptReason.ParameterBindMissing, "Lack of Parameter:" + item.Name);
                        options.Logger.ParameterBindMissing(OperationMissingKind.LackOfParameter, item.Name);
                        if (options.OperationMissingHandlingPolicy == OperationMissingHandlingPolicy.ThrowException)
                        {
                            throw new ParameterMissingException(OperationMissingKind.LackOfParameter, item.Name);
                        }
                        else
                        {
                            environment.EmitBadRequest();
                            if (options.OperationMissingHandlingPolicy == OperationMissingHandlingPolicy.ReturnErrorStatusCodeIncludeErrorDetails)
                            {
                                environment.EmitStringMessage("Lack of Parameter:" + item.Name);
                            }
                            return null;
                        }
                    }
                }
                else if (!item.ParameterTypeIsArray)
                {
                    var conv = TypeBinder.GetConverter(item.ParameterType, !options.ParameterEnumAllowsFieldNameParse);
                    if (conv == null) throw new InvalidOperationException("critical:register code is broken");

                    object pValue;
                    if (conv(value ?? values[0], out pValue))
                    {
                        methodParameters[i] = pValue;
                        continue;
                    }
                    else if (item.IsOptional)
                    {
                        methodParameters[i] = item.DefaultValue;
                        continue;
                    }
                    else if ((!item.ParameterTypeIsString || options.ParameterStringImplicitNullAsDefault) && (item.ParameterTypeIsClass || item.ParameterTypeIsNullable))
                    {
                        methodParameters[i] = null;
                        continue;
                    }
                    else
                    {
                        coordinator.OnProcessInterrupt(options, environment, InterruptReason.ParameterBindMissing, "Mismatch ParameterType:" + item.Name);
                        options.Logger.ParameterBindMissing(OperationMissingKind.MissmatchParameterType, item.Name);
                        if (options.OperationMissingHandlingPolicy == OperationMissingHandlingPolicy.ThrowException)
                        {
                            throw new ParameterMissingException(OperationMissingKind.MissmatchParameterType, item.Name);
                        }
                        else
                        {
                            environment.EmitBadRequest();
                            if (options.OperationMissingHandlingPolicy == OperationMissingHandlingPolicy.ReturnErrorStatusCodeIncludeErrorDetails)
                            {
                                environment.EmitStringMessage("Mismatch ParameterType:" + item.Name);
                            }
                            return null;
                        }
                    }
                }

                var arrayConv = TypeBinder.GetArrayConverter(item.ParameterType, !options.ParameterEnumAllowsFieldNameParse);
                if (arrayConv == null) throw new InvalidOperationException("critical:register code is broken");

                methodParameters[i] = arrayConv((values != null) ? values : (value != null) ? new[] { value } : (IList<string>)new string[0]);
                continue;
            }

            return methodParameters;
        }
コード例 #52
0
 public virtual bool OnStartProcessRequest(ILightNodeOptions options, IDictionary<string, object> environment)
 {
     return true;
 }