コード例 #1
0
        internal static object StringToType(
            TypeConfig typeConfig,
            StringSegment strType,
            EmptyCtorDelegate ctorFn,
            Dictionary <HashedStringSegment, TypeAccessor> typeAccessorMap)
        {
            var index = 0;
            var type  = typeConfig.Type;

            if (!strType.HasValue)
            {
                return(null);
            }

            //if (!Serializer.EatMapStartChar(strType, ref index))
            if (strType.GetChar(index++) != JsWriter.MapStartChar)
            {
                throw DeserializeTypeRef.CreateSerializationError(type, strType.Value);
            }

            if (JsonTypeSerializer.IsEmptyMap(strType))
            {
                return(ctorFn());
            }

            object instance = null;

            var propertyResolver = JsConfig.PropertyConvention == PropertyConvention.Lenient
                ? ParseUtils.LenientPropertyNameResolver
                : ParseUtils.DefaultPropertyNameResolver;

            var strTypeLength = strType.Length;

            while (index < strTypeLength)
            {
                var propertyName = Serializer.EatMapKey(strType, ref index);

                //Serializer.EatMapKeySeperator(strType, ref index);
                index++;

                var propertyValueStr = Serializer.EatValue(strType, ref index);
                var possibleTypeInfo = propertyValueStr != null && propertyValueStr.Length > 1;

                if (possibleTypeInfo && propertyName == new StringSegment(JsWriter.TypeAttr))
                {
                    var explicitTypeName = Serializer.ParseString(propertyValueStr);
                    var explicitType     = JsConfig.TypeFinder(explicitTypeName);

                    if (explicitType == null || explicitType.IsInterface() || explicitType.IsAbstract())
                    {
                        Tracer.Instance.WriteWarning("Could not find type: " + propertyValueStr);
                    }
                    else if (!type.IsAssignableFromType(explicitType))
                    {
                        Tracer.Instance.WriteWarning("Could not assign type: " + propertyValueStr);
                    }
                    else
                    {
                        JsWriter.AssertAllowedRuntimeType(explicitType);
                        instance = explicitType.CreateInstance();
                    }

                    if (instance != null)
                    {
                        //If __type info doesn't match, ignore it.
                        if (!type.InstanceOfType(instance))
                        {
                            instance = null;
                        }
                        else
                        {
                            var derivedType = instance.GetType();
                            if (derivedType != type)
                            {
                                var derivedTypeConfig = new TypeConfig(derivedType);
                                var map = DeserializeTypeRef.GetTypeAccessorMap(derivedTypeConfig, Serializer);
                                if (map != null)
                                {
                                    typeAccessorMap = map;
                                }
                            }
                        }
                    }

                    //Serializer.EatItemSeperatorOrMapEndChar(strType, ref index);
                    if (index != strType.Length)
                    {
                        index++;
                    }

                    continue;
                }

                if (instance == null)
                {
                    instance = ctorFn();
                }

                var typeAccessor = propertyResolver.GetTypeAccessorForProperty(propertyName, typeAccessorMap);

                var propType = possibleTypeInfo && propertyValueStr.GetChar(0) == '_' ? TypeAccessor.ExtractType(Serializer, propertyValueStr) : null;
                if (propType != null)
                {
                    try
                    {
                        if (typeAccessor != null)
                        {
                            var parseFn       = Serializer.GetParseStringSegmentFn(propType);
                            var propertyValue = parseFn(propertyValueStr);
                            if (typeConfig.OnDeserializing != null)
                            {
                                propertyValue = typeConfig.OnDeserializing(instance, propertyName.Value, propertyValue);
                            }
                            typeAccessor.SetProperty(instance, propertyValue);
                        }

                        //Serializer.EatItemSeperatorOrMapEndChar(strType, ref index);
                        if (index != strType.Length)
                        {
                            index++;
                        }

                        continue;
                    }
                    catch (Exception e)
                    {
                        if (JsConfig.OnDeserializationError != null)
                        {
                            JsConfig.OnDeserializationError(instance, propType, propertyName.Value, propertyValueStr.Value, e);
                        }
                        if (JsConfig.ThrowOnDeserializationError)
                        {
                            throw DeserializeTypeRef.GetSerializationException(propertyName.Value, propertyValueStr.Value, propType, e);
                        }
                        else
                        {
                            Tracer.Instance.WriteWarning("WARN: failed to set dynamic property {0} with: {1}", propertyName, propertyValueStr);
                        }
                    }
                }

                if (typeAccessor?.GetProperty != null && typeAccessor.SetProperty != null)
                {
                    try
                    {
                        var propertyValue = typeAccessor.GetProperty(propertyValueStr);
                        if (typeConfig.OnDeserializing != null)
                        {
                            propertyValue = typeConfig.OnDeserializing(instance, propertyName.Value, propertyValue);
                        }
                        typeAccessor.SetProperty(instance, propertyValue);
                    }
                    catch (NotSupportedException) { throw; }
                    catch (Exception e)
                    {
                        if (JsConfig.OnDeserializationError != null)
                        {
                            JsConfig.OnDeserializationError(instance, propType ?? typeAccessor.PropertyType, propertyName.Value, propertyValueStr.Value, e);
                        }
                        if (JsConfig.ThrowOnDeserializationError)
                        {
                            throw DeserializeTypeRef.GetSerializationException(propertyName.Value, propertyValueStr.Value, propType, e);
                        }
                        else
                        {
                            Tracer.Instance.WriteWarning("WARN: failed to set property {0} with: {1}", propertyName, propertyValueStr);
                        }
                    }
                }
                else
                {
                    // the property is not known by the DTO
                    typeConfig.OnDeserializing?.Invoke(instance, propertyName.Value, propertyValueStr);
                }

                //Serializer.EatItemSeperatorOrMapEndChar(strType, ref index);
                if (index != strType.Length)
                {
                    index++;
                }
            }

            return(instance);
        }
コード例 #2
0
        private static bool Init()
        {
            if (!typeof(T).IsClass() && !typeof(T).IsInterface() && !JsConfig.TreatAsRefType(typeof(T)))
            {
                return(false);
            }

            var propertyInfos       = TypeConfig <T> .Properties;
            var fieldInfos          = JsConfig.IncludePublicFields ? TypeConfig <T> .Fields : new FieldInfo[0];
            var propertyNamesLength = propertyInfos.Length;
            var fieldNamesLength    = fieldInfos.Length;

            PropertyWriters = new TypePropertyWriter[propertyNamesLength + fieldNamesLength];

            if (propertyNamesLength + fieldNamesLength == 0 && !JsState.IsWritingDynamic)
            {
                return(typeof(T).IsDto());
            }

            // NOTE: very limited support for DataContractSerialization (DCS)
            //	NOT supporting Serializable
            //	support for DCS is intended for (re)Name of properties and Ignore by NOT having a DataMember present
            var isDataContract = typeof(T).IsDto();

            for (var i = 0; i < propertyNamesLength; i++)
            {
                var propertyInfo = propertyInfos[i];

                string propertyName, propertyNameCLSFriendly, propertyNameLowercaseUnderscore, propertyReflectedName;
                int    propertyOrder = -1;
                var    propertyType  = propertyInfo.PropertyType;
                var    defaultValue  = propertyType.GetDefaultValue();
                bool   propertySuppressDefaultConfig    = defaultValue != null && propertyType.IsValueType() && JsConfig.HasSerializeFn.Contains(propertyType);
                bool   propertySuppressDefaultAttribute = false;

                if (isDataContract)
                {
                    var dcsDataMember = propertyInfo.GetDataMember();
                    if (dcsDataMember == null)
                    {
                        continue;
                    }

                    propertyName                     = dcsDataMember.Name ?? propertyInfo.Name;
                    propertyNameCLSFriendly          = dcsDataMember.Name ?? propertyName.ToCamelCase();
                    propertyNameLowercaseUnderscore  = dcsDataMember.Name ?? propertyName.ToLowercaseUnderscore();
                    propertyReflectedName            = dcsDataMember.Name ?? propertyInfo.ReflectedType.Name;
                    propertyOrder                    = dcsDataMember.Order;
                    propertySuppressDefaultAttribute = !dcsDataMember.EmitDefaultValue;
                }
                else
                {
                    propertyName                    = propertyInfo.Name;
                    propertyNameCLSFriendly         = propertyName.ToCamelCase();
                    propertyNameLowercaseUnderscore = propertyName.ToLowercaseUnderscore();
                    propertyReflectedName           = propertyInfo.ReflectedType.Name;
                }


                PropertyWriters[i] = new TypePropertyWriter
                                     (
                    propertyName,
                    propertyReflectedName,
                    propertyNameCLSFriendly,
                    propertyNameLowercaseUnderscore,
                    propertyOrder,
                    propertySuppressDefaultConfig,
                    propertySuppressDefaultAttribute,
                    propertyInfo.GetValueGetter <T>(),
                    Serializer.GetWriteFn(propertyType),
                    propertyType.GetDefaultValue()
                                     );
            }

            for (var i = 0; i < fieldNamesLength; i++)
            {
                var fieldInfo = fieldInfos[i];

                string propertyName, propertyNameCLSFriendly, propertyNameLowercaseUnderscore, propertyReflectedName;
                int    propertyOrder = -1;
                var    propertyType  = fieldInfo.FieldType;
                var    defaultValue  = propertyType.GetDefaultValue();
                bool   propertySuppressDefaultConfig    = defaultValue != null && propertyType.IsValueType() && JsConfig.HasSerializeFn.Contains(propertyType);
                bool   propertySuppressDefaultAttribute = false;

                if (isDataContract)
                {
                    var dcsDataMember = fieldInfo.GetDataMember();
                    if (dcsDataMember == null)
                    {
                        continue;
                    }

                    propertyName                     = dcsDataMember.Name ?? fieldInfo.Name;
                    propertyNameCLSFriendly          = dcsDataMember.Name ?? propertyName.ToCamelCase();
                    propertyNameLowercaseUnderscore  = dcsDataMember.Name ?? propertyName.ToLowercaseUnderscore();
                    propertyReflectedName            = dcsDataMember.Name ?? fieldInfo.ReflectedType.Name;
                    propertyOrder                    = dcsDataMember.Order;
                    propertySuppressDefaultAttribute = !dcsDataMember.EmitDefaultValue;
                }
                else
                {
                    propertyName                    = fieldInfo.Name;
                    propertyNameCLSFriendly         = propertyName.ToCamelCase();
                    propertyNameLowercaseUnderscore = propertyName.ToLowercaseUnderscore();
                    propertyReflectedName           = fieldInfo.ReflectedType.Name;
                }

                PropertyWriters[i + propertyNamesLength] = new TypePropertyWriter
                                                           (
                    propertyName,
                    propertyReflectedName,
                    propertyNameCLSFriendly,
                    propertyNameLowercaseUnderscore,
                    propertyOrder,
                    propertySuppressDefaultConfig,
                    propertySuppressDefaultAttribute,
                    fieldInfo.GetValueGetter <T>(),
                    Serializer.GetWriteFn(propertyType),
                    defaultValue
                                                           );
            }
            PropertyWriters = PropertyWriters.OrderBy(x => x.propertyOrder).ToArray();
            return(true);
        }
