Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing a class as parameter in RESTful WCF Service

In my RESTful WCF Serice I need to pass a class as a parameter for URITemplate. I was able to pass a string or multiple strings as parameters. But I have a lot of fields are there to pass to WCF Service. So I have created a class and added all the fields as properties and then I want to pass this class as one paramenter to the URITemplate. When I am trying to pass class to the URITemplate I am getting error "Path segment must have type string". Its not accepting class as a parameter. Any idea how to pass class as a parameter. Here is my code (inputData is class)


    [OperationContract]
    [WebGet(UriTemplate = "/InsertData/{param1}")]
    string saveData(inputData param1);
like image 896
Henry Avatar asked Jul 21 '11 21:07

Henry


People also ask

Is it possible to use RESTful services using WCF?

You can use WCF to build RESTful services in . NET. REST (Representational State Transfer) is an architecture paradigm that conforms to the REST architecture principles. The REST architecture is based on the concept of resources: It uses resources to represent the state and functionality of an application.

Which WCF attribute is used to define RESTful services?

WCF has the option to send the response in JSON object. This can be configured with the WebGet or WebInvoke attribute and the WebHttpBinding. This allows you to expose a ServiceContract as a REST service that can be invoked using either JSON or plain XML.


1 Answers

You actually can pass a complex type (class) in a GET request, but you need to "teach" WCF how to use it, via a QueryStringConverter. However, you usually shouldn't do that, especially in a method which will change something in the service (GET should be for read-only operations).

The code below shows both passing a complex type in a GET (with a custom QueryStringConverter) and POST (the way it's supposed to be done).

public class StackOverflow_6783264
{
    public class InputData
    {
        public string FirstName;
        public string LastName;
    }
    [ServiceContract]
    public interface ITest
    {
        [OperationContract]
        [WebGet(UriTemplate = "/InsertData?param1={param1}")]
        string saveDataGet(InputData param1);
        [OperationContract]
        [WebInvoke(UriTemplate = "/InsertData")]
        string saveDataPost(InputData param1);
    }
    public class Service : ITest
    {
        public string saveDataGet(InputData param1)
        {
            return "Via GET: " + param1.FirstName + " " + param1.LastName;
        }
        public string saveDataPost(InputData param1)
        {
            return "Via POST: " + param1.FirstName + " " + param1.LastName;
        }
    }
    public class MyQueryStringConverter : QueryStringConverter
    {
        public override bool CanConvert(Type type)
        {
            return (type == typeof(InputData)) || base.CanConvert(type);
        }
        public override object ConvertStringToValue(string parameter, Type parameterType)
        {
            if (parameterType == typeof(InputData))
            {
                string[] parts = parameter.Split(',');
                return new InputData { FirstName = parts[0], LastName = parts[1] };
            }
            else
            {
                return base.ConvertStringToValue(parameter, parameterType);
            }
        }
    }
    public class MyWebHttpBehavior : WebHttpBehavior
    {
        protected override QueryStringConverter GetQueryStringConverter(OperationDescription operationDescription)
        {
            return new MyQueryStringConverter();
        }
    }
    public static void Test()
    {
        string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
        ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
        host.AddServiceEndpoint(typeof(ITest), new WebHttpBinding(), "").Behaviors.Add(new MyWebHttpBehavior());
        host.Open();
        Console.WriteLine("Host opened");

        WebClient client = new WebClient();
        Console.WriteLine(client.DownloadString(baseAddress + "/InsertData?param1=John,Doe"));

        client = new WebClient();
        client.Headers[HttpRequestHeader.ContentType] = "application/json";
        Console.WriteLine(client.UploadString(baseAddress + "/InsertData", "{\"FirstName\":\"John\",\"LastName\":\"Doe\"}"));

        Console.Write("Press ENTER to close the host");
        Console.ReadLine();
        host.Close();
    }
}
like image 155
carlosfigueira Avatar answered Sep 20 '22 13:09

carlosfigueira