private XmlRpcRequest MakeXmlRpcRequest(WebRequest webReq, MethodInfo mi, object[] parameters, object clientObj, string xmlRpcMethod, Guid proxyId) { webReq.Method = "POST"; webReq.ContentType = "text/xml"; var rpcMethodName = XmlRpcTypeInfo.GetRpcMethodName(mi); return(new XmlRpcRequest(rpcMethodName, parameters, mi, xmlRpcMethod, proxyId)); }
private void CheckImplictString(Type valType, MappingStack mappingStack) { if (valType != null && valType != typeof(string) && !valType.IsEnum) { throw new XmlRpcTypeMismatchException(mappingStack.MappingType + " contains implicit string value where " + XmlRpcTypeInfo.GetXmlRpcTypeString(valType) + " expected " + StackDump(mappingStack)); } }
string GetEffectiveUrl(object clientObj) { // client can either have define URI in attribute or have set it // via proxy's ServiceURI property - but must exist by now if (!string.IsNullOrEmpty(Url)) { return(Url); } var useUrl = XmlRpcTypeInfo.GetUrlFromAttribute(clientObj.GetType()); if (!string.IsNullOrEmpty(useUrl)) { return(useUrl); } throw new XmlRpcMissingUrl("Proxy XmlRpcUrl attribute or Url property not set."); }
private void CheckExpectedType(Type expectedType, Type actualType, MappingStack mappingStack) { if (expectedType != null && expectedType.IsEnum) { Type[] i4Types = { typeof(byte), typeof(sbyte), typeof(short), typeof(ushort), typeof(int) }; Type[] i8Types = { typeof(uint), typeof(long) }; var underlyingType = Enum.GetUnderlyingType(expectedType); if (Array.IndexOf(i4Types, underlyingType) >= 0) { expectedType = typeof(int); } else if (Array.IndexOf(i8Types, underlyingType) >= 0) { expectedType = typeof(long); } else { throw new XmlRpcInvalidEnumValue(mappingStack.MappingType + " contains " + XmlRpcTypeInfo.GetXmlRpcTypeString(actualType) + " which cannot be mapped to " + XmlRpcTypeInfo.GetXmlRpcTypeString(expectedType) + " " + StackDump(mappingStack)); } } // TODO: throw exception for invalid enum type if (expectedType != null && expectedType != typeof(object) && expectedType != actualType && (actualType.IsValueType && expectedType != typeof(Nullable <>).MakeGenericType(actualType))) { throw new XmlRpcTypeMismatchException(mappingStack.MappingType + " contains " + XmlRpcTypeInfo.GetXmlRpcTypeString(actualType) + " value where " + XmlRpcTypeInfo.GetXmlRpcTypeString(expectedType) + " expected " + StackDump(mappingStack)); } }
public void Serialize(XmlWriter xtw, object o, MappingActions mappingActions, List <object> nestedObjs) { if (nestedObjs.Contains(o)) { throw new XmlRpcUnsupportedTypeException(nestedObjs[0].GetType(), "Cannot serialize recursive data structure"); } nestedObjs.Add(o); try { xtw.WriteStartElement("", "value", ""); var xType = XmlRpcTypeInfo.GetXmlRpcType(o); switch (xType) { case XmlRpcType.tArray: xtw.WriteStartElement("", "array", ""); xtw.WriteStartElement("", "data", ""); var a = (Array)o; foreach (object aobj in a) { //if (aobj == null) // throw new XmlRpcMappingSerializeException(String.Format( // "Items in array cannot be null ({0}[]).", //o.GetType().GetElementType())); Serialize(xtw, aobj, mappingActions, nestedObjs); } WriteFullEndElement(xtw); WriteFullEndElement(xtw); break; case XmlRpcType.tMultiDimArray: var mda = (Array)o; var indices = new int[mda.Rank]; BuildArrayXml(xtw, mda, 0, indices, mappingActions, nestedObjs); break; case XmlRpcType.tBase64: var buf = (byte[])o; xtw.WriteStartElement("", "base64", ""); xtw.WriteBase64(buf, 0, buf.Length); WriteFullEndElement(xtw); break; case XmlRpcType.tBoolean: var strBoolVal = (bool)o ? "1" : "0"; WriteFullElementString(xtw, "boolean", strBoolVal); break; case XmlRpcType.tDateTime: var dt = (DateTime)o; var sdt = dt.ToString("yyyyMMdd'T'HH':'mm':'ss", DateTimeFormatInfo.InvariantInfo); WriteFullElementString(xtw, "dateTime.iso8601", sdt); break; case XmlRpcType.tDouble: double doubleVal = (double)o; WriteFullElementString(xtw, "double", doubleVal.ToString(null, CultureInfo.InvariantCulture)); break; case XmlRpcType.tHashtable: xtw.WriteStartElement("", "struct", ""); var xrs = o as XmlRpcStruct; foreach (object obj in xrs.Keys) { string skey = obj as string; xtw.WriteStartElement("", "member", ""); WriteFullElementString(xtw, "name", skey); Serialize(xtw, xrs[skey], mappingActions, nestedObjs); WriteFullEndElement(xtw); } WriteFullEndElement(xtw); break; case XmlRpcType.tInt32: o = SerializeInt32(xtw, o, mappingActions); break; case XmlRpcType.tInt64: o = SerializeInt64(xtw, o, mappingActions); break; case XmlRpcType.tString: SerializeString(xtw, o); break; case XmlRpcType.tStruct: MappingActions structActions = GetMappingActions(o.GetType(), mappingActions); xtw.WriteStartElement("", "struct", ""); MemberInfo[] mis = o.GetType().GetMembers(); foreach (var mi in mis) { if (Attribute.IsDefined(mi, typeof(NonSerializedAttribute))) { continue; } if (mi.MemberType == MemberTypes.Field) { var fi = (FieldInfo)mi; var member = fi.Name; var attrchk = Attribute.GetCustomAttribute(fi, typeof(XmlRpcMemberAttribute)); if (attrchk != null && attrchk is XmlRpcMemberAttribute) { var mmbr = ((XmlRpcMemberAttribute)attrchk).Member; if (mmbr != "") { member = mmbr; } } var memberActions = MemberMappingActions(o.GetType(), fi.Name, structActions); if (fi.GetValue(o) == null) { if (memberActions.NullMappingAction == NullMappingAction.Ignore) { continue; } if (memberActions.NullMappingAction == NullMappingAction.Error) { throw new XmlRpcMappingSerializeException(@"Member """ + member + @""" of struct """ + o.GetType().Name + @""" cannot be null."); } } xtw.WriteStartElement("", "member", ""); WriteFullElementString(xtw, "name", member); Serialize(xtw, fi.GetValue(o), memberActions, nestedObjs); WriteFullEndElement(xtw); } else if (mi.MemberType == MemberTypes.Property) { var pi = (PropertyInfo)mi; var member = pi.Name; var attrchk = Attribute.GetCustomAttribute(pi, typeof(XmlRpcMemberAttribute)); if (attrchk != null && attrchk is XmlRpcMemberAttribute) { var mmbr = ((XmlRpcMemberAttribute)attrchk).Member; if (mmbr != "") { member = mmbr; } } var memberActions = MemberMappingActions(o.GetType(), pi.Name, structActions); if (pi.GetValue(o, null) == null) { if (memberActions.NullMappingAction == NullMappingAction.Ignore) { continue; } if (memberActions.NullMappingAction == NullMappingAction.Error) { throw new XmlRpcMappingSerializeException(@"Member """ + member + @""" of struct """ + o.GetType().Name + @""" cannot be null."); } } xtw.WriteStartElement("", "member", ""); WriteFullElementString(xtw, "name", member); Serialize(xtw, pi.GetValue(o, null), memberActions, nestedObjs); WriteFullEndElement(xtw); } } WriteFullEndElement(xtw); break; case XmlRpcType.tVoid: WriteFullElementString(xtw, "string", ""); break; case XmlRpcType.tNil: xtw.WriteStartElement("nil"); WriteFullEndElement(xtw); break; default: throw new XmlRpcUnsupportedTypeException(o.GetType()); } WriteFullEndElement(xtw); } catch (NullReferenceException) { throw new XmlRpcNullReferenceException("Attempt to serialize data " + "containing null reference"); } finally { nestedObjs.RemoveAt(nestedObjs.Count - 1); } }
private object MapArray(IEnumerator <Node> iter, Type valType, MappingStack mappingStack, MappingAction mappingAction, out Type mappedType) { mappedType = null; // required type must be an array if (valType != null && !(valType.IsArray == true || valType == typeof(Array) || valType == typeof(object))) { throw new XmlRpcTypeMismatchException(mappingStack.MappingType + $" contains array value where{XmlRpcTypeInfo.GetXmlRpcTypeString(valType)}" + $" expected {StackDump(mappingStack)}"); } if (valType != null) { XmlRpcType xmlRpcType = XmlRpcTypeInfo.GetXmlRpcType(valType); if (xmlRpcType == XmlRpcType.tMultiDimArray) { mappingStack.Push("array mapped to type " + valType.Name); return(MapMultiDimArray(iter, valType, mappingStack, mappingAction)); } mappingStack.Push("array mapped to type " + valType.Name); } else { mappingStack.Push("array"); } var values = new List <object>(); var elemType = DetermineArrayItemType(valType); while (iter.MoveNext() && iter.Current is ValueNode) { mappingStack.Push(string.Format("element {0}", values.Count)); var value = MapValueNode(iter, elemType, mappingStack, mappingAction); values.Add(value); mappingStack.Pop(); } var bGotType = false; Type useType = null; foreach (object value in values) { if (value == null) { continue; } if (bGotType) { if (useType != value.GetType()) { useType = null; } continue; } useType = value.GetType(); bGotType = true; } var args = new object[1]; args[0] = values.Count; object retObj = null; if (valType != null && valType != typeof(Array) && valType != typeof(object)) { retObj = CreateArrayInstance(valType, args); } else { if (useType == null) { retObj = CreateArrayInstance(typeof(object[]), args); } else { retObj = Array.CreateInstance(useType, (int)args[0]); } } for (int j = 0; j < values.Count; j++) { ((Array)retObj).SetValue(values[j], j); } mappingStack.Pop(); return(retObj); }
private object MapStruct(IEnumerator <Node> iter, Type valueType, MappingStack mappingStack, MappingAction mappingAction, out Type mappedType) { mappedType = null; if (valueType.IsPrimitive) { throw new XmlRpcTypeMismatchException(mappingStack.MappingType + " contains struct value where " + XmlRpcTypeInfo.GetXmlRpcTypeString(valueType) + " expected " + StackDump(mappingStack)); } if (valueType.IsGenericType && valueType.GetGenericTypeDefinition() == typeof(Nullable <>)) { valueType = valueType.GetGenericArguments()[0]; } object retObj; try { retObj = Activator.CreateInstance(valueType); } catch (Exception) { throw new XmlRpcTypeMismatchException(mappingStack.MappingType + " contains struct value where " + XmlRpcTypeInfo.GetXmlRpcTypeString(valueType) + $" expected (as type {valueType.Name}) " + StackDump(mappingStack)); } // Note: mapping action on a struct is only applied locally - it // does not override the global mapping action when members of the // struct are mapped var localAction = mappingAction; if (valueType != null) { mappingStack.Push("struct mapped to type " + valueType.Name); localAction = StructMappingAction(valueType, mappingAction); } else { mappingStack.Push("struct"); } // create map of field names and remove each name from it as // processed so we can determine which fields are missing var names = new List <string>(); CreateFieldNamesMap(valueType, names); var fieldCount = 0; var rpcNames = new List <string>(); try { while (iter.MoveNext()) { if (!(iter.Current is StructMember)) { break; } var rpcName = (iter.Current as StructMember).Value; if (rpcNames.Contains(rpcName)) { if (!IgnoreDuplicateMembers) { throw new XmlRpcInvalidXmlRpcException(mappingStack.MappingType + $" contains struct value with duplicate member {rpcName} {StackDump(mappingStack)}"); } continue; } rpcNames.Add(rpcName); var name = GetStructName(valueType, rpcName) ?? rpcName; MemberInfo mi = valueType.GetField(name); if (mi == null) { mi = valueType.GetProperty(name); } if (mi == null) { iter.MoveNext(); // move to value if (iter.Current is ComplexValueNode) { int depth = iter.Current.Depth; while (!(iter.Current is EndComplexValueNode && iter.Current.Depth == depth)) { iter.MoveNext(); } } continue; } if (names.Contains(name)) { names.Remove(name); } else { if (Attribute.IsDefined(mi, typeof(NonSerializedAttribute))) { mappingStack.Push($"member {name}"); throw new XmlRpcNonSerializedMember("Cannot map XML-RPC struct member onto member marked as [NonSerialized]: " + StackDump(mappingStack)); } } var memberType = mi.MemberType == MemberTypes.Field ? (mi as FieldInfo).FieldType : (mi as PropertyInfo).PropertyType; var mappingMsg = valueType == null ? $"member {name}" : $"member {name} mapped to type {memberType.Name}"; iter.MoveNext(); var valObj = OnStack(mappingMsg, mappingStack, () => MapValueNode(iter, memberType, mappingStack, mappingAction)); if (mi.MemberType == MemberTypes.Field) { (mi as FieldInfo).SetValue(retObj, valObj); } else { (mi as PropertyInfo).SetValue(retObj, valObj, null); } fieldCount++; } if (localAction == MappingAction.Error && names.Count > 0) { ReportMissingMembers(valueType, names, mappingStack); } return(retObj); } finally { mappingStack.Pop(); } }