コード例 #3
0
        protected ServiceStackHost(string serviceName, params Assembly[] assembliesWithServices)
        {
            this.StartedAt = DateTime.UtcNow;

            ServiceName = serviceName;
            AppSettings = new AppSettings();
            Container   = new Container {
                DefaultOwner = Owner.External
            };
            ServiceAssemblies = assembliesWithServices.ToList();

            ContentTypes                      = new ContentTypes();
            RestPaths                         = new List <RestPath>();
            Routes                            = new ServiceRoutes(this);
            Metadata                          = new ServiceMetadata(RestPaths);
            PreRequestFilters                 = new List <Action <IRequest, IResponse> >();
            RequestConverters                 = new List <Func <IRequest, object, Task <object> > >();
            ResponseConverters                = new List <Func <IRequest, object, Task <object> > >();
            GlobalRequestFilters              = new List <Action <IRequest, IResponse, object> >();
            GlobalRequestFiltersAsync         = new List <Func <IRequest, IResponse, object, Task> >();
            GlobalTypedRequestFilters         = new Dictionary <Type, ITypedFilter>();
            GlobalResponseFilters             = new List <Action <IRequest, IResponse, object> >();
            GlobalResponseFiltersAsync        = new List <Func <IRequest, IResponse, object, Task> >();
            GlobalTypedResponseFilters        = new Dictionary <Type, ITypedFilter>();
            GlobalMessageRequestFilters       = new List <Action <IRequest, IResponse, object> >();
            GlobalMessageRequestFiltersAsync  = new List <Func <IRequest, IResponse, object, Task> >();
            GlobalTypedMessageRequestFilters  = new Dictionary <Type, ITypedFilter>();
            GlobalMessageResponseFilters      = new List <Action <IRequest, IResponse, object> >();
            GlobalMessageResponseFiltersAsync = new List <Func <IRequest, IResponse, object, Task> >();
            GlobalTypedMessageResponseFilters = new Dictionary <Type, ITypedFilter>();
            GatewayRequestFilters             = new List <Action <IRequest, object> >();
            GatewayRequestFiltersAsync        = new List <Func <IRequest, object, Task> >();
            GatewayResponseFilters            = new List <Action <IRequest, object> >();
            GatewayResponseFiltersAsync       = new List <Func <IRequest, object, Task> >();
            ViewEngines                       = new List <IViewEngine>();
            ServiceExceptionHandlers          = new List <HandleServiceExceptionDelegate>();
            ServiceExceptionHandlersAsync     = new List <HandleServiceExceptionAsyncDelegate>();
            UncaughtExceptionHandlers         = new List <HandleUncaughtExceptionDelegate>();
            UncaughtExceptionHandlersAsync    = new List <HandleUncaughtExceptionAsyncDelegate>();
            BeforeConfigure                   = new List <Action <ServiceStackHost> >();
            AfterConfigure                    = new List <Action <ServiceStackHost> >();
            AfterInitCallbacks                = new List <Action <IAppHost> >();
            OnDisposeCallbacks                = new List <Action <IAppHost> >();
            OnEndRequestCallbacks             = new List <Action <IRequest> >();
            AddVirtualFileSources             = new List <IVirtualPathProvider>();
            RawHttpHandlers                   = new List <Func <IHttpRequest, IHttpHandler> > {
                ReturnRedirectHandler,
                ReturnRequestInfoHandler,
            };
            CatchAllHandlers        = new List <HttpHandlerResolverDelegate>();
            FallbackHandlers        = new List <HttpHandlerResolverDelegate>();
            CustomErrorHttpHandlers = new Dictionary <HttpStatusCode, IServiceStackHandler> {
                { HttpStatusCode.Forbidden, new ForbiddenHttpHandler() },
                { HttpStatusCode.NotFound, new NotFoundHttpHandler() },
            };
            StartUpErrors = new List <ResponseStatus>();
            AsyncErrors   = new List <ResponseStatus>();
            PluginsLoaded = new List <string>();
            Plugins       = new List <IPlugin> {
                new HtmlFormat(),
                new CsvFormat(),
                new PredefinedRoutesFeature(),
                new MetadataFeature(),
                new NativeTypesFeature(),
                new HttpCacheFeature(),
                new RequestInfoFeature(),
                new SpanFormats(),
            };
            ExcludeAutoRegisteringServiceTypes = new HashSet <Type> {
                typeof(AuthenticateService),
                typeof(RegisterService),
                typeof(AssignRolesService),
                typeof(UnAssignRolesService),
                typeof(NativeTypesService),
                typeof(PostmanService),
                typeof(TemplateHotReloadService),
                typeof(HotReloadFilesService),
                typeof(TemplateApiPagesService),
                typeof(TemplateMetadataDebugService),
                typeof(ServerEventsSubscribersService),
                typeof(ServerEventsUnRegisterService),
            };

            JsConfig.InitStatics();
        }
コード例 #4
0
 public void SetUp()
 {
     JsConfig.Reset();
     _localTimezoneOffset = TimeZoneInfo.Local.BaseUtcOffset.Hours.ToString("00") + TimeZoneInfo.Local.BaseUtcOffset.Minutes.ToString("00");
 }
