Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WCF REST Service: Method parameter (object) is null

why is the parameter of my WCF Rest service method always null?....I do access the service's method and i do get the string returned by the wcf method, but the parameter remains null.

Operation Contract:

  [OperationContract]
    [WebInvoke(UriTemplate = "AddNewLocation",
        Method="POST",
        BodyStyle = WebMessageBodyStyle.WrappedRequest,
        ResponseFormat = WebMessageFormat.Json,
        RequestFormat = WebMessageFormat.Json)]
    string AddNewLocation(NearByAttractions newLocation);

Implementation of AddNewLocation method

 public string AddNewLocation(NearByAttractions newLocation)
    {
        if (newLocation == null)
        {
            //I'm always getting this text in my logfile
            Log.Write("In add new location:- Is Null");
        }
        else
        {
            Log.Write("In add new location:- " );
        }

        //String is returned even though parameter is null
        return "59";
    }

Client code:

        WebClient clientNewLocation = new WebClient();
        clientNewLocation.Headers[HttpRequestHeader.ContentType] = "application/json";

        JavaScriptSerializer js = new JavaScriptSerializer();
        js.MaxJsonLength = Int32.MaxValue;

        //Serialising location object to JSON
        string serialLocation = js.Serialize(newLocation);

        //uploading JSOn string and retrieve location's ID
        string jsonLocationID = clientNewLocation.UploadString(GetURL() + "AddNewLocation", serialLocation);

I also tried this code in my client but still get a null parameter

            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(NearByAttractions));

        MemoryStream ms = new MemoryStream();
        ser.WriteObject(ms, newLocation);

        String json = Encoding.UTF8.GetString(ms.ToArray());


        WebClient clientNewLocation = new WebClient();
        clientNewLocation.Headers[HttpRequestHeader.ContentType] = "application/json";

        string r = clientNewLocation.UploadString(GetURL() + "AddNewLocation", json);

        Console.Write(r);

Then i also changed the BodyStyle option to "Bare" but then I got the following error (with both client codes):

The remote server returned an error: (400) Bad Request.

Any help please? thanks

Edit 1: My GetUrl() method loads the web service IP address from the web config file and returns an object of type Uri

private static Uri GetURL()
    {
        Configuration config = WebConfigurationManager.OpenWebConfiguration("~/web.config");

        string sURL = config.AppSettings.Settings["serviceURL"].Value;
        Uri url = null;

        try
        {
            url = new Uri(sURL);
        }
        catch (UriFormatException ufe)
        {
            Log.Write(ufe.Message);
        }
        catch (ArgumentNullException ane)
        {
            Log.Write(ane.Message);
        }
        catch (Exception ex)
        {
            Log.Write(ex.Message);
        }

        return url;
    }

service address stored in web config as follows:

<appSettings>
    <add key="serviceURL" value="http://192.168.2.123:55666/TTWebService.svc/"/>
  </appSettings>

This is how my NearByAttraction class defined

 [DataContractAttribute]
public class NearByAttractions
{


    [DataMemberAttribute(Name = "ID")]
    private int _ID;
    public int ID
    {
        get { return _ID; }
        set { _ID = value; }
    }



    [DataMemberAttribute(Name = "Latitude")]
    private string _Latitude;
    public string Latitude
    {
        get { return _Latitude; }
        set { _Latitude = value; }
    }


     [DataMemberAttribute(Name = "Longitude")]
    private string _Longitude;
    public string Longitude
    {
        get { return _Longitude; }
        set { _Longitude = value; }
    }
like image 753
drew Avatar asked Aug 03 '26 23:08

drew


1 Answers

You seem to be in the right track. You need the Bare body style, otherwise you'd need to wrap the serialized version of your input in another JSON object. The second code should work - but without more information about how the service is set up and what GetURL() returns we can only guess.

One way to find out what to send to a WCF REST service is to use a WCF client itself for that - using the WebChannelFactory<T> class, then use a tool such as Fiddler to see what it's sending. The example below is a SSCCE which shows your scenario working.

public class StackOverflow_15786448
{
    [ServiceContract]
    public interface ITest
    {
        [OperationContract]
        [WebInvoke(UriTemplate = "AddNewLocation",
            Method = "POST",
            BodyStyle = WebMessageBodyStyle.Bare,
            ResponseFormat = WebMessageFormat.Json,
            RequestFormat = WebMessageFormat.Json)]
        string AddNewLocation(NearByAttractions newLocation);
    }
    public class NearByAttractions
    {
        public double Lat { get; set; }
        public double Lng { get; set; }
        public string Name { get; set; }
    }
    public class Service : ITest
    {
        public string AddNewLocation(NearByAttractions newLocation)
        {
            if (newLocation == null)
            {
                //I'm always getting this text in my logfile
                Console.WriteLine("In add new location:- Is Null");
            }
            else
            {
                Console.WriteLine("In add new location:- ");
            }

            //String is returned even though parameter is null
            return "59";
        }
    }
    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");

        Console.WriteLine("Using WCF-based client (WebChannelFactory)");
        var factory = new WebChannelFactory<ITest>(new Uri(baseAddress));
        var proxy = factory.CreateChannel();
        var newLocation = new NearByAttractions { Lat = 12, Lng = -34, Name = "56" };
        Console.WriteLine(proxy.AddNewLocation(newLocation));

        Console.WriteLine();
        Console.WriteLine("Now with WebClient");

        DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(NearByAttractions));
        MemoryStream ms = new MemoryStream();
        ser.WriteObject(ms, newLocation);

        String json = Encoding.UTF8.GetString(ms.ToArray());

        WebClient clientNewLocation = new WebClient();
        clientNewLocation.Headers[HttpRequestHeader.ContentType] = "application/json";

        string r = clientNewLocation.UploadString(baseAddress + "/AddNewLocation", json);

        Console.WriteLine(r);
    }
}
like image 122
carlosfigueira Avatar answered Aug 05 '26 15:08

carlosfigueira