locked
Data types supported by WebGet RRS feed

  • Question

  • Hi

    I remember that when we could use HttpGet in ASMX services only with the primitive data types and not the complex ones like a custom class, dictionary, etc. But in case of the WCF WebGet, what all data types are supported? Is it the same as in the ASMX or does it support the complex data types also?

     

    Thanks


    Akshaya K Sharma
    Wednesday, November 10, 2010 9:26 AM

Answers

  • For the response, all serializable types are supported, as Ido mentioned. For the request, by default only a certain number of parameters (primitives) are supported, but you can override the behavior by providing your own QueryStringConverter implementation (http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.querystringconverter.aspx), which will tell WCF how to convert between the string in the query string (where the input parameters to WebGet operations are passed) and the actual parameter type.

    There is also one out-of-the-box implentation of a QueryStringConverter (QSC), the JsonQueryStringConverter (JQSC), which understand JSON-formatted parameters in the query string. The example below shows both the JQSC and a custom QSC for a user-defined type.

      public class Post_aca60ca7_03c7_4dc0_b671_61682bae2ea8
      {
        [DataContract(Name = "Person", Namespace = "")]
        public class Person
        {
          [DataMember]
          public string Name;
          [DataMember]
          public int Age;
        }
        [ServiceContract]
        public interface ITest
        {
          [WebGet(ResponseFormat = WebMessageFormat.Json)]
          Person GetPersonWithMyQSC(Person p);
          [WebGet(ResponseFormat = WebMessageFormat.Json)]
          Person GetPersonWithJsonQSC(Person p);
        }
        public class Service : ITest
        {
          public Person GetPersonWithMyQSC(Person p) { return p; }
          public Person GetPersonWithJsonQSC(Person p) { return p; }
        }
        class MyQueryStringConverter : QueryStringConverter
        {
          public override bool CanConvert(Type type)
          {
            return type == typeof(Person) || base.CanConvert(type);
          }
          public override object ConvertStringToValue(string parameter, Type parameterType)
          {
            if (parameterType == typeof(Person))
            {
              string separator = "---";
              int separatorIndex = parameter.IndexOf(separator);
              string name = parameter.Substring(0, separatorIndex);
              int age = int.Parse(parameter.Substring(separatorIndex + separator.Length));
              return new Person { Name = name, Age = age };
            }
            else
            {
              return base.ConvertStringToValue(parameter, parameterType);
            }
          }
        }
        class MyWebHttpBehavior : WebHttpBehavior
        {
          protected override QueryStringConverter GetQueryStringConverter(OperationDescription operationDescription)
          {
            if (operationDescription.Name == "GetPersonWithMyQSC")
            {
              return new MyQueryStringConverter();
            }
            else
            {
              return new JsonQueryStringConverter();
            }
          }
        }
        public static void Test()
        {
          string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
          ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
          ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(ITest), new WebHttpBinding(), "");
          MyWebHttpBehavior behavior = new MyWebHttpBehavior();
          endpoint.Behaviors.Add(behavior);
          host.Open();
    
          Console.WriteLine("Host opened");
    
          Util.SendRequest(baseAddress + "/GetPersonWithMyQSC?p=John%20Doe---23", "GET", null, null);
          Util.SendRequest(baseAddress + "/GetPersonWithJsonQSC?p=%7B%22Name%22%3A%22John%20Doe%22%2C%22Age%22%3A23%7D", "GET", null, null);
    
          Console.WriteLine("Press ENTER to close");
          Console.ReadLine();
          host.Close();
        }
      }
      public static class Util
      {
        public static string SendRequest(string uri, string method, string contentType, string body)
        {
          return SendRequest(uri, method, contentType, body, null);
        }
        public static string SendRequest(string uri, string method, string contentType, string body, Dictionary<string, string> headers)
        {
          string responseBody = null;
    
          HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(uri);
          req.Method = method;
          if (headers != null)
          {
            foreach (string headerName in headers.Keys)
            {
              req.Headers[headerName] = headers[headerName];
            }
          }
          if (!String.IsNullOrEmpty(contentType))
          {
            req.ContentType = contentType;
          }
    
          if (body != null)
          {
            byte[] bodyBytes = Encoding.UTF8.GetBytes(body);
            req.GetRequestStream().Write(bodyBytes, 0, bodyBytes.Length);
            req.GetRequestStream().Close();
          }
    
          HttpWebResponse resp;
          try
          {
            resp = (HttpWebResponse)req.GetResponse();
          }
          catch (WebException e)
          {
            resp = (HttpWebResponse)e.Response;
          }
    
          if (resp == null)
          {
            responseBody = null;
            Console.WriteLine("Response is null");
          }
          else
          {
            Console.WriteLine("HTTP/{0} {1} {2}", resp.ProtocolVersion, (int)resp.StatusCode, resp.StatusDescription);
            foreach (string headerName in resp.Headers.AllKeys)
            {
              Console.WriteLine("{0}: {1}", headerName, resp.Headers[headerName]);
            }
            Console.WriteLine();
            Stream respStream = resp.GetResponseStream();
            if (respStream != null)
            {
              responseBody = new StreamReader(respStream).ReadToEnd();
              Console.WriteLine(responseBody);
            }
            else
            {
              Console.WriteLine("HttpWebResponse.GetResponseStream returned null");
            }
          }
    
          Console.WriteLine();
          Console.WriteLine(" *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* ");
          Console.WriteLine();
    
          return responseBody;
        }
      }
    
    
    Wednesday, November 10, 2010 5:56 PM