コード例 #5
0
        public void ProcessRequest(IHttpRequest httpReq, IHttpResponse httpRes, string operationName)
        {
            if (EndpointHost.ApplyPreRequestFilters(httpReq, httpRes))
            {
                return;
            }

            List <KeyValuePair <string, object> > configInfo = new List <KeyValuePair <string, object> >();

            if (AppHostBase.Instance != null)
            {
                configInfo.Add(new KeyValuePair <string, object>("StartUpTime", AppHostBase.Instance.StartUpTime));
            }

            if (AppHostHttpListenerBase.Instance != null)
            {
                configInfo.Add(new KeyValuePair <string, object>("StartUpTime", AppHostHttpListenerBase.Instance.StartUpTime));
            }

            configInfo.Add(new KeyValuePair <string, object>("AppId", ServiceUtils.AppId));

            configInfo.Add(new KeyValuePair <string, object>("IPv4", ServiceUtils.HostIP));

            configInfo.Add(new KeyValuePair <string, object>("MachineName", ServiceUtils.MachineName));

            configInfo.Add(new KeyValuePair <string, object>("SOA.CurrentEnv", EnvironmentUtility.CurrentEnv));

            var metadata = EndpointHost.MetadataMap[httpReq.ServicePath];

            configInfo.Add(new KeyValuePair <string, object>("SOA.ServiceName", metadata.ServiceName));
            configInfo.Add(new KeyValuePair <string, object>("SOA.ServiceNamespace", metadata.ServiceNamespace));
            configInfo.Add(new KeyValuePair <string, object>("SOA.ServiceTestSubEnv", metadata.ServiceTestSubEnv ?? "null"));


            configInfo.Add(new KeyValuePair <string, object>(
                               ServiceMetadata.DefaultLogErrorWithRequestInfoSettingKey,
                               metadata.LogErrorWithRequestInfo));

            configInfo.Add(new KeyValuePair <string, object>(
                               ServiceMetadata.DefaultLogCommonRequestInfoSettingKey,
                               metadata.LogCommonRequestInfo));
            configInfo.Add(new KeyValuePair <string, object>(
                               ServiceMetadata.DefaultLogH5HeadExtensionDataSettingKey,
                               metadata.LogH5HeadExtensionData));

            bool circuitBreakerForceClosed = metadata.CircuitBreakerForceClosed;

            configInfo.Add(new KeyValuePair <string, object>(ServiceMetadata.DefaultCircuitBreakerForceClosedSettingKey, circuitBreakerForceClosed));

            Dictionary <string, double> timeoutMap = new Dictionary <string, double>();

            foreach (Operation operation in metadata.Operations)
            {
                timeoutMap.Add(operation.Name, operation.HystrixCommand.GetExecutionTimeout().TotalMilliseconds);
            }
            configInfo.Add(new KeyValuePair <string, object>(ServiceMetadata.DefaultOperationTimeoutMapSettingKey, timeoutMap));

            configInfo.Add(new KeyValuePair <string, object>(
                               ServiceMetadata.DefaultUseChunkedTransferEncodingSettingKey, metadata.UseChunkedTransferEncoding));

            configInfo.Add(new KeyValuePair <string, object>("SOA.FxConfigWebServiceUtils.Enabled", AntFxConfigWebServiceUtils.Enabled));
            configInfo.Add(new KeyValuePair <string, object>("SOA.FxConfigWebServiceUtils.ApiUrl", AntFxConfigWebServiceUtils.ConfigWebServiceApiUrl));

            configInfo.Add(new KeyValuePair <string, object>(
                               "SOA.MinGlobalDefaultTimeout", HystrixCommandHelper.MinGlobalDefaultCircuitBreakerTimeoutSetting.TotalMilliseconds.ToString()));

            configInfo.Add(new KeyValuePair <string, object>(
                               "SOA.GlobalDefaultTimeout",
                               HystrixCommandHelper.GlobalDefaultCircuitBreakerTimeoutSetting.HasValue ? HystrixCommandHelper.GlobalDefaultCircuitBreakerTimeoutSetting.Value.TotalMilliseconds.ToString() : null));

            configInfo.Add(new KeyValuePair <string, object>(
                               "SOA.FrameworkDefaultTimeout", HystrixPropertiesCommandDefault.DefaultExecutionIsolationThreadTimeout.TotalMilliseconds.ToString()));

            configInfo.Add(new KeyValuePair <string, object>(
                               "SOA.FrameworkDefaultConnectionMaxRequestCount", ServiceMetadata.FrameworkDefaultConnectionMaxRequestCount));
            configInfo.Add(new KeyValuePair <string, object>(
                               "SOA.MinConnectionMaxRequestCount", ServiceMetadata.MinConnectionMaxRequestCount));
            configInfo.Add(new KeyValuePair <string, object>(
                               "SOA.CheckConnectionMaxRequestCount", metadata.CheckConnectionMaxRequestCount));
            configInfo.Add(new KeyValuePair <string, object>(
                               "SOA.ConnectionMaxRequestCount", metadata.ConnectionMaxRequestCount));

            configInfo.Add(new KeyValuePair <string, object>(
                               "SOA.MessageLogConfig.RequestLogMaxSize", MessageLogConfig.RequestLogMaxSize));

            configInfo.Add(new KeyValuePair <string, object>(
                               "SOA.MessageLogConfig.ResponseLogMaxSize", MessageLogConfig.ResponseLogMaxSize));

            configInfo.Add(new KeyValuePair <string, object>(
                               "SOA.MessageLogConfig.FrameworkDefalut.Test", MessageLogConfig.FrameworkDefalutMessageLogConfigOfTestEnv));

            configInfo.Add(new KeyValuePair <string, object>(
                               "SOA.MessageLogConfig.FrameworkDefalut.Uat", MessageLogConfig.FrameworkDefalutMessageLogConfigOfUatEnv));

            configInfo.Add(new KeyValuePair <string, object>(
                               "SOA.MessageLogConfig.FrameworkDefalut.Prod", MessageLogConfig.FrameworkDefalutMessageLogConfigOfProdEnv));

            configInfo.Add(new KeyValuePair <string, object>(
                               "SOA.MessageLogConfig.FrameworkDefalut.Null", MessageLogConfig.FrameworkDefalutMessageLogConfigOfNullEnv));

            configInfo.Add(new KeyValuePair <string, object>(
                               "SOA.MessageLogConfig.FrameworkDefault.Current", MessageLogConfig.CurrentFrameworkDefaultMessageLogConfig));

            configInfo.Add(new KeyValuePair <string, object>(
                               "SOA.MessageLogConfig.Service", metadata.ServiceMessageLogConfig));

            var operationMessageConfigs = from operation in metadata.Operations
                                          select new
            {
                operation.Name,
                operation.OperationMessageLogConfig,
            };

            configInfo.Add(new KeyValuePair <string, object>(
                               "SOA.MessageLogConfig.Operation", operationMessageConfigs));
            configInfo.Add(new KeyValuePair <string, object>(
                               "SOA.DeserializeRequestUseMemoryStream", metadata.DeserializeRequestUseMemoryStream));
            configInfo.Add(new KeyValuePair <string, object>(
                               "SOA.LogPopulateExceptionAsWarning", ReflectionUtils.LogPopulateExceptionAsWarning));

            foreach (IHasConfigInfo configInfoOwner in ConfigInfoOwners)
            {
                configInfo.AddRange(configInfoOwner.GetConfigInfo(httpReq.ServicePath));
            }

            using (JsConfigScope scope = JsConfig.BeginScope())
            {
                scope.ExcludeTypeInfo = true;
                scope.DateHandler     = JsonDateHandler.LongDateTime;
                httpRes.ContentType   = "application/json";
                httpRes.Write(WrappedJsonSerializer.Instance.SerializeToString(configInfo));
            }
        }
