private void SerializeValue(JsonWriter writer, object value) { //JsonConverter converter; _currentRecursionCounter++; if (RecursionLimit > 0 && _currentRecursionCounter > RecursionLimit) { throw new ArgumentException("RecursionLimit exceeded."); } if (value == null) { writer.WriteNull(); } else { JavaScriptConverter jsconverter = _context.GetConverter(value.GetType()); if (jsconverter != null) { value = jsconverter.Serialize(value, _context); if (value == null) { writer.WriteNull(); return; } } Type valueType = value.GetType(); switch (Type.GetTypeCode(valueType)) { case TypeCode.String: writer.WriteValue((string)value); break; case TypeCode.Char: writer.WriteValue((char)value); break; case TypeCode.Boolean: writer.WriteValue((bool)value); break; case TypeCode.SByte: writer.WriteValue((sbyte)value); break; case TypeCode.Int16: writer.WriteValue((short)value); break; case TypeCode.UInt16: writer.WriteValue((ushort)value); break; case TypeCode.Int32: writer.WriteValue((int)value); break; case TypeCode.Byte: writer.WriteValue((byte)value); break; case TypeCode.UInt32: writer.WriteValue((uint)value); break; case TypeCode.Int64: writer.WriteValue((long)value); break; case TypeCode.UInt64: writer.WriteValue((ulong)value); break; case TypeCode.Single: writer.WriteValue((float)value); break; case TypeCode.Double: writer.WriteValue((double)value); break; case TypeCode.DateTime: writer.WriteValue((DateTime)value); break; case TypeCode.Decimal: writer.WriteValue((decimal)value); break; default: ThrowOnReferenceLoop(writer, value); writer.SerializeStack.Push(value); try { Type genDictType; if (value is IDictionary) { SerializeDictionary(writer, (IDictionary)value); } else if (value is IDictionary <string, object> ) { SerializeDictionary(writer, (IDictionary <string, object>)value, null); } else if ((genDictType = ReflectionUtils.GetGenericDictionary(valueType)) != null) { SerializeDictionary(writer, new GenericDictionaryLazyDictionary(value, genDictType), null); } else if (value is IEnumerable) { SerializeEnumerable(writer, (IEnumerable)value); } else { SerializeCustomObject(writer, value, valueType); } } finally { object x = writer.SerializeStack.Pop(); if (x != value) { throw new InvalidOperationException("Serialization stack is corrupted"); } } break; } } _currentRecursionCounter--; }
/// <summary> /// Registers the converter. /// </summary> /// <param name="converter">The converter.</param> public static void RegisterConverter(JavaScriptConverter converter) { jsonSerializer.RegisterConverters(new[] { converter }); }
/// <summary> /// 预处理序列化对象,通过调用此函数,可对序列化进行预处理 /// </summary> /// <param name="input">要序列化的对象</param> /// <param name="type">要序列化的类型,可以是input的基类或input实现的接口</param> /// <param name="resolverTypeLevel">要输出类型信息的级别深度</param> /// <returns>处理结果</returns> /// <remarks>预处理序列化对象,通过调用此函数,可对序列化进行预处理</remarks> public static object PreSerializeObject(object input, Type type, int resolverTypeLevel) { object result = input; if (input != null) { JavaScriptConverter converter = JsonSerializerFactory.GetJavaScriptConverter(input.GetType()); if (converter != null) { result = converter.Serialize(input, JsonSerializerFactory.GetJavaScriptSerializer()); } else { if (input is XElement || input is XmlElement) { result = null; } else if (input is DateTime) { result = input.ToString(); } //当前判断条件,只适用经营指标系统,其他系统请注销此判断条件。 else if (input is double) { result = ((double)input).ToString("F7"); } else if (!(input is ValueType) && !(input is string) && !(input is IDictionary)) { IEnumerable list = input as IEnumerable; if (list != null) { ArrayList a = new ArrayList(); foreach (object o in list) { a.Add(PreSerializeObject(o, null, resolverTypeLevel - 1)); } result = a; } else { Dictionary <string, object> dict = new Dictionary <string, object>(); Type inputType = input.GetType(); if (type != null) { ExceptionHelper.FalseThrow(type.IsAssignableFrom(inputType), string.Format("{0} 没有从类型{1}继承", inputType, type)); } else { type = inputType; } foreach (PropertyInfo pi in type.GetProperties(BindingFlags.Instance | BindingFlags.Public)) { ScriptIgnoreAttribute ignoreAttr = (ScriptIgnoreAttribute)Attribute.GetCustomAttribute(pi, typeof(ScriptIgnoreAttribute), false); if (ignoreAttr == null) { MethodInfo mi = pi.GetGetMethod(); if (mi != null && mi.GetParameters().Length <= 0) { object v = PreSerializeObject(mi.Invoke(input, null), null, resolverTypeLevel - 1); ClientPropertyNameAttribute nameAttr = (ClientPropertyNameAttribute)Attribute.GetCustomAttribute(pi, typeof(ClientPropertyNameAttribute), false); string name = nameAttr == null ? pi.Name : nameAttr.PropertyName; dict.Add(name, v); } } } result = dict; } } } } if (resolverTypeLevel > 0 && result is Dictionary <string, object> ) { Dictionary <string, object> resultDict = result as Dictionary <string, object>; if (!resultDict.ContainsKey("__type")) { resultDict["__type"] = input.GetType().AssemblyQualifiedName; } } return(result); }
public static void DescribeComponent(object instance, ScriptComponentDescriptor descriptor, IUrlResolutionService urlResolver, IControlResolver controlResolver) { // validate preconditions if (instance == null) { throw new ArgumentNullException("instance"); } if (descriptor == null) { throw new ArgumentNullException("descriptor"); } if (urlResolver == null) { urlResolver = instance as IUrlResolutionService; } if (controlResolver == null) { controlResolver = instance as IControlResolver; } // describe properties // PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(instance); PropertyInfo[] properties = instance.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (PropertyInfo prop in properties) { ScriptControlPropertyAttribute propAttr = null; ScriptControlEventAttribute eventAttr = null; string propertyName = prop.Name; System.ComponentModel.AttributeCollection attribs = new System.ComponentModel.AttributeCollection(Attribute.GetCustomAttributes(prop, false)); // Try getting a property attribute propAttr = (ScriptControlPropertyAttribute)attribs[typeof(ScriptControlPropertyAttribute)]; if (propAttr == null || !propAttr.IsScriptProperty) { // Try getting an event attribute eventAttr = (ScriptControlEventAttribute)attribs[typeof(ScriptControlEventAttribute)]; if (eventAttr == null || !eventAttr.IsScriptEvent) { continue; } } // attempt to rename the property/event ClientPropertyNameAttribute nameAttr = (ClientPropertyNameAttribute)attribs[typeof(ClientPropertyNameAttribute)]; if (nameAttr != null && !string.IsNullOrEmpty(nameAttr.PropertyName)) { propertyName = nameAttr.PropertyName; } // determine whether to serialize the value of a property. readOnly properties should always be serialized //bool serialize = true;// prop.ShouldSerializeValue(instance) || prop.IsReadOnly; //if (serialize) //{ // get the value of the property, skip if it is null Control c = null; object value = prop.GetValue(instance, new object[0] { }); if (value == null) { continue; } // convert and resolve the value if (eventAttr != null && prop.PropertyType != typeof(String)) { throw new InvalidOperationException("ScriptControlEventAttribute can only be applied to a property with a PropertyType of System.String."); } else { if (!prop.PropertyType.IsPrimitive && !prop.PropertyType.IsEnum) { if (prop.PropertyType == typeof(Color)) { value = ColorTranslator.ToHtml((Color)value); } else { // TODO: Determine if we should let ASP.NET AJAX handle this type of conversion, as it supports JSON serialization //TypeConverter conv = prop.Converter; //value = conv.ConvertToString(null, CultureInfo.InvariantCulture, value); //if (prop.PropertyType == typeof(CssStyleCollection)) // value = (new CssStyleCollectionJSCoverter()).Serialize(value, new JavaScriptSerializer()); //if (prop.PropertyType == typeof(Style)) // value = (new CssStyleCollectionJSCoverter()).Serialize(((Style)value).GetStyleAttributes(null), new JavaScriptSerializer()); Type valueType = value.GetType(); JavaScriptConverterAttribute attr = (JavaScriptConverterAttribute)attribs[typeof(JavaScriptConverterAttribute)]; JavaScriptConverter converter = attr != null ? (JavaScriptConverter)TypeCreator.CreateInstance(attr.ConverterType) : JSONSerializerFactory.GetJavaScriptConverter(valueType); if (converter != null) { value = converter.Serialize(value, JSONSerializerFactory.GetJavaScriptSerializer()); } else { value = JSONSerializerExecute.PreSerializeObject(value); } //Dictionary<string, object> dict = value as Dictionary<string, object>; //if (dict != null && !dict.ContainsKey("__type")) // dict["__type"] = valueType.AssemblyQualifiedName; } } if (attribs[typeof(IDReferencePropertyAttribute)] != null && controlResolver != null) { c = controlResolver.ResolveControl((string)value); } if (attribs[typeof(UrlPropertyAttribute)] != null && urlResolver != null) { value = urlResolver.ResolveClientUrl((string)value); } } // add the value as an appropriate description if (eventAttr != null) { if (!string.IsNullOrEmpty((string)value)) { descriptor.AddEvent(propertyName, (string)value); } } else if (attribs[typeof(ElementReferenceAttribute)] != null) { if (c == null && controlResolver != null) { c = controlResolver.ResolveControl((string)value); } if (c != null) { value = c.ClientID; } descriptor.AddElementProperty(propertyName, (string)value); } else if (attribs[typeof(ComponentReferenceAttribute)] != null) { if (c == null && controlResolver != null) { c = controlResolver.ResolveControl((string)value); } if (c != null) { //ExtenderControlBase ex = c as ExtenderControlBase; //if (ex != null && ex.BehaviorID.Length > 0) // value = ex.BehaviorID; //else value = c.ClientID; } descriptor.AddComponentProperty(propertyName, (string)value); } else { if (c != null) { value = c.ClientID; } descriptor.AddProperty(propertyName, value); } } //} // determine if we should describe methods foreach (MethodInfo method in instance.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public)) { ScriptControlMethodAttribute methAttr = (ScriptControlMethodAttribute)Attribute.GetCustomAttribute(method, typeof(ScriptControlMethodAttribute)); if (methAttr == null || !methAttr.IsScriptMethod) { continue; } // We only need to support emitting the callback target and registering the WebForms.js script if there is at least one valid method Control control = instance as Control; if (control != null) { // Force WebForms.js control.Page.ClientScript.GetCallbackEventReference(control, null, null, null); // Add the callback target descriptor.AddProperty("_callbackTarget", control.UniqueID); } break; } }
public void TestSkipConversionOnNewModel() { var flavorName1 = "flavorA"; var url1 = "http://a.com"; var outputPath = "D:/Test"; var sfxStyle = "Hmm"; var complexScript = @"// Fills in details for download packages automatically. // This instance created AUTOMATICALLY during a previous run. function AutomatePackages() { " + string.Format(@"SetElement(""FlavorName1"", ""{0}""); SetElement(""FlavorUrl1"", ""{1}""); NextStage(); SelectElement(""IncludedF1P1"", true); NextStage(); SetElement(""OutputPath"", ""{2}""); SelectElement(""WriteXml"", true); SelectElement(""WriteDownloadsXml"", true); SelectElement(""Compile"", true); SelectElement(""GatherFiles"", true); SelectElement(""BuildSfx"", true); SetElement(""SfxStyle"", ""{3}""); SetElement(""SaveSettings"", true);" , flavorName1, url1, outputPath, sfxStyle) + @" }" ; var configuration = new ConfigurationModel { Version = "1.0" }; configuration.Products = new List <ConfigurationModel.Product>(); var mainProduct = "Main Product"; configuration.Products.Add(new ConfigurationModel.Product { Title = mainProduct }); var scriptFile = Path.Combine(TestFolder, "test.js"); var installerFile = Path.Combine(TestFolder, "installer.xml"); File.WriteAllText(scriptFile, complexScript); configuration.Tasks = new ConfigurationModel.TasksToExecuteSettings(); configuration.FileLocation = installerFile; configuration.Save(); // Prove that values started as false Assert.That(configuration.Tasks.BuildSelfExtractingDownloadPackage, Is.False, "Setup did not initiate values to false, test invalid"); Assert.That(configuration.Tasks.Compile, Is.False, "Setup did not initiate values to false, test invalid"); Assert.That(configuration.Tasks.GatherFiles, Is.False, "Setup did not initiate values to false, test invalid"); Assert.That(configuration.Tasks.WriteDownloadsXml, Is.False, "Setup did not initiate values to false, test invalid"); Assert.That(configuration.Tasks.WriteInstallerXml, Is.False, "Setup did not initiate values to false, test invalid"); Assert.That(configuration.Tasks.RememberSettings, Is.False, "Setup did not initiate values to false, test invalid"); // SUT JavaScriptConverter.ConvertJsToXml(scriptFile, installerFile); var serializer = new XmlSerializer(typeof(ConfigurationModel)); using (var textReader = new StreamReader(installerFile)) { var model = (ConfigurationModel)serializer.Deserialize(textReader); Assert.That(model.Tasks.BuildSelfExtractingDownloadPackage, Is.False); Assert.That(model.Tasks.Compile, Is.False); Assert.That(model.Tasks.GatherFiles, Is.False); Assert.That(model.Tasks.WriteDownloadsXml, Is.False); Assert.That(model.Tasks.WriteInstallerXml, Is.False); Assert.That(model.Tasks.RememberSettings, Is.False); Assert.That(model.Tasks.OutputFolder, Is.Null); } }
public void TestFeatureProductSelection() { var flavorName1 = "flavorA"; var flavorName2 = "flavorB"; var url1 = "http://a.com"; var url2 = "http://b.com"; var complexScript = @"// Fills in details for download packages automatically. // This instance created AUTOMATICALLY during a previous run. function AutomatePackages() { " + string.Format(@"SetElement(""FlavorName1"", ""{0}""); SetElement(""FlavorUrl1"", ""{1}""); AddFlavor(); SetElement(""FlavorName2"", ""{2}""); SetElement(""FlavorUrl2"", ""{3}""); NextStage(); SelectElement(""IncludedF1P1"", true); SelectElement(""IncludedF1P2"", false); SelectElement(""IncludedF2P1"", false); SelectElement(""IncludedF2P2"", true); NextStage();" , flavorName1, url1, flavorName2, url2) + @" }" ; var configuration = new ConfigurationModel(); // The configuration needs to have 2 Products for the given JavaScript configuration.Products = new List <ConfigurationModel.Product>(); var mainProduct = "Main Product"; configuration.Products.Add(new ConfigurationModel.Product { Title = mainProduct }); var dependency = "Dependency"; configuration.Products.Add(new ConfigurationModel.Product { Title = dependency }); var scriptFile = Path.Combine(TestFolder, "test.js"); var installerFile = Path.Combine(TestFolder, "installer.xml"); File.WriteAllText(scriptFile, complexScript); configuration.FileLocation = installerFile; configuration.Save(); JavaScriptConverter.ConvertJsToXml(scriptFile, installerFile); var serializer = new XmlSerializer(typeof(ConfigurationModel)); using (var textReader = new StreamReader(installerFile)) { var model = (ConfigurationModel)serializer.Deserialize(textReader); Assert.That(model.Flavors, Is.Not.Null); Assert.That(model.Flavors.Count, Is.EqualTo(2)); var firstFlavor = model.Flavors[0]; var secondFlavor = model.Flavors[1]; Assert.That(firstFlavor.FlavorName, Is.EqualTo(flavorName1)); Assert.That(firstFlavor.DownloadURL, Is.EqualTo(url1)); Assert.That(firstFlavor.IncludedProductTitles[0], Is.EqualTo(mainProduct)); Assert.That(secondFlavor.FlavorName, Is.EqualTo(flavorName2)); Assert.That(secondFlavor.DownloadURL, Is.EqualTo(url2)); Assert.That(secondFlavor.IncludedProductTitles[0], Is.EqualTo(dependency)); } }