All replies

  • As far as I know, there's no special limitation of response serializatio when using WebGet. The result will just be serialized as plain XML (POX) or JSON.

    You might have a problem with circular references when serializing, because circular references are not supported in JSON and POX (you'll probably get an exception from the service).


    Please mark posts as answers/helpful if it answers your question
    Wednesday, November 10, 2010 10:10 AM
  • For the response, all serializable types are supported, as Ido mentioned. For the request, by default only a certain number of parameters (primitives) are supported, but you can override the behavior by providing your own QueryStringConverter implementation (http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.querystringconverter.aspx), which will tell WCF how to convert between the string in the query string (where the input parameters to WebGet operations are passed) and the actual parameter type.

    There is also one out-of-the-box implentation of a QueryStringConverter (QSC), the JsonQueryStringConverter (JQSC), which understand JSON-formatted parameters in the query string. The example below shows both the JQSC and a custom QSC for a user-defined type.

      public class Post_aca60ca7_03c7_4dc0_b671_61682bae2ea8
      {
        [DataContract(Name = "Person", Namespace = "")]
        public class Person
        {
          [DataMember]
          public string Name;
          [DataMember]
          public int Age;
        }
        [ServiceContract]
        public interface ITest
        {
          [WebGet(ResponseFormat = WebMessageFormat.Json)]
          Person GetPersonWithMyQSC(Person p);
          [WebGet(ResponseFormat = WebMessageFormat.Json)]
          Person GetPersonWithJsonQSC(Person p);
        }
        public class Service : ITest
        {
          public Person GetPersonWithMyQSC(Person p) { return p; }
          public Person GetPersonWithJsonQSC(Person p) { return p; }
        }
        class MyQueryStringConverter : QueryStringConverter
        {
          public override bool CanConvert(Type type)
          {
            return type == typeof(Person) || base.CanConvert(type);
          }
          public override object ConvertStringToValue(string parameter, Type parameterType)
          {
            if (parameterType == typeof(Person))
            {
              string separator = "---";
              int separatorIndex = parameter.IndexOf(separator);
              string name = parameter.Substring(0, separatorIndex);
              int age = int.Parse(parameter.Substring(separatorIndex + separator.Length));
              return new Person { Name = name, Age = age };
            }
            else
            {
              return base.ConvertStringToValue(parameter, parameterType);
            }
          }
        }
        class MyWebHttpBehavior : WebHttpBehavior
        {
          protected override QueryStringConverter GetQueryStringConverter(OperationDescription operationDescription)
          {
            if (operationDescription.Name == "GetPersonWithMyQSC")
            {
              return new MyQueryStringConverter();
            }
            else
            {
              return new JsonQueryStringConverter();
            }
          }
        }
        public static void Test()
        {
          string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
          ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
          ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(ITest), new WebHttpBinding(), "");
          MyWebHttpBehavior behavior = new MyWebHttpBehavior();
          endpoint.Behaviors.Add(behavior);
          host.Open();
    
          Console.WriteLine("Host opened");
    
          Util.SendRequest(baseAddress + "/GetPersonWithMyQSC?p=John%20Doe---23", "GET", null, null);
          Util.SendRequest(baseAddress + "/GetPersonWithJsonQSC?p=%7B%22Name%22%3A%22John%20Doe%22%2C%22Age%22%3A23%7D", "GET", null, null);
    
          Console.WriteLine("Press ENTER to close");
          Console.ReadLine();
          host.Close();
        }
      }
      public static class Util
      {
        public static string SendRequest(string uri, string method, string contentType, string body)
        {
          return SendRequest(uri, method, contentType, body, null);
        }
        public static string SendRequest(string uri, string method, string contentType, string body, Dictionary<string, string> headers)
        {
          string responseBody = null;
    
          HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(uri);
          req.Method = method;
          if (headers != null)
          {
            foreach (string headerName in headers.Keys)
            {
              req.Headers[headerName] = headers[headerName];
            }
          }
          if (!String.IsNullOrEmpty(contentType))
          {
            req.ContentType = contentType;
          }
    
          if (body != null)
          {
            byte[] bodyBytes = Encoding.UTF8.GetBytes(body);
            req.GetRequestStream().Write(bodyBytes, 0, bodyBytes.Length);
            req.GetRequestStream().Close();
          }
    
          HttpWebResponse resp;
          try
          {
            resp = (HttpWebResponse)req.GetResponse();
          }
          catch (WebException e)
          {
            resp = (HttpWebResponse)e.Response;
          }
    
          if (resp == null)
          {
            responseBody = null;
            Console.WriteLine("Response is null");
          }
          else
          {
            Console.WriteLine("HTTP/{0} {1} {2}", resp.ProtocolVersion, (int)resp.StatusCode, resp.StatusDescription);
            foreach (string headerName in resp.Headers.AllKeys)
            {
              Console.WriteLine("{0}: {1}", headerName, resp.Headers[headerName]);
            }
            Console.WriteLine();
            Stream respStream = resp.GetResponseStream();
            if (respStream != null)
            {
              responseBody = new StreamReader(respStream).ReadToEnd();
              Console.WriteLine(responseBody);
            }
            else
            {
              Console.WriteLine("HttpWebResponse.GetResponseStream returned null");
            }
          }
    
          Console.WriteLine();
          Console.WriteLine(" *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* ");
          Console.WriteLine();
    
          return responseBody;
        }
      }
    
    
    Wednesday, November 10, 2010 5:56 PM