コード例 #6
0
        internal static object StringToType(
            TypeConfig typeConfig,
            StringSegment strType,
            EmptyCtorDelegate ctorFn,
            Dictionary <HashedStringSegment, TypeAccessor> typeAccessorMap)
        {
            var index = 0;
            var type  = typeConfig.Type;

            if (!strType.HasValue)
            {
                return(null);
            }

            var buffer        = strType.Buffer;
            var offset        = strType.Offset;
            var strTypeLength = strType.Length;

            // if (!Serializer.EatMapStartChar(strType, ref index))
            for (; index < strTypeLength; index++)
            {
                if (!JsonUtils.IsWhiteSpace(buffer[offset + index]))
                {
                    break;
                }
            }
            // Whitespace inline

            if (buffer[offset + index] != JsWriter.MapStartChar)
            {
                throw DeserializeTypeRef.CreateSerializationError(type, strType.Value);
            }

            index++;
            if (JsonTypeSerializer.IsEmptyMap(strType, index))
            {
                return(ctorFn());
            }

            object instance = null;

            var propertyResolver = JsConfig.PropertyConvention == PropertyConvention.Lenient
                                       ? ParseUtils.LenientPropertyNameResolver
                                       : ParseUtils.DefaultPropertyNameResolver;

            while (index < strTypeLength)
            {
                var propertyName = JsonTypeSerializer.ParseJsonString(strType, ref index);

                // Serializer.EatMapKeySeperator(strType, ref index);
                for (; index < strTypeLength; index++)
                {
                    if (!JsonUtils.IsWhiteSpace(buffer[offset + index]))
                    {
                        break;
                    }
                }
                // Whitespace inline

                if (strTypeLength != index)
                {
                    index++;
                }

                var propertyValueStr = Serializer.EatValue(strType, ref index);
                var possibleTypeInfo = propertyValueStr != null && propertyValueStr.Length > 1;

                // if we already have an instance don't check type info, because then we will have a half deserialized object
                // we could throw here or just use the existing instance.
                if (instance == null && possibleTypeInfo && propertyName == typeAttr)
                {
                    var explicitTypeName = Serializer.ParseString(propertyValueStr);
                    var explicitType     = JsConfig.TypeFinder(explicitTypeName);

                    if (explicitType == null || explicitType.IsInterface || explicitType.IsAbstract)
                    {
                        Tracer.Instance.WriteWarning("Could not find type: " + propertyValueStr);
                    }
                    else if (!type.IsAssignableFrom(explicitType))
                    {
                        Tracer.Instance.WriteWarning("Could not assign type: " + propertyValueStr);
                    }
                    else
                    {
                        JsWriter.AssertAllowedRuntimeType(explicitType);
                        instance = explicitType.CreateInstance();
                    }

                    if (instance != null)
                    {
                        // If __type info doesn't match, ignore it.
                        if (!type.IsInstanceOfType(instance))
                        {
                            instance = null;
                        }
                        else
                        {
                            var derivedType = instance.GetType();
                            if (derivedType != type)
                            {
                                var derivedTypeConfig = new TypeConfig(derivedType);
                                var map = DeserializeTypeRef.GetTypeAccessorMap(derivedTypeConfig, Serializer);
                                if (map != null)
                                {
                                    typeAccessorMap = map;
                                }
                            }
                        }
                    }

                    Serializer.EatItemSeperatorOrMapEndChar(strType, ref index);
                    continue;
                }

                if (instance == null)
                {
                    instance = ctorFn();
                }

                var typeAccessor = propertyResolver.GetTypeAccessorForProperty(propertyName, typeAccessorMap);

                var propType = possibleTypeInfo && propertyValueStr.GetChar(0) == '_'
                                   ? TypeAccessor.ExtractType(Serializer, propertyValueStr)
                                   : null;
                if (propType != null)
                {
                    try
                    {
                        if (typeAccessor != null)
                        {
                            // var parseFn = Serializer.GetParseFn(propType);
                            var parseFn = JsonReader.GetParseStringSegmentFn(propType);

                            var propertyValue = parseFn(propertyValueStr);
                            if (typeConfig.OnDeserializing != null)
                            {
                                propertyValue = typeConfig.OnDeserializing(instance, propertyName.Value, propertyValue);
                            }
                            typeAccessor.SetProperty(instance, propertyValue);
                        }

                        // Serializer.EatItemSeperatorOrMapEndChar(strType, ref index);
                        for (; index < strTypeLength; index++)
                        {
                            if (!JsonUtils.IsWhiteSpace(buffer[offset + index]))
                            {
                                break;
                            }
                        }
                        // Whitespace inline

                        if (index != strTypeLength)
                        {
                            var success = buffer[offset + index] == JsWriter.ItemSeperator ||
                                          buffer[offset + index] == JsWriter.MapEndChar;
                            index++;
                            if (success)
                            {
                                for (; index < strTypeLength; index++)
                                {
                                    if (!JsonUtils.IsWhiteSpace(buffer[offset + index]))
                                    {
                                        break;
                                    }
                                }
                            }
                            // Whitespace inline
                        }

                        continue;
                    }
                    catch (Exception e)
                    {
                        if (JsConfig.OnDeserializationError != null)
                        {
                            JsConfig.OnDeserializationError(
                                instance,
                                propType,
                                propertyName.Value,
                                propertyValueStr.Value,
                                e);
                        }
                        if (JsConfig.ThrowOnDeserializationError)
                        {
                            throw DeserializeTypeRef.GetSerializationException(
                                      propertyName.Value,
                                      propertyValueStr.Value,
                                      propType,
                                      e);
                        }
                        else
                        {
                            Tracer.Instance.WriteWarning(
                                "WARN: failed to set dynamic property {0} with: {1}",
                                propertyName,
                                propertyValueStr.Value);
                        }
                    }
                }

                if (typeAccessor?.GetProperty != null && typeAccessor.SetProperty != null)
                {
                    try
                    {
                        var propertyValue = typeAccessor.GetProperty(propertyValueStr);
                        if (typeConfig.OnDeserializing != null)
                        {
                            propertyValue = typeConfig.OnDeserializing(instance, propertyName.Value, propertyValue);
                        }
                        typeAccessor.SetProperty(instance, propertyValue);
                    }
                    catch (NotSupportedException)
                    {
                        throw;
                    }
                    catch (Exception e)
                    {
                        if (JsConfig.OnDeserializationError != null)
                        {
                            JsConfig.OnDeserializationError(
                                instance,
                                propType ?? typeAccessor.PropertyType,
                                propertyName.Value,
                                propertyValueStr.Value,
                                e);
                        }
                        if (JsConfig.ThrowOnDeserializationError)
                        {
                            throw DeserializeTypeRef.GetSerializationException(
                                      propertyName.Value,
                                      propertyValueStr.Value,
                                      typeAccessor.PropertyType,
                                      e);
                        }
                        else
                        {
                            Tracer.Instance.WriteWarning(
                                "WARN: failed to set property {0} with: {1}",
                                propertyName,
                                propertyValueStr.Value);
                        }
                    }
                }
                else
                {
                    // the property is not known by the DTO
                    typeConfig.OnDeserializing?.Invoke(instance, propertyName.Value, propertyValueStr.Value);
                }

                // Serializer.EatItemSeperatorOrMapEndChar(strType, ref index);
                for (; index < strTypeLength; index++)
                {
                    if (!JsonUtils.IsWhiteSpace(buffer[offset + index]))
                    {
                        break;
                    }
                }
                // Whitespace inline

                if (index != strType.Length)
                {
                    var success = buffer[offset + index] == JsWriter.ItemSeperator ||
                                  buffer[offset + index] == JsWriter.MapEndChar;
                    index++;
                    if (success)
                    {
                        for (; index < strTypeLength; index++)
                        {
                            if (!JsonUtils.IsWhiteSpace(buffer[offset + index]))
                            {
                                break;
                            }
                        }
                    }
                    // Whitespace inline
                }
            }

            return(instance);
        }
コード例 #7
0
        public object Get(OpenApiSpecification request)
        {
            var map   = HostContext.ServiceController.RestPathMap;
            var paths = new List <RestPath>();

            var basePath = new Uri(base.Request.GetBaseUrl());

            var meta = HostContext.Metadata;

            foreach (var key in map.Keys)
            {
                var restPaths    = map[key];
                var visiblePaths = restPaths.Where(x => meta.IsVisible(Request, Format.Json, x.RequestType.Name));
                paths.AddRange(visiblePaths);
            }

            var definitions = new Dictionary <string, OpenApiSchema>
            {
                { "Object", new OpenApiSchema {
                      Description = "Object", Type = OpenApiType.Object, Properties = new OrderedDictionary <string, OpenApiProperty>()
                  } },
            };

            foreach (var restPath in paths.SelectMany(x => x.Verbs.Select(y => new { Value = x, Verb = y })))
            {
                ParseDefinitions(definitions, restPath.Value.RequestType, restPath.Value.Path, restPath.Verb);
            }

            var tags     = new Dictionary <string, OpenApiTag>();
            var apiPaths = ParseOperations(paths, definitions, tags);

            var result = new OpenApiDeclaration
            {
                Info = new OpenApiInfo
                {
                    Title   = HostContext.ServiceName,
                    Version = HostContext.Config.ApiVersion,
                },
                Paths    = apiPaths,
                BasePath = basePath.AbsolutePath,
                Schemes  = new List <string> {
                    basePath.Scheme
                },                                              //TODO: get https from config
                Host     = basePath.Authority,
                Consumes = new List <string> {
                    "application/json"
                },
                Produces = new List <string> {
                    "application/json"
                },
                Definitions = definitions,
                Tags        = tags.Values.OrderBy(x => x.Name).ToList(),
                Parameters  = new Dictionary <string, OpenApiParameter> {
                    { "Accept", GetAcceptHeaderParameter() }
                },
                SecurityDefinitions = new Dictionary <string, OpenApiSecuritySchema> {
                    { "basic", new OpenApiSecuritySchema {
                          Type = "basic"
                      } }
                }
            };

            if (OperationFilter != null)
            {
                apiPaths.Each(x => GetOperations(x.Value).Each(o => OperationFilter(o.Item1, o.Item2)));
            }

            ApiDeclarationFilter?.Invoke(result);

            return(new HttpResult(result)
            {
                ResultScope = () => JsConfig.With(includeNullValues: false)
            });
        }
コード例 #8
0
        public override void Configure(Container container)
        {
            Plugins.Add(new MiniProfilerFeature());
            Plugins.Add(new RazorFormat());
            Plugins.Add(new ServerEventsFeature
            {
                OnCreated = (sub, req) =>
                {
                    sub.ServerArgs = new Dictionary <string, string>
                    {
                        { "server-arg", "1" }
                    };
                }
            });

            container.Register(new DataSource());

            var UsePostgreSql = false;

            if (UsePostgreSql)
            {
                container.Register <IDbConnectionFactory>(
                    new OrmLiteConnectionFactory(
                        Environment.GetEnvironmentVariable("PGSQL_CONNECTION") ??
                        "Server=localhost;Port=5432;User Id=test;Password=test;Database=test;Pooling=true;MinPoolSize=0;MaxPoolSize=200",
                        PostgreSqlDialect.Provider)
                {
                    ConnectionFilter = x => new ProfiledDbConnection(x, Profiler.Current)
                });
            }
            else
            {
                container.Register <IDbConnectionFactory>(
                    new OrmLiteConnectionFactory(":memory:", SqliteDialect.Provider)
                {
                    ConnectionFilter = x => new ProfiledDbConnection(x, Profiler.Current)
                });
            }

            using (var db = container.Resolve <IDbConnectionFactory>().Open())
            {
                db.DropAndCreateTable <Rockstar>();
                db.Insert(Rockstar.SeedData);
            }

            JsConfig.Init(new Text.Config {
                TextCase = TextCase.CamelCase
            });

            //Register a external dependency-free
            container.Register <ICacheClient>(new MemoryCacheClient());

            //Enable Authentication an Registration
            ConfigureAuth(container);

            //Create your own custom User table
            using (var db = container.Resolve <IDbConnectionFactory>().Open())
                db.DropAndCreateTable <UserTable>();

            SetConfig(new HostConfig
            {
                DebugMode = true,
                AddRedirectParamsToQueryString = true,
            });
        }
