Click here to Skip to main content
Click here to Skip to main content
 
Add your own
alternative version

Build ReST based Web Services in .NET/C#

, 12 Jul 2009 CPOL
A ReST based Web Service for C#.
PoC.Web.ReSTService.zip
PoC.Web.ReSTService
obj
Debug
PoC.Web.ReSTService.dll
Refactor
PoC.Web.ReSTService.dll
Properties
PoC_Web_ReSTService.zip
PoC.Web.ReSTService.dll
PoC.Web.ReSTService.dll
TestWebApp.zip
tstWebApplication1
App_Data
bin
PoC.Web.ReSTService.dll
tstWebApplication1.dll
Properties
tstWebApplication1.csproj.user
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Collections;
using System.Globalization;

namespace PoC.Web.Services.Utilities
{
    public class TypeConversion
    {
        private static IDictionary<Type, TypeConverter> customConverters;
        static TypeConversion()
        {
            customConverters = new Dictionary<Type, TypeConverter>();
            AddConverter(typeof(System.Xml.XmlDocument), new XmlDocumentConverter());
            //TODO: Add for external converters...
        }
        public static void AddConverter(Type forType, TypeConverter conv)
        {
            //Assert.NotNull(forType, "forType");
            //Assert.NotNull(conv, "conv");
            customConverters.Add(forType, conv);
        }


        public static object ConvertType(string propName, object valueToSet, Type typeToSet)
        {
            if (valueToSet != null)
            {
                if (IsAssignableFrom(valueToSet, typeToSet))
                {
                    return valueToSet;
                }
                if (typeToSet != null && typeToSet.IsArray)
                {
                    Type componentType = typeToSet.GetElementType();
                    if (valueToSet is IList)
                    {
                        IList elements = (IList)valueToSet;
                        return ToArray(componentType, elements, propName);
                    }
                    else if (valueToSet is string)
                    {
                        if (typeToSet.Equals(typeof(char[])))
                        {
                            return ((string)valueToSet).ToCharArray();
                        }
                        else
                        {
                            string[] elements = GetStringList((string)valueToSet);
                            return ToArray(componentType, elements, propName);
                        }
                    }
                    else if (!valueToSet.GetType().IsArray)
                    {
                        Array result = Array.CreateInstance(componentType, 1);
                        object val = ConvertType(propName, valueToSet, componentType);
                        result.SetValue(val, 0);
                        return result;
                    }
                }

                #region Type Converter Factory
                try
                {
                    TypeConverter typeConverter = GetTypeConverter(typeToSet);
                    if (typeConverter != null && typeConverter.CanConvertFrom(valueToSet.GetType()))
                    {
                        try
                        {
                            valueToSet = typeConverter.ConvertFrom(valueToSet);
                        }
                        catch
                        {
                            if (valueToSet is string)
                            {
                                valueToSet = typeConverter.ConvertFromInvariantString((string)valueToSet);
                            }
                        }
                    }
                    else
                    {
                        typeConverter = GetTypeConverter(valueToSet.GetType());
                        if (typeConverter != null && typeConverter.CanConvertTo(typeToSet))
                        {
                            valueToSet = typeConverter.ConvertTo(valueToSet, typeToSet);
                        }
                        else if (customConverters.ContainsKey(typeToSet) && customConverters[typeToSet].CanConvertFrom(valueToSet.GetType()))
                        {
                            valueToSet = customConverters[typeToSet].ConvertFrom(valueToSet);
                        }
                        else
                        {
                            // finally look if it's an enum
                            if (typeToSet != null
                                && typeToSet.IsEnum
                                && (!(valueToSet is float)
                                    && (!(valueToSet is double))))
                            {
                                // convert numeric value into enum's underlying type
                                Type numericType = Enum.GetUnderlyingType(typeToSet);
                                valueToSet = System.Convert.ChangeType(valueToSet, numericType);

                                if (Enum.IsDefined(typeToSet, valueToSet))
                                {
                                    valueToSet = Enum.ToObject(typeToSet, valueToSet);
                                }
                                else
                                {
                                    throw new InvalidCastException(string.Format("Property [{0}] could not be set. Type mismatch detected.", propName));
                                }
                            }
                            else
                            {
                                throw new InvalidCastException(string.Format("Property [{0}] could not be set. Type mismatch detected.", propName));
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw new InvalidCastException(string.Format("Property [{0}] could not be set. Type mismatch detected.", propName), ex);

                }
                #endregion
                if (valueToSet == null)
                {
                    throw new InvalidCastException(string.Format("Property [{0}] could not be set. Type mismatch detected.", propName));
                }
            }
            return valueToSet;
        }
        private static TypeConverter GetTypeConverter(Type type)
        {
            if (type == null) throw new ArgumentNullException("type"); 
            //Assert.NotNull(type, "type");
            TypeConverter converter = null;
            if (converter == null)
            {
                if (type.IsEnum)
                {
                    converter = new EnumConverter(type);
                }
                else
                {
                    converter = TypeDescriptor.GetConverter(type);
                }
            }

            return converter;
        }
        private static string[] GetStringList(string p)
        {
            return ToStringArray(p, ",");
        }
        public static string[] ToStringArray(string input, string delimiter)
        {
            if (input == null)
            {
                return new string[0];
            }
            if (string.IsNullOrEmpty(delimiter))
            {
                return new string[] { input };
            }
            return input.Split(delimiter[0]);
        }


        private static object ToArray(Type t, IList elem, string propName)
        {
            Array destination = Array.CreateInstance(t, elem.Count);
            for (int i = 0; i < elem.Count; ++i)
            {
                object value = ConvertType(propName + "[" + i + "]", elem[i], t);
                destination.SetValue(value, i);
            }
            return destination;
        }

        private static bool IsAssignableFrom(object newValue, Type requiredType)
        {
            if (newValue is MarshalByRefObject)
            {
                return true;
            }
            if (requiredType == null)
            {
                return false;
            }
            return requiredType.IsAssignableFrom(newValue.GetType());
        }

        public static GrafT Deserialize<GrafT>(System.IO.Stream stream)
        {
            System.Xml.Serialization.XmlSerializer deserializer = new System.Xml.Serialization.XmlSerializer(typeof(GrafT));
            return (GrafT) deserializer.Deserialize(stream);
        }
    }
    public class XmlDocumentConverter : TypeConverter
    {
        public override bool CanConvertFrom(
            ITypeDescriptorContext context, Type sourceType)
        {
            if (sourceType == typeof(string))
            {
                return true;
            }
            return TypeDescriptor.GetConverter(typeof(System.Xml.XmlDocument)).CanConvertFrom(context, sourceType);
            //return base.CanConvertFrom(context, sourceType);
        }

        public override object ConvertFrom(
            ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            string xmlstr = value as string;
            if (xmlstr != null)
            {
                System.Xml.XmlDocument dom = new System.Xml.XmlDocument();
                if (xmlstr.Length > 0)
                {
                    dom.LoadXml(xmlstr);
                    return dom;
                }
            }
            return TypeDescriptor.GetConverter(typeof(System.Xml.XmlDocument)).ConvertFrom(context, culture, value);
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Parag.Gadkari

United States United States
Loves coding...

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.141223.1 | Last Updated 12 Jul 2009
Article Copyright 2009 by Parag.Gadkari
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid