Amazon Ad

Saturday 20 October 2012

REST Services With Phonegap Android

Hi Guys,

Hope you are doing fine. Today I am going to share how to work with WCF(REST Services) made in asp.net and connecting it with phonegap android app.

Here goes the step wise description

Step 1 :Create a WCF Webservice in asp.net name it Plumber.

Create a WCF webservice in a new asp.net web application. By default the service name is Service1.svc. Two files are created one is the interface and second is the implementation file.

In the interface i.e IService1.svc add the following lines


[OperationContract]
        [WebInvoke(BodyStyle = WebMessageBodyStyle.Wrapped, Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "SearchWorkBook")]
        List<PlumberWork> SearchWorkBook(string PlumberId, string HouseNo,string PostCode,string BoilerCode);

In Service1.svc add the following method


public List<PlumberWork> SearchWorkBook(string PlumberId, string HouseNo,string PostCode,string BoilerCode)
        {
            if (con.State == System.Data.ConnectionState.Closed)
                con.Open();

            List<PlumberWork> list = new List<PlumberWork>();
            string query = "[pSearchWorkBook]";
            SqlCommand cmd = new SqlCommand(query, con);
            cmd.Parameters.AddWithValue("@PlumberId", PlumberId);
            cmd.Parameters.AddWithValue("@HouseNo", HouseNo);
            cmd.Parameters.AddWithValue("@PostCode", PostCode);
            cmd.Parameters.AddWithValue("@BoilerCode", BoilerCode);

            cmd.CommandType = CommandType.StoredProcedure;
            SqlDataAdapter adapt = new SqlDataAdapter(cmd);

            DataSet ds = new DataSet();
            adapt.Fill(ds);
            for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
            {
                PlumberWork obj = new PlumberWork();
                obj.SerialNo = ds.Tables[0].Rows[i]["SerialNo"].ToString();
                obj.PostCode = ds.Tables[0].Rows[i]["PostCode"].ToString();
                obj.Notes = ds.Tables[0].Rows[i]["Notes"].ToString();
                obj.EntryDate = ds.Tables[0].Rows[i]["EntryDate"].ToString();
                list.Add(obj);
            }
            return list;
        }
   
After the class ends add another class


 public class PlumberWork
    {
        public string SerialNo{get;set;}
        public string PostCode{get;set;}
        public string Notes{get;set;}
        public string EntryDate { get; set; }
    }




Step 2: Configure the web.config.


    <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
    </system.webServer>

    <system.serviceModel>
        <services>
            <service name="Plumber.Service1" behaviorConfiguration="ATServiceBehavior">
                <endpoint address="" binding="webHttpBinding" contract="Plumber.IService1" behaviorConfiguration="web" bindingConfiguration="RestServiceBindingConfig">
                </endpoint>
            </service>
        </services>
        <bindings>
            <webHttpBinding>
                <binding crossDomainScriptAccessEnabled="true" name="RestServiceBindingConfig">
                    <security mode="None"></security>
                </binding>
            </webHttpBinding>
        </bindings>
        <behaviors>
            <serviceBehaviors>
                <behavior name="ATServiceBehavior">
                    <serviceMetadata httpGetEnabled="true"/>
                    <serviceDebug includeExceptionDetailInFaults="true" />
                </behavior>
            </serviceBehaviors>
            <endpointBehaviors>
                <behavior name="web">
                    <webHttp defaultOutgoingResponseFormat="Json" helpEnabled="true"/>
                </behavior>
            </endpointBehaviors>
        </behaviors>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
    </system.serviceModel>


Step 3: Create global.asax file for cross domain ajax configuration.

Add the following in your Application_BeginRequest


protected void Application_BeginRequest(object sender, EventArgs e)
        {
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
            if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
            {
                HttpContext.Current.Response.AddHeader("Cache-Control", "no-cache");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
             
                //For GET
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
                //For POST
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept, x-requested-with");

                HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
                HttpContext.Current.Response.End();
            }

       
        }


Step 4: Publish it on IIS.
Step 5: Create a phonegap application.
Step 6: Call WCF service using jquery ajax.


 function searchwork()
        {
            var servicepath = "http://IP_Address_Of_Computer_Hosting(IIS)/PlumberService/";
            var PlumberId="13";
            var HouseNo = "EA 3772";
            var PostCode = "L1A89A";
            var BoilerCode = "B9022A33A";

            alert('{"PlumberId":"' + PlumberId + '","HouseNo":"' + HouseNo + '","PostCode":"' + PostCode + '","BoilerCode":"'+BoilerCode+'"}');
            $.ajax({
                data: '{"PlumberId":"' + PlumberId + '","HouseNo":"' + HouseNo + '","PostCode":"' + PostCode + '","BoilerCode":"' + BoilerCode + '"}',
                type: "POST",
                dataType: "json",
                contentType: "application/json;charset=utf-8",
                url: servicepath + "PlumberService.svc/SearchWorkBook",
                success: function (data) {
                    for (i = 0; i < data.SearchWorkBookResult.length; i++) {
                        document.write("<br>");
                        document.write(data.SearchWorkBookResult[i].SerialNo);
                        document.write(data.SearchWorkBookResult[i].make);
                        document.write(data.SearchWorkBookResult[i].model);
                        document.write(data.SearchWorkBookResult[i].installationdate);
                        document.write(data.SearchWorkBookResult[i].gcnumber);
                        document.write(data.SearchWorkBookResult[i].gascertificateexpirydate);
                        document.write(data.SearchWorkBookResult[i].HouseNo);
                        document.write(data.SearchWorkBookResult[i].PostCode);
                        document.write(data.SearchWorkBookResult[i].Notes);
                        document.write(data.SearchWorkBookResult[i].EntryDate);
                    }
                },
                error: function (a, e, d) { alert(e + ' ' + d); }
            });
        }