コード例 #9
0
 public void TestFixtureTearDown()
 {
     JsConfig.Reset();
 }
コード例 #10
0
        private ParseStringDelegate GetCoreParseFn <T>()
        {
            var type = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T);

            if (JsConfig <T> .HasDeserializeFn)
            {
                return(value => JsConfig <T> .ParseFn(Serializer, value));
            }

            if (type.IsEnum())
            {
                return(x => Enum.Parse(type, Serializer.UnescapeSafeString(x), true));
            }

            if (type == typeof(string))
            {
                return(Serializer.UnescapeString);
            }

            if (type == typeof(object))
            {
                return(DeserializeType <TSerializer> .ObjectStringToType);
            }

            var specialParseFn = ParseUtils.GetSpecialParseMethod(type);

            if (specialParseFn != null)
            {
                return(specialParseFn);
            }

            if (type.IsEnum())
            {
                return(x => Enum.Parse(type, x, true));
            }

            if (type.IsArray)
            {
                return(DeserializeArray <T, TSerializer> .Parse);
            }

            var builtInMethod = DeserializeBuiltin <T> .Parse;

            if (builtInMethod != null)
            {
                return(value => builtInMethod(Serializer.UnescapeSafeString(value)));
            }

            if (type.HasGenericType())
            {
                if (type.IsOrHasGenericInterfaceTypeOf(typeof(IList <>)))
                {
                    return(DeserializeList <T, TSerializer> .Parse);
                }

                if (type.IsOrHasGenericInterfaceTypeOf(typeof(IDictionary <,>)))
                {
                    return(DeserializeDictionary <TSerializer> .GetParseMethod(type));
                }

                if (type.IsOrHasGenericInterfaceTypeOf(typeof(ICollection <>)))
                {
                    return(DeserializeCollection <TSerializer> .GetParseMethod(type));
                }

                if (type.HasAnyTypeDefinitionsOf(typeof(Queue <>)) ||
                    type.HasAnyTypeDefinitionsOf(typeof(Stack <>)))
                {
                    return(DeserializeSpecializedCollections <T, TSerializer> .Parse);
                }

                if (type.IsOrHasGenericInterfaceTypeOf(typeof(KeyValuePair <,>)))
                {
                    return(DeserializeKeyValuePair <TSerializer> .GetParseMethod(type));
                }

                if (type.IsOrHasGenericInterfaceTypeOf(typeof(IEnumerable <>)))
                {
                    return(DeserializeEnumerable <T, TSerializer> .Parse);
                }
            }

#if NET40
            if (typeof(T).IsAssignableFrom(typeof(System.Dynamic.IDynamicMetaObjectProvider)) ||
                typeof(T).HasInterface(typeof(System.Dynamic.IDynamicMetaObjectProvider)))
            {
                return(DeserializeDynamic <TSerializer> .Parse);
            }
#endif

            var isDictionary = typeof(T) != typeof(IEnumerable) &&
                               (typeof(T).AssignableFrom(typeof(IDictionary)) || typeof(T).HasInterface(typeof(IDictionary)));
            if (isDictionary)
            {
                return(DeserializeDictionary <TSerializer> .GetParseMethod(type));
            }

            var isEnumerable = typeof(T).AssignableFrom(typeof(IEnumerable)) ||
                               typeof(T).HasInterface(typeof(IEnumerable));
            if (isEnumerable)
            {
                var parseFn = DeserializeSpecializedCollections <T, TSerializer> .Parse;
                if (parseFn != null)
                {
                    return(parseFn);
                }
            }

            if (type.IsValueType())
            {
                var staticParseMethod = StaticParseMethod <T> .Parse;
                if (staticParseMethod != null)
                {
                    return(value => staticParseMethod(Serializer.UnescapeSafeString(value)));
                }
            }
            else
            {
                var staticParseMethod = StaticParseRefTypeMethod <TSerializer, T> .Parse;
                if (staticParseMethod != null)
                {
                    return(value => staticParseMethod(Serializer.UnescapeSafeString(value)));
                }
            }

            var typeConstructor = DeserializeType <TSerializer> .GetParseMethod(TypeConfig <T> .GetState());

            if (typeConstructor != null)
            {
                return(typeConstructor);
            }

            var stringConstructor = DeserializeTypeUtils.GetParseMethod(type);
            if (stringConstructor != null)
            {
                return(stringConstructor);
            }

            return(DeserializeType <TSerializer> .ParseAbstractType <T>);
        }
コード例 #11
0
 public void SetUp()
 {
     JsConfig.Reset();
     JsConfig <ICat> .ExcludeTypeInfo = false;
 }
コード例 #12
0
 public static void RegisterConverter <From, To>(Func <From, To> converter)
 {
     JsConfig.InitStatics();
     converters[Tuple.Create(typeof(From), typeof(To))] = x => converter((From)x);
 }
コード例 #13
0
        public static IDictionary <TKey, TValue> ParseDictionary <TKey, TValue>(
            ReadOnlySpan <char> value, Type createMapType,
            ParseStringSpanDelegate parseKeyFn, ParseStringSpanDelegate parseValueFn)
        {
            if (value.IsEmpty)
            {
                return(null);
            }

            var to = (createMapType == null)
                ? new Dictionary <TKey, TValue>()
                : (IDictionary <TKey, TValue>)createMapType.CreateInstance();

            var objDeserializer = Json.JsonTypeSerializer.Instance.ObjectDeserializer;

            if (to is Dictionary <string, object> && objDeserializer != null && typeof(TSerializer) == typeof(Json.JsonTypeSerializer))
            {
                return((IDictionary <TKey, TValue>)objDeserializer(value));
            }

            var config = JsConfig.GetConfig();

            var tryToParseItemsAsDictionaries =
                config.ConvertObjectTypesIntoStringDictionary && typeof(TValue) == typeof(object);
            var tryToParseItemsAsPrimitiveTypes =
                config.TryToParsePrimitiveTypeValues && typeof(TValue) == typeof(object);

            var index = VerifyAndGetStartIndex(value, createMapType);

            if (Json.JsonTypeSerializer.IsEmptyMap(value, index))
            {
                return(to);
            }

            var valueLength = value.Length;

            while (index < valueLength)
            {
                var keyValue = Serializer.EatMapKey(value, ref index);
                Serializer.EatMapKeySeperator(value, ref index);
                var elementStartIndex = index;
                var elementValue      = Serializer.EatTypeValue(value, ref index);
                if (keyValue.IsNullOrEmpty())
                {
                    continue;
                }

                TKey mapKey = (TKey)parseKeyFn(keyValue);

                if (tryToParseItemsAsDictionaries)
                {
                    Serializer.EatWhitespace(value, ref elementStartIndex);
                    if (elementStartIndex < valueLength && value[elementStartIndex] == JsWriter.MapStartChar)
                    {
                        var tmpMap = ParseDictionary <TKey, TValue>(elementValue, createMapType, parseKeyFn, parseValueFn);
                        if (tmpMap != null && tmpMap.Count > 0)
                        {
                            to[mapKey] = (TValue)tmpMap;
                        }
                    }
                    else if (elementStartIndex < valueLength && value[elementStartIndex] == JsWriter.ListStartChar)
                    {
                        to[mapKey] = (TValue)DeserializeList <List <object>, TSerializer> .ParseStringSpan(elementValue);
                    }
                    else
                    {
                        to[mapKey] = (TValue)(tryToParseItemsAsPrimitiveTypes && elementStartIndex < valueLength
                            ? DeserializeType <TSerializer> .ParsePrimitive(elementValue.Value(), value[elementStartIndex])
                            : parseValueFn(elementValue));
                    }
                }
                else
                {
                    if (tryToParseItemsAsPrimitiveTypes && elementStartIndex < valueLength)
                    {
                        Serializer.EatWhitespace(value, ref elementStartIndex);
                        to[mapKey] = (TValue)DeserializeType <TSerializer> .ParsePrimitive(elementValue.Value(), value[elementStartIndex]);
                    }
                    else
                    {
                        to[mapKey] = (TValue)parseValueFn(elementValue);
                    }
                }

                Serializer.EatItemSeperatorOrMapEndChar(value, ref index);
            }

            return(to);
        }
コード例 #14
0
 public void SetUp()
 {
     LicenseUtils.RemoveLicense();
     JsConfig.Reset();
 }
コード例 #15
0
 public void TearDown()
 {
     JsConfig.Reset();
 }
