/// <summary> /// Get the FQ type name for this datanode. /// We return typeof(object) for ResXNullRef /// </summary> public string GetValueTypeName(ITypeResolutionService typeResolver) { // the type name here is always a FQN if (!string.IsNullOrEmpty(typeName)) { return (typeName == MultitargetUtil.GetAssemblyQualifiedName(typeof(ResXNullRef), typeNameConverter) ? MultitargetUtil.GetAssemblyQualifiedName(typeof(object), typeNameConverter) : typeName); } string result = FileRefType; Type objectType = null; // do we have a fileref? if (result != null) { // try to resolve this type objectType = ResolveType(FileRefType, typeResolver); } else if (nodeInfo != null) { // we dont have a fileref, try to resolve the type of the datanode result = nodeInfo.TypeName; // if typename is null, the default is just a string if (string.IsNullOrEmpty(result)) { // we still dont know... do we have a mimetype? if yes, our only option is to // deserialize to know what we're dealing with... very inefficient... if (!string.IsNullOrEmpty(nodeInfo.MimeType)) { object insideObject = null; try { insideObject = GenerateObjectFromDataNodeInfo(nodeInfo, typeResolver); } catch (Exception ex) { // it'd be better to catch SerializationException but the underlying type resolver // can throw things like FileNotFoundException which is kinda confusing, so I am catching all here.. if (ClientUtils.IsCriticalException(ex)) { throw; } // something went wrong, type is not specified at all or stream is corrupted // return system.object result = MultitargetUtil.GetAssemblyQualifiedName(typeof(object), typeNameConverter); } if (insideObject != null) { result = MultitargetUtil.GetAssemblyQualifiedName(insideObject.GetType(), typeNameConverter); } } else { // no typename, no mimetype, we have a string... result = MultitargetUtil.GetAssemblyQualifiedName(typeof(string), typeNameConverter); } } else { objectType = ResolveType(nodeInfo.TypeName, typeResolver); } } if (objectType != null) { if (objectType == typeof(ResXNullRef)) { result = MultitargetUtil.GetAssemblyQualifiedName(typeof(object), typeNameConverter); } else { result = MultitargetUtil.GetAssemblyQualifiedName(objectType, typeNameConverter); } } return(result); }
private void FillDataNodeInfoFromObject(DataNodeInfo nodeInfo, object value) { if (value is CultureInfo ci) { // special-case CultureInfo, cannot use CultureInfoConverter for serialization nodeInfo.ValueData = ci.Name; nodeInfo.TypeName = MultitargetUtil.GetAssemblyQualifiedName(typeof(CultureInfo), typeNameConverter); } else if (value is string str) { nodeInfo.ValueData = str; } else if (value is byte[] bytes) { nodeInfo.ValueData = ToBase64WrappedString(bytes); nodeInfo.TypeName = MultitargetUtil.GetAssemblyQualifiedName(typeof(byte[]), typeNameConverter); } else { Type valueType = (value == null) ? typeof(object) : value.GetType(); if (value != null && !valueType.IsSerializable) { throw new InvalidOperationException(string.Format(SR.NotSerializableType, name, valueType.FullName)); } TypeConverter tc = TypeDescriptor.GetConverter(valueType); bool toString = tc.CanConvertTo(typeof(string)); bool fromString = tc.CanConvertFrom(typeof(string)); try { if (toString && fromString) { nodeInfo.ValueData = tc.ConvertToInvariantString(value); nodeInfo.TypeName = MultitargetUtil.GetAssemblyQualifiedName(valueType, typeNameConverter); return; } } catch (Exception ex) { // Some custom type converters will throw in ConvertTo(string) // to indicate that this object should be serialized through ISeriazable // instead of as a string. This is semi-wrong, but something we will have to // live with to allow user created Cursors to be serializable. if (ClientUtils.IsSecurityOrCriticalException(ex)) { throw; } } bool toByteArray = tc.CanConvertTo(typeof(byte[])); bool fromByteArray = tc.CanConvertFrom(typeof(byte[])); if (toByteArray && fromByteArray) { byte[] data = (byte[])tc.ConvertTo(value, typeof(byte[])); nodeInfo.ValueData = ToBase64WrappedString(data); nodeInfo.MimeType = ResXResourceWriter.ByteArraySerializedObjectMimeType; nodeInfo.TypeName = MultitargetUtil.GetAssemblyQualifiedName(valueType, typeNameConverter); return; } if (value == null) { nodeInfo.ValueData = string.Empty; nodeInfo.TypeName = MultitargetUtil.GetAssemblyQualifiedName(typeof(ResXNullRef), typeNameConverter); } else { if (binaryFormatter == null) { binaryFormatter = new BinaryFormatter { Binder = new ResXSerializationBinder(typeNameConverter) }; } using (MemoryStream ms = new MemoryStream()) { binaryFormatter.Serialize(ms, value); nodeInfo.ValueData = ToBase64WrappedString(ms.ToArray()); } nodeInfo.MimeType = ResXResourceWriter.DefaultSerializedObjectMimeType; } } }