locked
I have a WCF RESTful service, and I want it to return data in format of YAML RRS feed

  • Question

  • I have a WCF RESTful service, and I want it to return data in format of YAML ..some thing like ResponseFormat = WebMessageFormat.YAML
    Monday, January 2, 2012 5:35 PM

Answers

  • It can be done, but it's not as simple as setting the response format to YAML, since this format is not available out-of-the-box. There are basically two options you can do: one you can serialize the object as YAML and return it as a stream (see code below). That is the simplest one, since you essentially control the output of your operation (you'll be using the raw programming model - more information at http://blogs.msdn.com/b/carlosfigueira/archive/2008/04/17/wcf-raw-programming-model-web.aspx), but it will force you to declare all of your operations returning Stream (if you don't have many, than that's not a problem).

    Another option would be to create a new IDispatchResponseFormatter which knows how to serialize the return values of the operations to that format. You can find more about message formatters, including one example on custom serialization formats, at http://blogs.msdn.com/b/carlosfigueira/archive/2011/05/03/wcf-extensibility-message-formatters.aspx).

        public class Post_73c1b1c2_8085_46d0_9635_efcef68bcc70
        {
            public class Person
            {
                public string Name;
                public int Age;
                public Address Address;
            }
            public class Address
            {
                public string Street;
                public string City;
                public string State;
            }
            public static string SerializeToYaml(object obj)
            {
                StringBuilder sb = new StringBuilder();
                sb.AppendLine("---");
                SerializeToYaml(sb, "", obj);
                sb.AppendLine("...");
                return sb.ToString();
            }
            private static void SerializeToYaml(StringBuilder sb, string indent, object obj)
            {
                Type type = obj.GetType();
                foreach (FieldInfo field in type.GetFields())
                {
                    string name = field.Name;
                    object value = field.GetValue(obj);
                    switch (Type.GetTypeCode(value.GetType()))
                    {
                        case TypeCode.String:
                        case TypeCode.Int32:
                            sb.Append(indent);
                            sb.Append(name);
                            sb.Append(": ");
                            sb.Append(value);
                            sb.AppendLine();
                            break;
                        case TypeCode.Object:
                            sb.Append(indent);
                            sb.Append(name);
                            sb.AppendLine(":");
                            SerializeToYaml(sb, indent + "    ", value);
                            break;
                        default:
                            throw new ArgumentException("Not implemented yet");
                    }
                }
            }
            [ServiceContract]
            public class Service
            {
                [WebGet]
                public Stream GetYaml()
                {
                    Person p = new Person
                    {
                        Name = "John Doe",
                        Age = 25,
                        Address = new Address { Street = "123 Tornado Alley", City = "East Centerville", State = "KS" },
                    };
                    WebOperationContext.Current.OutgoingResponse.ContentType = "text/plain";
                    return new MemoryStream(Encoding.UTF8.GetBytes(SerializeToYaml(p)));
                }
            }
            public static void Test()
            {
                string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
                WebServiceHost host = new WebServiceHost(typeof(Service), new Uri(baseAddress));
                host.Open();
                Console.WriteLine("Host opened");
    
                WebClient c = new WebClient();
                Console.WriteLine(c.DownloadString(baseAddress + "/GetYaml"));
    
                Console.Write("Press ENTER to close the host");
                Console.ReadLine();
                host.Close();
            }
        }
    
    


    Carlos Figueira
    Tuesday, January 3, 2012 5:45 AM