コード例 #16
0
        protected ServiceStackHost(string serviceName, params Assembly[] assembliesWithServices)
        {
            this.StartedAt = DateTime.UtcNow;

            ServiceName = serviceName;
            AppSettings = new AppSettings();
            Container   = new Container {
                DefaultOwner = Owner.External
            };
            ServiceAssemblies = assembliesWithServices;
            ServiceController = CreateServiceController(assembliesWithServices);

            ContentTypes                      = Host.ContentTypes.Instance;
            RestPaths                         = new List <RestPath>();
            Routes                            = new ServiceRoutes(this);
            Metadata                          = new ServiceMetadata(RestPaths);
            PreRequestFilters                 = new List <Action <IRequest, IResponse> >();
            RequestConverters                 = new List <Func <IRequest, object, object> >();
            ResponseConverters                = new List <Func <IRequest, object, object> >();
            GlobalRequestFilters              = new List <Action <IRequest, IResponse, object> >();
            GlobalTypedRequestFilters         = new Dictionary <Type, ITypedFilter>();
            GlobalResponseFilters             = new List <Action <IRequest, IResponse, object> >();
            GlobalTypedResponseFilters        = new Dictionary <Type, ITypedFilter>();
            GlobalMessageRequestFilters       = new List <Action <IRequest, IResponse, object> >();
            GlobalTypedMessageRequestFilters  = new Dictionary <Type, ITypedFilter>();
            GlobalMessageResponseFilters      = new List <Action <IRequest, IResponse, object> >();
            GlobalTypedMessageResponseFilters = new Dictionary <Type, ITypedFilter>();
            GatewayRequestFilters             = new List <Action <IRequest, object> >();
            GatewayResponseFilters            = new List <Action <IRequest, object> >();
            ViewEngines                       = new List <IViewEngine>();
            ServiceExceptionHandlers          = new List <HandleServiceExceptionDelegate>();
            UncaughtExceptionHandlers         = new List <HandleUncaughtExceptionDelegate>();
            AfterInitCallbacks                = new List <Action <IAppHost> >();
            OnDisposeCallbacks                = new List <Action <IAppHost> >();
            OnEndRequestCallbacks             = new List <Action <IRequest> >();
            RawHttpHandlers                   = new List <Func <IHttpRequest, IHttpHandler> > {
                HttpHandlerFactory.ReturnRequestInfo,
                MiniProfilerHandler.MatchesRequest,
            };
            CatchAllHandlers        = new List <HttpHandlerResolverDelegate>();
            CustomErrorHttpHandlers = new Dictionary <HttpStatusCode, IServiceStackHandler> {
                { HttpStatusCode.Forbidden, new ForbiddenHttpHandler() },
                { HttpStatusCode.NotFound, new NotFoundHttpHandler() },
            };
            StartUpErrors = new List <ResponseStatus>();
            AsyncErrors   = new List <ResponseStatus>();
            PluginsLoaded = new List <string>();
            Plugins       = new List <IPlugin> {
                new HtmlFormat(),
                new CsvFormat(),
                new MarkdownFormat(),
                new PredefinedRoutesFeature(),
                new MetadataFeature(),
                new NativeTypesFeature(),
                new HttpCacheFeature(),
            };
            ExcludeAutoRegisteringServiceTypes = new HashSet <Type> {
                typeof(AuthenticateService),
                typeof(RegisterService),
                typeof(AssignRolesService),
                typeof(UnAssignRolesService),
                typeof(NativeTypesService),
                typeof(PostmanService),
            };

            JsConfig.InitStatics();
        }
コード例 #17
0
 public void SetUp()
 {
     JsConfig.Reset();
 }
コード例 #18
0
        public static void RegisterLicense(string licenseKeyText)
        {
            JsConfig.InitStatics();

            if (__activatedLicense != null) //Skip multiple license registrations. Use RemoveLicense() to reset.
            {
                return;
            }

            string subId = null;
            var    hold  = Thread.CurrentThread.CurrentCulture;

            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
            try
            {
                if (IsFreeLicenseKey(licenseKeyText))
                {
                    ValidateFreeLicenseKey(licenseKeyText);
                    return;
                }

                var parts = licenseKeyText.SplitOnFirst('-');
                subId = parts[0];

                if (int.TryParse(subId, out var subIdInt) && revokedSubs.Contains(subIdInt))
                {
                    throw new LicenseException("This subscription has been revoked. " + ContactDetails);
                }

                var key = VerifyLicenseKeyText(licenseKeyText);
                ValidateLicenseKey(key);
            }
            catch (PlatformNotSupportedException)
            {
                // Allow usage in environments like dotnet script
                __activatedLicense = new __ActivatedLicense(new LicenseKey {
                    Type = LicenseType.Indie
                });
            }
            catch (Exception ex)
            {
                //bubble unrelated project Exceptions
                switch (ex)
                {
                case FileNotFoundException or FileLoadException or BadImageFormatException or NotSupportedException
#if NET6_0_OR_GREATER
                    or System.Net.Http.HttpRequestException
#endif
                    or WebException or TaskCanceledException or LicenseException:
                    throw;
                }

                var msg = "This license is invalid." + ContactDetails;
                if (!string.IsNullOrEmpty(subId))
                {
                    msg += $" The id for this license is '{subId}'";
                }

                lock (typeof(LicenseUtils))
                {
                    try
                    {
                        var key = PclExport.Instance.VerifyLicenseKeyTextFallback(licenseKeyText);
                        ValidateLicenseKey(key);
                    }
                    catch (Exception exFallback)
                    {
                        if (exFallback is FileNotFoundException or FileLoadException or BadImageFormatException)
                        {
                            throw;
                        }

                        throw new LicenseException(msg, exFallback).Trace();
                    }
                }

                throw new LicenseException(msg, ex).Trace();
            }
            finally
            {
                Thread.CurrentThread.CurrentCulture = hold;
            }
        }
コード例 #19
0
 static QueryStringSerializer()
 {
     JsConfig.InitStatics();
     Instance = new JsWriter <JsvTypeSerializer>();
 }
コード例 #20
0
 internal static JsConfigScope GetJsScope()
 {
     return(JsConfig.With(new Config {
         ExcludeTypeInfo = false
     }));
 }