Hope you enjoyed, Please do give your comments.

Thanks
Ritesh Tandon

23 comments:

Manoj kumar said...

There is error when i run the wcf service in explorer i.e:web page cannot be found.
Another thing : What is the -SearchWorkBookResult

Ritesh said...

SearchWorkBookResult is the default type returned by the webservice for the data to be returned. If you webmethod name is SearchWorkBook then in jquery the data returned would be SearchWorkBookResult i.e methodname+"Result" and you can retrieve it using data.methodname+"Result".

Unknown said...

its run in browser accuratelly but not working in android device

Ritesh said...

What error you are getting? can you please elaborate

Unknown said...

I tried ur example. but getting error:

405 (Method Not Allowed)
Origin null is not allowed by Access-Control-Allow-Origin.
Please Help

Ritesh said...

Hi Jomin,

The error you have specified here means, That you have not included the correct global.asax file. Please check the global.asax file code in this blog. The 405 method is actually due to the cross domain ajax policy. I have added this code in jquery ($.support.cors = true) and server side code in global.asax. Hope this would solve your problem otherwise send me the code so that i can check what exactly is the problem.

Thanks
Ritesh

Unknown said...

"The name 'con' does not exist in the current"
Maybe i'm missing something but the variable "con" is never declared. I'm assuming this is a connection... please elaborate.

Ritesh said...

Hi Tervor,

Yes, you are right 'con' is actually object of SqlConnection class. I have added the line declaring con in this blog. You need to provide your connectionstring here.

Unknown said...

I tried ur example. but getting error:

Error NOT FOUND

Ritesh said...

Hi Mai Mohamed,

The "Error NOT FOUND" comes when the web service path is not correct or the interface doesn't have the operation contract definition. Please check the path of the web service and the interface having operation contract definition. In case of any problem please feel to revert back on the same.

Thanks
Ritesh

Unknown said...

thanks to your advice we are almost there :)

Unknown said...

i have simple weservices that get id from query string and display it !!
public string JSONData(string id)
{
return "You requested product " + id;
}
when i try your code after modification
first i didn't get the value of id , i got "error"
function test()
{
var servicepath = "http://localhost:35798/RestServiceImpl";
var id="13";

alert('{id}');

$.support.cors = true;

$.ajax({
data: '{"id"}',
type: "POST",
dataType: "json",
contentType: "application/json;charset=utf-8",
url: servicepath + "RestServiceImpl.svc/json",
success: function (data) {
document.write("
");
document.write(data.id);
},
error: function (a, e, d) { alert(e + ' ' + d); }
});
}

Ritesh said...

Hi Asmaa Matar,

What i think that there is a problem with the path of the service. I think instead of

var servicepath = "http://localhost:35798/RestServiceImpl";

you should use

var servicepath = "http://localhost:35798/RestServiceImpl/";

i.e there is a forward slash at the end and the jquery ajax code should be

$.ajax({
data: '{"id":"'+id+'"}',
type: "POST",
dataType: "json",
contentType: "application/json;charset=utf-8",
url: servicepath + "RestServiceImpl.svc/JSONData",
success: function (data) {
document.write(data.JSONDataResult);
},
error: function (a, e, d) { alert(a.responseText+' '+e + ' ' + d); }
});

Try the above code and make sure your operation contract is also in the interface to be implemented.

Hope this helps!!

Thanks
Ritesh

Ritesh said...

Glad it helped

Mark & Amy Priestner said...

Hello,

This tutorial is exactly what I am trying to achieve. I have no trouble with GET requests, only POST. I have re-written my WebService following this but still end up with the same errors. My Ajax POST always fails and returns a html error text where the content states "...The exception message is 'The incoming message has an unexpected message format 'RAW'.......This can be because a WebContentTypeMapper has not been configured on the binding."

Would you have you come across this before? Not sure what else to try.

Thanks,
Mark

Ritesh said...

Hi Mark,

From your error description looks like that you have not specified the Response Format as json, If your response format is json in the operation contract attribute, you should not face this, But still if you have any problem please post the service code and the error you are getting. This would help me to resolve the problem.

Thanks
Ritesh

Mark & Amy Priestner said...

Thanks Ritesh,

I found the problem. The data I was posting wasn't formatted correctly. It's always something simple.

Mark

Ritesh said...

Hi Mark,

Glad it worked, You are right there is always something simple :-).

Thanks
Ritesh

PolatAydin said...

u use port 80 to host your webservice?

Ritesh said...

Yes i use port 80 to host my web service.

Ritesh said...

Yes i use port 80 to host my web service.

Unknown said...

Im getting undefined error while accessing this function $.ajax({})....

Ritesh said...

Can you please post the complete error description.

Post a Comment

Comments are welcome, Please join me on my Linked In account

http://in.linkedin.com/pub/ritesh-tandon/21/644/33b

How to implement Captcha v3 in ASP.NET

 I was facing an issue of dom parsing in my website. I finally resolved it by using Google Captcha V3. Step 1: Get your keys from https:...