LuxuryWaffles
LuxuryWaffles

Reputation: 1708

WCF POST Params not returning in JSON format

I am developing an android application and am trying to send data through a webservice. For some reason my WCF is not sending data in JSON format, I have set bindings to webHttpBinding, ResponseFormat = WebMessageFormat.Json

Here is my Code for IService:

    [OperationContract]
    [WebInvoke(
        Method = "POST",
        UriTemplate = "LoginMobile",
        BodyStyle = WebMessageBodyStyle.WrappedRequest,
        ResponseFormat = WebMessageFormat.Json,
        RequestFormat = WebMessageFormat.Json)]
    LoginCredentials GetLogin(LoginCredentials Lc);

[DataContract]
public class LoginCredentials
{
    [DataMember(Name = "AccountID")]
    public string AccountID
    {
        get;
        set;
    }
    [DataMember(Name = "NRIC")]
    public string NRIC
    {
        get;
        set;
    }
    [DataMember(Name = "Password")]
    public string Password
    {
        get;
        set;
    }
}

And my Service:

    public LoginCredentials GetLogin(LoginCredentials credentials)
    {
        string strConnectionString = ConfigurationManager.ConnectionStrings["PCSDB"].ConnectionString;
        string strCommandText = "Select AccountID from Account Where NRIC=@NRIC AND Password=@Password";

        using (SqlConnection sqlConnection = new SqlConnection(strConnectionString))
        {
            sqlConnection.Open();

            using (SqlCommand sqlCommand = new SqlCommand(strCommandText, sqlConnection))
            {
                sqlCommand.Parameters.AddWithValue("@NRIC", credentials.NRIC);
                sqlCommand.Parameters.AddWithValue("@Password", credentials.Password);

                int queryResult = sqlCommand.ExecuteNonQuery();
                SqlDataReader reader = sqlCommand.ExecuteReader();

                if (reader.Read())
                {
                    credentials.AccountID = reader["AccountID"].ToString();
                    return credentials;
                }
                else
                {
                    credentials.AccountID = "0";
                    return credentials;
                }
            }
        }
    }

Please help me! Have been on this the whole day!

Upvotes: 0

Views: 294

Answers (2)

I4V
I4V

Reputation: 35353

I tested your code. Your method defintion is correct and returns json as expected.

As far as I can see, the only way for your method to return an XML is if your method throws an exception. (you can test it by adding return credentials as the first line to your method)

You can override this behaviour(returning an xml when an exception is thrown) by writing a custom error handler as below.

Just add [JsonErrorHandlerBehavior] to your class after [ServiceContract] attribute

public class JsonErrorHandlerBehaviorAttribute : Attribute, IErrorHandler, IServiceBehavior
{
    public bool HandleError(Exception error)
    {
        //Log the error
        return true;
    }

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
    {
        var fd = new JsonFaultDetail();
        fd.Message = error.Message;

        fault = Message.CreateMessage(version, string.Empty, fd, new DataContractJsonSerializer(fd.GetType()));

        var jsonFormatting = new WebBodyFormatMessageProperty(WebContentFormat.Json);
        fault.Properties.Add(WebBodyFormatMessageProperty.Name, jsonFormatting);

        var httpResponse = new HttpResponseMessageProperty()
        {
            StatusCode = HttpStatusCode.InternalServerError,
        };

        fault.Properties.Add(HttpResponseMessageProperty.Name, httpResponse);
    }

    public void AddBindingParameters(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
    {
        return;
    }

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
        foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers)
        {
            if (dispatcher.BindingName.Contains("WebHttpBinding"))
                dispatcher.ErrorHandlers.Add(this);
        }
    }

    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
    }
}

BTW, the json string you post to service should be like

{"Lc":{"AccountID":null,"NRIC":"nric1","Password":"password1"}} as defined in interface,

not {"LoginCredentials":{"AccountID":null,"NRIC":"nric1","Password":"password1"}}

Otherwise this would result in credentials parameter being null and credentials.NRIC would throw an exception

Upvotes: 1

Philo
Philo

Reputation: 1989

When I worked with JSon, I used something like this on my WebMethod.

//references. //
    using System;
    using System.IO;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.Services;
    using System.Web.Script.Services;
    using System.Data.SqlClient;
    using System.Web.Security;
    using Newtonsoft.Json;

// returning. //
    return JsonConvert.SerializeObject(credentials);

and on my client side I used:-

// client side reference. //
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.0.min.js"></script>

// storing returned data. //
    var jsondata = $.parseJSON(data.d);
    credentials = jsondata.credentials; 

Not sure if this is what you are looking for. Need more explanation.

Upvotes: 0

Related Questions