コード例 #21
0
        internal static object StringToType(ReadOnlySpan <char> strType,
                                            TypeConfig typeConfig,
                                            EmptyCtorDelegate ctorFn,
                                            KeyValuePair <string, TypeAccessor>[] typeAccessors)
        {
            var index = 0;
            var type  = typeConfig.Type;

            if (strType.IsEmpty)
            {
                return(null);
            }

            var buffer        = strType;
            var strTypeLength = strType.Length;

            //if (!Serializer.EatMapStartChar(strType, ref index))
            for (; index < strTypeLength; index++)
            {
                if (!JsonUtils.IsWhiteSpace(buffer[index]))
                {
                    break;
                }
            }                                                                                             //Whitespace inline
            if (buffer[index] != JsWriter.MapStartChar)
            {
                throw DeserializeTypeRef.CreateSerializationError(type, strType.ToString());
            }

            index++;
            if (JsonTypeSerializer.IsEmptyMap(strType, index))
            {
                return(ctorFn());
            }

            object instance = null;
            var    lenient  = JsConfig.PropertyConvention == PropertyConvention.Lenient;

            for (; index < strTypeLength; index++)
            {
                if (!JsonUtils.IsWhiteSpace(buffer[index]))
                {
                    break;
                }
            }                                                                                             //Whitespace inline

            while (index < strTypeLength)
            {
                var propertyName = JsonTypeSerializer.UnescapeJsString(strType, JsonUtils.QuoteChar, removeQuotes: true, ref index);

                //Serializer.EatMapKeySeperator(strType, ref index);
                for (; index < strTypeLength; index++)
                {
                    if (!JsonUtils.IsWhiteSpace(buffer[index]))
                    {
                        break;
                    }
                }                                                                                             //Whitespace inline
                if (strTypeLength != index)
                {
                    index++;
                }

                var propertyValueStr = Serializer.EatValue(strType, ref index);
                var possibleTypeInfo = propertyValueStr != null && propertyValueStr.Length > 1;

                //if we already have an instance don't check type info, because then we will have a half deserialized object
                //we could throw here or just use the existing instance.
                if (instance == null && possibleTypeInfo && propertyName.Equals(typeAttr.Span, StringComparison.OrdinalIgnoreCase))
                {
                    var explicitTypeName = Serializer.ParseString(propertyValueStr);
                    var explicitType     = JsConfig.TypeFinder(explicitTypeName);

                    if (explicitType == null || explicitType.IsInterface || explicitType.IsAbstract)
                    {
                        Tracer.Instance.WriteWarning("Could not find type: " + propertyValueStr.ToString());
                    }
                    else if (!type.IsAssignableFrom(explicitType))
                    {
                        Tracer.Instance.WriteWarning("Could not assign type: " + propertyValueStr.ToString());
                    }
                    else
                    {
                        JsWriter.AssertAllowedRuntimeType(explicitType);
                        instance = explicitType.CreateInstance();
                    }

                    if (instance != null)
                    {
                        //If __type info doesn't match, ignore it.
                        if (!type.IsInstanceOfType(instance))
                        {
                            instance = null;
                        }
                        else
                        {
                            var derivedType = instance.GetType();
                            if (derivedType != type)
                            {
                                var map = DeserializeTypeRef.GetCachedTypeAccessors(derivedType, Serializer);
                                if (map != null)
                                {
                                    typeAccessors = map;
                                }
                            }
                        }
                    }

                    Serializer.EatItemSeperatorOrMapEndChar(strType, ref index);
                    continue;
                }

                if (instance == null)
                {
                    instance = ctorFn();
                }

                var typeAccessor = typeAccessors.Get(propertyName, lenient);

                var propType = possibleTypeInfo && propertyValueStr[0] == '_' ? TypeAccessor.ExtractType(Serializer, propertyValueStr.ToString()) : null;
                if (propType != null)
                {
                    try
                    {
                        if (typeAccessor != null)
                        {
                            //var parseFn = Serializer.GetParseFn(propType);
                            var parseFn = JsonReader.GetParseStringSegmentFn(propType);

                            var propertyValue = parseFn(propertyValueStr);
                            if (typeConfig.OnDeserializing != null)
                            {
                                propertyValue = typeConfig.OnDeserializing(instance, propertyName.ToString(), propertyValue);
                            }
                            typeAccessor.SetProperty(instance, propertyValue);
                        }

                        //Serializer.EatItemSeperatorOrMapEndChar(strType, ref index);
                        for (; index < strTypeLength; index++)
                        {
                            if (!JsonUtils.IsWhiteSpace(buffer[index]))
                            {
                                break;
                            }
                        }                                                                                             //Whitespace inline
                        if (index != strTypeLength)
                        {
                            var success = buffer[index] == JsWriter.ItemSeperator || buffer[index] == JsWriter.MapEndChar;
                            index++;
                            if (success)
                            {
                                for (; index < strTypeLength; index++)
                                {
                                    if (!JsonUtils.IsWhiteSpace(buffer[index]))
                                    {
                                        break;
                                    }
                                }                                                                                             //Whitespace inline
                            }
                        }

                        continue;
                    }
                    catch (Exception e)
                    {
                        if (JsConfig.OnDeserializationError != null)
                        {
                            JsConfig.OnDeserializationError(instance, propType, propertyName.ToString(), propertyValueStr.ToString(), e);
                        }
                        if (JsConfig.ThrowOnError)
                        {
                            throw DeserializeTypeRef.GetSerializationException(propertyName.ToString(), propertyValueStr.ToString(), propType, e);
                        }
                        else
                        {
                            Tracer.Instance.WriteWarning("WARN: failed to set dynamic property {0} with: {1}", propertyName.ToString(), propertyValueStr.ToString());
                        }
                    }
                }

                if (typeAccessor?.GetProperty != null && typeAccessor.SetProperty != null)
                {
                    try
                    {
                        var propertyValue = typeAccessor.GetProperty(propertyValueStr.ToString());
                        if (typeConfig.OnDeserializing != null)
                        {
                            propertyValue = typeConfig.OnDeserializing(instance, propertyName.ToString(), propertyValue);
                        }
                        typeAccessor.SetProperty(instance, propertyValue);
                    }
                    catch (NotSupportedException) { throw; }
                    catch (Exception e)
                    {
                        if (JsConfig.OnDeserializationError != null)
                        {
                            JsConfig.OnDeserializationError(instance, propType ?? typeAccessor.PropertyType, propertyName.ToString(), propertyValueStr.ToString(), e);
                        }
                        if (JsConfig.ThrowOnError)
                        {
                            throw DeserializeTypeRef.GetSerializationException(propertyName.ToString(), propertyValueStr.ToString(), typeAccessor.PropertyType, e);
                        }
                        else
                        {
                            Tracer.Instance.WriteWarning("WARN: failed to set property {0} with: {1}", propertyName.ToString(), propertyValueStr.ToString());
                        }
                    }
                }
                else
                {
                    // the property is not known by the DTO
                    typeConfig.OnDeserializing?.Invoke(instance, propertyName.ToString(), propertyValueStr.ToString());
                }

                //Serializer.EatItemSeperatorOrMapEndChar(strType, ref index);
                for (; index < strTypeLength; index++)
                {
                    if (!JsonUtils.IsWhiteSpace(buffer[index]))
                    {
                        break;
                    }
                }                                                                                             //Whitespace inline
                if (index != strType.Length)
                {
                    var success = buffer[index] == JsWriter.ItemSeperator || buffer[index] == JsWriter.MapEndChar;
                    index++;
                    if (success)
                    {
                        for (; index < strTypeLength; index++)
                        {
                            if (!JsonUtils.IsWhiteSpace(buffer[index]))
                            {
                                break;
                            }
                        }                                                                                             //Whitespace inline
                    }
                }
            }

            return(instance);
        }
コード例 #22
0
 public void SetUp()
 {
     OrmLiteConfig.ClearCache();
     LicenseUtils.RemoveLicense();
     JsConfig.Reset();
 }
コード例 #23
0
        /// <summary>
        /// Writes to response.
        /// Response headers are customizable by implementing IHasOptions an returning Dictionary of Http headers.
        /// </summary>
        /// <param name="response">The response.</param>
        /// <param name="result">Whether or not it was implicitly handled by ServiceStack's built-in handlers.</param>
        /// <param name="defaultAction">The default action.</param>
        /// <param name="request">The serialization context.</param>
        /// <param name="bodyPrefix">Add prefix to response body if any</param>
        /// <param name="bodySuffix">Add suffix to response body if any</param>
        /// <returns></returns>
        public static async Task <bool> WriteToResponse(this IResponse response, object result, StreamSerializerDelegateAsync defaultAction, IRequest request, byte[] bodyPrefix, byte[] bodySuffix, CancellationToken token = default(CancellationToken))
        {
            using (Profiler.Current.Step("Writing to Response"))
            {
                var  defaultContentType = request.ResponseContentType;
                var  disposableResult   = result as IDisposable;
                bool flushAsync         = false;

                try
                {
                    if (result == null)
                    {
                        response.EndRequestWithNoContent();
                        return(true);
                    }

                    ApplyGlobalResponseHeaders(response);

                    IDisposable resultScope = null;


                    if (result is Exception)
                    {
                        if (response.Request.Items.TryGetValue(Keywords.ErrorView, out var oErrorView))
                        {
                            response.Request.Items[Keywords.View] = oErrorView;
                        }
                    }

                    var httpResult = result as IHttpResult;
                    if (httpResult != null)
                    {
                        if (httpResult.ResultScope != null)
                        {
                            resultScope = httpResult.ResultScope();
                        }

                        if (httpResult.RequestContext == null)
                        {
                            httpResult.RequestContext = request;
                        }

                        var paddingLength = bodyPrefix?.Length ?? 0;
                        if (bodySuffix != null)
                        {
                            paddingLength += bodySuffix.Length;
                        }

                        httpResult.PaddingLength = paddingLength;

                        if (httpResult is IHttpError httpError)
                        {
                            response.Dto = httpError.CreateErrorResponse();
                            if (await response.HandleCustomErrorHandler(request, defaultContentType, httpError.Status, response.Dto, httpError as Exception))
                            {
                                return(true);
                            }
                        }

                        response.Dto = response.Dto ?? httpResult.GetDto();

                        if (!response.HasStarted)
                        {
                            response.StatusCode        = httpResult.Status;
                            response.StatusDescription = (httpResult.StatusDescription ?? httpResult.StatusCode.ToString()).Localize(request);

                            if (string.IsNullOrEmpty(httpResult.ContentType))
                            {
                                httpResult.ContentType = defaultContentType;
                            }
                            response.ContentType = httpResult.ContentType;

                            if (httpResult.Cookies != null)
                            {
                                foreach (var cookie in httpResult.Cookies)
                                {
                                    response.SetCookie(cookie);
                                }
                            }
                        }
                    }
                    else
                    {
                        response.Dto = result;
                    }

                    var config = HostContext.Config;
                    if (!response.HasStarted)
                    {
                        /* Mono Error: Exception: Method not found: 'System.Web.HttpResponse.get_Headers' */
                        if (result is IHasOptions responseOptions)
                        {
                            //Reserving options with keys in the format 'xx.xxx' (No Http headers contain a '.' so its a safe restriction)
                            const string reservedOptions = ".";

                            foreach (var responseHeaders in responseOptions.Options)
                            {
                                if (responseHeaders.Key.Contains(reservedOptions))
                                {
                                    continue;
                                }
                                if (responseHeaders.Key == HttpHeaders.ContentLength)
                                {
                                    response.SetContentLength(long.Parse(responseHeaders.Value));
                                    continue;
                                }

                                if (responseHeaders.Key.EqualsIgnoreCase(HttpHeaders.ContentType))
                                {
                                    response.ContentType = responseHeaders.Value;
                                    continue;
                                }

                                if (Log.IsDebugEnabled)
                                {
                                    Log.Debug($"Setting Custom HTTP Header: {responseHeaders.Key}: {responseHeaders.Value}");
                                }

                                response.AddHeader(responseHeaders.Key, responseHeaders.Value);
                            }
                        }

                        //ContentType='text/html' is the default for a HttpResponse
                        //Do not override if another has been set
                        if (response.ContentType == null || response.ContentType == MimeTypes.Html)
                        {
                            response.ContentType = defaultContentType == (config.DefaultContentType ?? MimeTypes.Html) && result is byte[]
                                ? MimeTypes.Binary
                                : defaultContentType;
                        }
                        if (bodyPrefix != null && response.ContentType.IndexOf(MimeTypes.Json, StringComparison.OrdinalIgnoreCase) >= 0)
                        {
                            response.ContentType = MimeTypes.JavaScript;
                        }

                        if (config.AppendUtf8CharsetOnContentTypes.Contains(response.ContentType))
                        {
                            response.ContentType += ContentFormat.Utf8Suffix;
                        }
                    }

                    var jsconfig = config.AllowJsConfig ? request.QueryString[Keywords.JsConfig] : null;
                    using (resultScope)
                        using (jsconfig != null ? JsConfig.CreateScope(jsconfig) : null)
                        {
                            if (WriteToOutputStream(response, result, bodyPrefix, bodySuffix))
                            {
                                response.Flush(); //required for Compression
                                return(true);
                            }

#if NET45
                            //JsConfigScope uses ThreadStatic in .NET v4.5 so avoid async thread hops by writing sync to MemoryStream
                            if (resultScope != null || jsconfig != null)
                            {
                                response.UseBufferedStream = true;
                            }
#endif

                            if (await WriteToOutputStreamAsync(response, result, bodyPrefix, bodySuffix, token))
                            {
                                flushAsync = true;
                                return(true);
                            }

                            if (httpResult != null)
                            {
                                result = httpResult.Response;
                            }

                            if (result is string responseText)
                            {
                                var strBytes = responseText.ToUtf8Bytes();
                                var len      = (bodyPrefix?.Length).GetValueOrDefault() +
                                               strBytes.Length +
                                               (bodySuffix?.Length).GetValueOrDefault();

                                response.SetContentLength(len);

                                if (response.ContentType == null || response.ContentType == MimeTypes.Html)
                                {
                                    response.ContentType = defaultContentType;
                                }

                                //retain behavior with ASP.NET's response.Write(string)
                                if (response.ContentType.IndexOf(';') == -1)
                                {
                                    response.ContentType += ContentFormat.Utf8Suffix;
                                }

                                if (bodyPrefix != null)
                                {
                                    await response.OutputStream.WriteAsync(bodyPrefix, token);
                                }

                                await response.OutputStream.WriteAsync(strBytes, token);

                                if (bodySuffix != null)
                                {
                                    await response.OutputStream.WriteAsync(bodySuffix, token);
                                }

                                return(true);
                            }

                            if (defaultAction == null)
                            {
                                throw new ArgumentNullException(nameof(defaultAction),
                                                                $"As result '{(result != null ? result.GetType().GetOperationName() : "")}' is not a supported responseType, a defaultAction must be supplied");
                            }

                            if (bodyPrefix != null)
                            {
                                await response.OutputStream.WriteAsync(bodyPrefix, token);
                            }

                            if (result != null)
                            {
                                await defaultAction(request, result, response.OutputStream);
                            }

                            if (bodySuffix != null)
                            {
                                await response.OutputStream.WriteAsync(bodySuffix, token);
                            }
                        }

                    return(false);
                }
                catch (Exception originalEx)
                {
                    //.NET Core prohibits some status codes from having a body
                    if (originalEx is InvalidOperationException invalidEx)
                    {
                        Log.Error(invalidEx.Message, invalidEx);
                        await response.OutputStream.FlushAsync(token); // Prevent hanging clients
                    }

                    await HandleResponseWriteException(originalEx, request, response, defaultContentType);

                    return(true);
                }
                finally
                {
                    if (flushAsync) // move async Thread Hop to outside JsConfigScope so .NET v4.5 disposes same scope
                    {
                        try
                        {
                            await response.FlushAsync(token);
                        }
                        catch (Exception flushEx) { Log.Error("response.FlushAsync()", flushEx); }
                    }
                    disposableResult?.Dispose();
                    await response.EndRequestAsync(skipHeaders : true);
                }
            }
        }
コード例 #24
0
        private ParseStringSpanDelegate GetCoreParseStringSpanFn <T>()
        {
            var type = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T);

            if (JsConfig <T> .HasDeserializeFn)
            {
                return(value => JsConfig <T> .ParseFn(Serializer, value.Value()));
            }

            if (type.IsEnum)
            {
                return(x => ParseUtils.TryParseEnum(type, Serializer.UnescapeSafeString(x).Value()));
            }

            if (type == typeof(string))
            {
                return(Serializer.UnescapeStringAsObject);
            }

            if (type == typeof(object))
            {
                return(DeserializeType <TSerializer> .ObjectStringToType);
            }

            var specialParseFn = ParseUtils.GetSpecialParseMethod(type);

            if (specialParseFn != null)
            {
                return(v => specialParseFn(v.Value()));
            }

            if (type.IsArray)
            {
                return(DeserializeArray <T, TSerializer> .ParseStringSpan);
            }

            var builtInMethod = DeserializeBuiltin <T> .ParseStringSpan;

            if (builtInMethod != null)
            {
                return(value => builtInMethod(Serializer.UnescapeSafeString(value)));
            }

            if (type.HasGenericType())
            {
                if (type.IsOrHasGenericInterfaceTypeOf(typeof(IList <>)))
                {
                    return(DeserializeList <T, TSerializer> .ParseStringSpan);
                }

                if (type.IsOrHasGenericInterfaceTypeOf(typeof(IDictionary <,>)))
                {
                    return(DeserializeDictionary <TSerializer> .GetParseStringSegmentMethod(type));
                }

                if (type.IsOrHasGenericInterfaceTypeOf(typeof(ICollection <>)))
                {
                    return(DeserializeCollection <TSerializer> .GetParseStringSegmentMethod(type));
                }

                if (type.HasAnyTypeDefinitionsOf(typeof(Queue <>)) ||
                    type.HasAnyTypeDefinitionsOf(typeof(Stack <>)))
                {
                    return(DeserializeSpecializedCollections <T, TSerializer> .ParseStringSpan);
                }

                if (type.IsOrHasGenericInterfaceTypeOf(typeof(KeyValuePair <,>)))
                {
                    return(DeserializeKeyValuePair <TSerializer> .GetParseStringSegmentMethod(type));
                }

                if (type.IsOrHasGenericInterfaceTypeOf(typeof(IEnumerable <>)))
                {
                    return(DeserializeEnumerable <T, TSerializer> .ParseStringSpan);
                }

                var customFn = DeserializeCustomGenericType <TSerializer> .GetParseStringSegmentMethod(type);

                if (customFn != null)
                {
                    return(customFn);
                }
            }

            var pclParseFn = PclExport.Instance.GetJsReaderParseStringSpanMethod <TSerializer>(typeof(T));

            if (pclParseFn != null)
            {
                return(pclParseFn);
            }

            var isDictionary = typeof(T) != typeof(IEnumerable) && typeof(T) != typeof(ICollection) &&
                               (typeof(T).IsAssignableFrom(typeof(IDictionary)) || typeof(T).HasInterface(typeof(IDictionary)));

            if (isDictionary)
            {
                return(DeserializeDictionary <TSerializer> .GetParseStringSegmentMethod(type));
            }

            var isEnumerable = typeof(T).IsAssignableFrom(typeof(IEnumerable)) ||
                               typeof(T).HasInterface(typeof(IEnumerable));

            if (isEnumerable)
            {
                var parseFn = DeserializeSpecializedCollections <T, TSerializer> .ParseStringSpan;
                if (parseFn != null)
                {
                    return(parseFn);
                }
            }

            if (type.IsValueType)
            {
                //at first try to find more faster `ParseStringSegment` method
                var staticParseStringSegmentMethod = StaticParseMethod <T> .ParseStringSpan;
                if (staticParseStringSegmentMethod != null)
                {
                    return(value => staticParseStringSegmentMethod(Serializer.UnescapeSafeString(value)));
                }

                //then try to find `Parse` method
                var staticParseMethod = StaticParseMethod <T> .Parse;
                if (staticParseMethod != null)
                {
                    return(value => staticParseMethod(Serializer.UnescapeSafeString(value).ToString()));
                }
            }
            else
            {
                var staticParseStringSegmentMethod = StaticParseRefTypeMethod <TSerializer, T> .ParseStringSpan;
                if (staticParseStringSegmentMethod != null)
                {
                    return(value => staticParseStringSegmentMethod(Serializer.UnescapeSafeString(value)));
                }

                var staticParseMethod = StaticParseRefTypeMethod <TSerializer, T> .Parse;
                if (staticParseMethod != null)
                {
                    return(value => staticParseMethod(Serializer.UnescapeSafeString(value).ToString()));
                }
            }

            var typeConstructor = DeserializeType <TSerializer> .GetParseStringSpanMethod(TypeConfig <T> .GetState());

            if (typeConstructor != null)
            {
                return(typeConstructor);
            }

            var stringConstructor = DeserializeTypeUtils.GetParseStringSegmentMethod(type);

            if (stringConstructor != null)
            {
                return(stringConstructor);
            }

            return(DeserializeType <TSerializer> .ParseAbstractType <T>);
        }