RSS

Monthly Archives: January 2012

How to Android as a RESTful Client

This is a how-to focused on creating a RESTful java object at Android. I’ve used HTTPClient, HTTPEntry, HTTPGet, HTTPResponse, JSONArray and JSONObject classes. I think it’ll be useful if we need to use a web-service from client application.

 

I’ve implemented a simple Java Object called RestClient which connects to a given Rest-JSON service. After connection, this object prints response content. Using this content, a JSONObject created. Then, RestClient prints the JSONObject’s content, parses all values of this object and prints them as well. And as a last job, RestClient pushes a sample value to the JSONObject.

I’ve uploaded RestClient. Hope it’ll be useful.

P.s: To get access to internet at Android, following field must be included to AndroidManifest.xml file of the project.

<uses-permission android:name="android.permission.INTERNET"></uses-permission>
package praeda.muzikmekan;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;

public class RestClient {

    private static String convertStreamToString(InputStream is) {
        /*
         * To convert the InputStream to String we use the BufferedReader.readLine()
         * method. We iterate until the BufferedReader return null which means
         * there's no more data to read. Each line will appended to a StringBuilder
         * and returned as String.
         */
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder sb = new StringBuilder();

        String line = null;
        try {
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }

    /* This is a test function which will connects to a given
     * rest service and prints it's response to Android Log with
     * labels "Praeda".
     */
    public static void connect(String url)
    {

        HttpClient httpclient = new DefaultHttpClient();

        // Prepare a request object
        HttpGet httpget = new HttpGet(url); 

        // Execute the request
        HttpResponse response;
        try {
            response = httpclient.execute(httpget);
            // Examine the response status
            Log.i("Praeda",response.getStatusLine().toString());

            // Get hold of the response entity
            HttpEntity entity = response.getEntity();
            // If the response does not enclose an entity, there is no need
            // to worry about connection release

            if (entity != null) {

                // A Simple JSON Response Read
                InputStream instream = entity.getContent();
                String result= convertStreamToString(instream);
                Log.i("Praeda",result);

                // A Simple JSONObject Creation
                JSONObject json=new JSONObject(result);
                Log.i("Praeda","<jsonobject>\n"+json.toString()+"\n</jsonobject>");

                // A Simple JSONObject Parsing
                JSONArray nameArray=json.names();
                JSONArray valArray=json.toJSONArray(nameArray);
                for(int i=0;i<valArray.length();i++)
                {
                    Log.i("Praeda","<jsonname"+i+">\n"+nameArray.getString(i)+"\n</jsonname"+i+">\n"
                            +"<jsonvalue"+i+">\n"+valArray.getString(i)+"\n</jsonvalue"+i+">");
                }

                // A Simple JSONObject Value Pushing
                json.put("sample key", "sample value");
                Log.i("Praeda","<jsonobject>\n"+json.toString()+"\n</jsonobject>");

                // Closing the input stream will trigger connection release
                instream.close();
            }

        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}
Advertisements
 
Leave a comment

Posted by on January 31, 2012 in Android

 

How to remove index.php in Codeigniter URL

By default, the index.php file will be included in your URLs:

example.com/index.php/news/article/my_article

You can easily remove this file by using a .htaccess file with some simple rules. Here is an example of such a file, using the “negative” method in which everything is redirected except the specified items:


<code>RewriteEngine on
RewriteCond $1 !^(index\.php|images|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]</code>

In the above example, any HTTP request other than those for index.php, images, and robots.txt is treated as a request for your index.php file.

 
Leave a comment

Posted by on January 25, 2012 in CodeIgniter

 

Linq to SQL with WCF Services

I was interested to see how I could use Linq to SQL with WCF Services to load and save data using a Silverlight project.  In this post I will expand upon the database I created in my Linq to SQL Tutorial and the console application I wrote for my Set inheritance modifiers with SQLMetal post.

The first step is to enable serialisation on my Linq entities so that they can be sent over the wire. To do this in the O/R Designer you can select the white space of the designer and view the DataContext properties.  Set the property called Serialization Mode to Unidirectional:

Linq Serialization Mode Property

 

If using SQLMetal you can use the serialization command line argument:

1
SQLMetal.exe"/server:localhost /database:University /dbml:University.dbml <strong>/serialization:unidirectional</strong> /namespace:Entities /context:UniversityDataContext /pluralize

Enabling unidirectional serialization in either of these two ways adds the necessaryDataContract and DataMember attributes to the generated entities and properties:

1
2
3
4
5
6
7
8
9
10
11
12
13
[Table(Name="dbo.Student")]
[DataContract()]
public partial class Student : EntityBase, INotifyPropertyChanging, INotifyPropertyChanged
{
    ....
    [Column(Storage="_Forename", DbType="NVarChar(50) NOT NULL", CanBeNull=false, UpdateCheck=UpdateCheck.Never)]
    [DataMember(Order=3)]
    public string Forename
    {
        ....
    }
}

The entities are now in a state where they can be serialised and sent down the wire.  In my WCF service I have a method that returns a list of my Linq to SQL Student entity:

1
2
3
4
5
6
7
public List GetStudents()
{
    using (_context)
    {
        return _context.Students.ToList();
    }
}

These entities can then be easily used by the client, in this case the Silverlight application:

1
2
3
4
5
6
7
8
9
10
11
12
UniversityContractClient _proxy = new UniversityContractClient();
private void PopulateStudents()
{
    _proxy.GetStudentsCompleted += new EventHandler(proxy_GetStudentsCompleted);
    _proxy.GetStudentsAsync();
}
void proxy_GetStudentsCompleted(object sender, GetStudentsCompletedEventArgs e)
{
    dgStudents.ItemsSource = e.Result;
}

Here I am using the list to populate a DataGrid:

Linq WCF Datagrid

This is all very straight forward, but the next step to update the data it a little more complex.  Here is my service method to save a Student entity created or updated by the client:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public void SaveStudent(Student student)
{
    using (_context)
    {
        if (student.IsNew)
        {
            _context.Students.InsertOnSubmit(student);
        }
        else
        {
            _context.Students.Attach(student, true);
        }
              
        _context.SubmitChanges();
    }
}

Here I am using the IsNew property I created in my Set inheritance modifiers with SQLMetalpost to check if the entity is to be inserted or updated.  The insert code is simple enough, but for the update we have to attach the entity to the DataContext as it has been modified outside of the DataContext’s scope.  I’m at doing this using the Attach method of the Student table, passing true for the asModified parameter to state that the entity has been updated.

In my Silverlight application I have a DataForm which calls this method passing the updated Student entity:

Linq WCF DataForm

At this point inserting data will work, but when I try to update an entity the service method will throw the following error when trying to attach the entity:

An entity can only be attached as modified without original state if it declares a version member or does not have an update check policy.

This occurs because the entity was modified outside of the scope of the DataContext, so Linq to SQL doesn’t know what has changed about the entity and what to update.  To overcome this we can use a Timestamp column.  The Timestamp is a byte array which is used for versioning.  Linq to SQL knows to check this column to see if an object has been updated.  In my database I have changed the Student table so that it has a field called Timestamp, of type timestamp which doesn’t allow NULLs:

Linq WCF Timestamp Field

When adding the new column, the O/R Designer automatically knows this is a timetamp column and sets the Time Stamp and Auto Generated Value properties to true:

Linq WCF Timestamp Properties

 

SQLMetal will also detect a column with the timestamp type and set the necessary attributes.

With this timestamp column set up it will now be possible to successfully update an entity that was changed by the client.

In my example if I try to update the entity twice it will throw the following exception when trying to submit the changes:

Row not found or changed.

This is because the client doesn’t have the entity with the updated timestamp.  Also when adding a new entity the entity at the client won’t have the updated ID identity column so trying to update this will create another entity.  To resolve this I can change my SaveStudent service method to return the updated Student entity:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public Student SaveStudent(Student student)
{
    using (_context)
    {
        if (student.IsNew)
        {
            _context.Students.InsertOnSubmit(student);
        }
        else
        {
            _context.Students.Attach(student, true);
        }
              
        _context.SubmitChanges();
    }
    return student;
}

In my Silverlight application I then pass the hash code for the object as the userState when calling the asyncronus service method:

1
_proxy.SaveStudentAsync(student, student.GetHashCode());

This user state can then be obtained in the callback EventArgs class using e.UserState.  Using this I get the correct object from my collection, update it and reassign the source for my DataGrid and DataForm:

1
2
3
4
5
6
7
8
9
10
11
12
void _proxy_SaveStudentCompleted(object sender, SaveStudentCompletedEventArgs e)
{
    ObservableCollection students = (ObservableCollection)dgStudents.ItemsSource;
    Student student = students.Where(s => s.GetHashCode() == Convert.ToInt32(e.UserState)).First();
    if (student.ID == 0)
    {
        student.ID = e.Result.ID;
    }
    student.Timestamp = e.Result.Timestamp;
    dgStudents.ItemsSource = students;
    dfStudent.ItemsSource = students;
}

This is all well and good and works as expected but what I really wanted to do was have an UpdateDate column which holds the date of the last update which could be used as a timestamp.  I replaced my current Timestamp column with an UpdateDate column:

Linq WCF UpdateDate Field

The default for the new column is set to getdate() to automatically populate with the current date when creating a new record:

Linq WCF UpdateDate Default

Using the O/R Designer this field can be set to a timestamp by setting the Time Stamp property to True, which will automatically set Auto Generated Value to True.

As I am using SQLMetal I can update the console application I wrote in my Set inheritance modifiers with SQLMetal post to add an IsVersion attribute to the DBML XML as well as the Modifier attribute:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.... code omitted ....
//Find the column node
if (child.Name.Equals("Column"))
{
    if (child.Attributes["Name"].Value.Equals("ID"))
    {
        //Create the Modifier attribute to add to ID column
        XmlAttribute modifierAttribute = xmlDoc.CreateAttribute("Modifier");
        modifierAttribute.Value = "Override";
        child.Attributes.Append(modifierAttribute);
    }
    else if (child.Attributes["Name"].Value.Equals("UpdateDate"))
    {
        //Create the IsVersion attribute to add to UpdateDate column
        XmlAttribute versionAttribute = xmlDoc.CreateAttribute("IsVersion");
        versionAttribute.Value = "True";
        child.Attributes.Append(versionAttribute);
    }
}
.... code omitted ....

Doing this adds the following values to the Column attribute on the UpdateDate property in the Student entity.  You can see IsVersion=true which tells Linq to SQL this property is the timestamp.

1
[Column(Storage="_UpdateDate", AutoSync=AutoSync.Always, DbType="DateTime NOT NULL", IsDbGenerated=true, IsVersion=true, UpdateCheck=UpdateCheck.Never)]

At this point everything works okay, but the UpdateDate is not refreshed on update.  To fix this add a trigger that sets the date on update:

1
2
3
4
5
6
7
ALTER TRIGGER trg_UpdateDate
ON dbo.Student
FOR UPDATE
AS
    UPDATE      Student
    SET         UpdateDate = getdate()
    WHERE       (ID IN (SELECT ID FROM Inserted))

The UpdateDate is now set for each update and is used by Linq to SQL as the timestamp.

Referenced by: http://www.joe-stevens.com/2009/07/10/linq-to-sql-with-wcf-services/

 
Leave a comment

Posted by on January 19, 2012 in C#, LinQ, WCF

 

How to call a WCF service using ksoap2 on android

In “theory” wcf with basic http binding and asmx should work the same.

It could be something to do with how your WCF service is configured.

We get a similar problem if we configure TransferMode Streamed on the client and Buffered on the server. Although not sure if this is relevant in your case.

 
private static final String SOAP_ACTION = "http://tempuri.org/IContact/GetContactCount"; 
private static final String METHOD_NAME = "GetContactCount"; private static final String NAMESPACE = "http://tempuri.org/"; 
private static final String URL = "http://xxx.xxx.com/Contacts/ContactsService.Contacts.svc";
 
import org.ksoap2.*;
import org.ksoap2.serialization.*;
import org.ksoap2.transport.*;
import org.xmlpull.v1.XmlSerializer;

import android.app.Activity;
import android.os.Bundle;
import android.util.Xml;
import android.widget.TextView;

public class ksop2test extends Activity {
/** Called when the activity is first created. */

private static final String METHOD_NAME = "HelloWorldRequest";
//  private static final String METHOD_NAME = "HelloWorld";

private static final String NAMESPACE = "http://tempuri.org/";
//  private static final String NAMESPACE = "http://tempuri.org";

private static final String URL = "http://192.168.0.2:8080/HelloWCF/Service1.svc";
//  private static final String URL = "http://192.168.0.2:8080/webservice1  /Service1.asmx";

final String SOAP_ACTION = "http://tempuri.org/IService1/HelloWorld";
//  final String SOAP_ACTION = "http://tempuri.org/HelloWorld";
TextView tv;
StringBuilder sb;
private XmlSerializer writer;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
tv = new TextView(this);
sb = new StringBuilder();
call();
tv.setText(sb.toString());
setContentView(tv);
}

public void call() {
try {

SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);

request.addProperty("Name", "Qing");

SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);

HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.call(SOAP_ACTION, envelope);
SoapPrimitive result = (SoapPrimitive)envelope.getResponse();

//to get the data
String resultData = result.toString();
// 0 is the first object of data

sb.append(resultData + "\n");
} catch (Exception e) {
sb.append("Error:\n" + e.getMessage() + "\n");
}

}

}

Referenced by: http://stackoverflow.com/questions/2589486/how-to-call-a-wcf-service-using-ksoap2-on-android

 
Leave a comment

Posted by on January 18, 2012 in Android, Mobile Development, WCF

 

Communication Between WCF Service and Android Client

Communication Between WCF Service and Android Client

Overview of REST in WCF
Windows Communication Foundation (WCF), part of the .NET Framework, provides the first unified programming model for rapidly building service-oriented applications. It enables the development of secure, reliable, transacted services that interoperate with current Microsoft investments and non-Microsoft platforms.

With the .NET Framework 3.5 release, WCF added support for building REST style services. REST, an architectural style for building distributed hypermedia driven applications, involves building resource-oriented services by defining resources that implement uniform interfaces using standard HTTP verbs (GET, POST, PUT, and DELETE), and that can be located/identified by a URI.

REST support within WCF was enhanced with the release of .NET Framework 3.5 SP1 to add make REST development easier and to support the ADO.NET Entity Framework entities in WCF contracts. Improvements were made around UriTemplate flexibility and the Visual Studio tooling to increase developer productivity.

Code example

A good tutorial on how to create RESTful Service using Visual Studio can be found here.

First we need to define the structure (class) which will be used for data exchange between server and client. In this case I created a base class named Response and extended classes named ActivityStatusResponse and ConnectionStatusResponse:

    public class Response
    {
        private bool successful;
        private string comment;

        public bool Successful
        {
            get
            {
                return successful;
            }
            set
            {
                successful = value;
            }
        }

        public string Comment
        {
            get
            {
                return comment;
            }
            set
            {
                comment = value;
            }
        }
    }
    public class ActivityStatusResponse : Response
    {
        private string activity;

        public string Activity
        {
            get
            {
                return activity;
            }
            set
            {
                activity = value;
            }
        }
    }

Next we need to define the methods, message formats and URI templates in the interface:

[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = “/{strSessionString}/activityStatus”)]
ActivityStatusResponse GetActivityStatus(string strSessionString);[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json,
UriTemplate = “/{strSessionString}/time={time}&lat={latitude}&long={longitude}”)]
Response StoreLocation(string strSessionString, string time, string latitude, string longitude);

WebMessageFormat parameter defines the data exchange format. In this example JSON format is used.

UriTemplate parameter defines the URI template.

The parameters within curly braces represent variable values. Everything else in the URI (not enclosed within curly braces) is considered a static part of the URI.

After the definition we have to implement the methods. The following code shows the implementation of StoreAcceleration method:

public Response StoreAcceleration(string strSessionString, string strMeasurementTime, string strAccelerationX, string strAccelerationY, string strAccelerationZ)
        {
            SQLWorks sqlWorks = new SQLWorks();
            Response response = new Response();
            try
            {
                string strTime = strMeasurementTime.Replace("_", " ");
                DateTime measurementTime = DateTime.ParseExact(strTime, "yyyy-MM-dd HH:mm:ss:fff", null);
                double accelerationX = Convert.ToDouble(strAccelerationX.Replace(".", ","));
                double accelerationY = Convert.ToDouble(strAccelerationY.Replace(".", ","));
                double accelerationZ = Convert.ToDouble(strAccelerationZ.Replace(".", ","));

                sqlWorks.StoreAcceleration(strSessionString, measurementTime, accelerationX, accelerationY, accelerationZ);

                response.Successful = true;
                response.Comment = "Stored!";
            }
            catch(Exception ex)
            {
                string sDummy = ex.ToString();
                response.Comment = "an error occured!";
                response.Successful = false;
            }

            return response;
        }

The service Endpoint and other properties are defined in .config file:

<configuration>
<system.web>
<compilation debug=”true”>
</compilation>
<system.servicemodel>
<bindings>
<webhttpbinding>
<binding name=”DefaultBinding”>
</binding>
</webhttpbinding>
<behaviors>
<endpointbehaviors>
<behavior name=”RESTFriendly”>
<webhttp>
</webhttp>
<behavior name=”RESTServer.JsonServiceAspNetAjaxBehavior”>
<enablewebscript>
</enablewebscript>
</behavior>
<servicebehaviors>
<behavior name=”RESTFriendly”>
<servicemetadata httpgetenabled=”true”>
<servicedebug includeexceptiondetailinfaults=”false”>
</servicedebug>
</servicemetadata>
</behavior>
<services>
<service name=”RESTServer.GaitLinkService”>
<endpoint address=”” behaviorconfiguration=”RESTFriendly” binding=”webHttpBinding” bindingconfiguration=”DefaultBinding” contract=”RESTServer.IGaitLinkService”>
<identity>
<dns value=”localhost”>
</dns>
</identity>
</endpoint>
</service>
<servicehostingenvironment aspnetcompatibilityenabled=”true”>
</servicehostingenvironment>
</services></servicebehaviors></behavior></endpointbehaviors></behaviors></bindings></system.servicemodel></system.web></configuration>

At this point everything is ready to host the service in the windows application:

public void StartRestService()
        {
            try
            {
                WebHttpBinding binding = new WebHttpBinding();
                RESTServiceHost = new ServiceHost(typeof(GaitLinkService), new Uri("http://localhost:8000/GaitLink"));
                RESTServiceHost.AddServiceEndpoint(typeof(IGaitLinkService), binding, "GaitLink");
                RESTServiceHost.Open();
            }
            catch(Exception ex)
            {
                string sDummy = ex.ToString();
                //TODO: notify user about the error!
            }
        }

Client application

On client side there is a service called CommunicationService and additional class RestClient. Function arguments are sent to the server by generating the url address which has to be the same format as the template specified in the service interface on the server side.

Class RestClient.java:

package com.client.gaitlink;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;

public class RestClient {

	private static String loginParameters;
	private static String accelerationParameters;
	private static String activityRequestParameters;
	private static String locationParameters;
	private static String serviceAddress = "http://76.30.178.213:8000/GaitLink/";

	private static String convertStreamToString(InputStream is) {
		BufferedReader reader = new BufferedReader(new InputStreamReader(is));
		StringBuilder sb = new StringBuilder();

		String line = null;
		try {
			while ((line = reader.readLine()) != null) {
				sb.append(line + "\n");
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return sb.toString();
	}

	public static void connect(String url) {

		HttpClient httpclient = new DefaultHttpClient();

		HttpGet httpget = new HttpGet(url);

		//HttpPost httppost = new HttpPost(url);

		HttpResponse response;
		try {

			response = httpclient.execute(httpget);

			Log.i("REST:Response Status line", response.getStatusLine().toString());

			HttpEntity entity = response.getEntity();

			if (entity != null) {

				InputStream instream = entity.getContent();
				String result = convertStreamToString(instream);
				Log.i("REST: result", result);

				JSONObject json = new JSONObject(result);
				Log.i("REST", "<jsonobject>\n" + json.toString()
						+ "\n</jsonobject>");

				// Parsing
				JSONArray nameArray = json.names();
				JSONArray valArray = json.toJSONArray(nameArray);
				for (int i = 0; i < valArray.length(); i++) {
					Log
							.i("REST", "<jsonname" + i + ">\n"
									+ nameArray.getString(i) + "\n</jsonname"
									+ i + ">\n" + "<jsonvalue" + i + ">\n"
									+ valArray.getString(i) + "\n</jsonvalue"
									+ i + ">");
				}

				json.put("sample key", "sample value");
				Log.i("REST", "<jsonobject>\n" + json.toString()
						+ "\n</jsonobject>");

				instream.close();
			}

		} catch (ClientProtocolException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public class Response
	{
		public boolean isSuccessful() {
			return successful;
		}

		public void setSuccessful(boolean successful) {
			this.successful = successful;
		}

		public String getComment() {
			return comment;
		}

		public void setComment(String comment) {
			this.comment = comment;
		}

		private boolean successful;
		private String comment;

		public Response()
		{
			this(false, null);
		}

		public Response(boolean successful, String comment)
		{
			this.successful = successful;
			this.comment = comment;
		}
	}

	public class LoginResponse extends Response
	{
		private String strSessionString;

		public LoginResponse()
		{
			this(false, null, "LoginFailed");
		}

		public LoginResponse(boolean successful, String strSessionString, String comment)
		{
			super(successful, comment);
			this.strSessionString = strSessionString;
		}

		public String getStrSessionString() {
			return strSessionString;
		}

		public void setStrSessionString(String strSessionString) {
			this.strSessionString = strSessionString;
		}
	}

	public class ActivityStatusResponse extends Response
	{
		private String activity;

		public String getActivity() {
			return activity;
		}

		public void setActivity(String activity) {
			this.activity = activity;
		}

		public ActivityStatusResponse(boolean successfull, String activity, String comment)
		{
			super(successfull, comment);
			this.activity = activity;
		}

		public ActivityStatusResponse()
		{
			this(false, null, "activity request failed");
		}
	}

	private static void SetLoginParameters(String username, String password)
	{
		loginParameters = "Login?username=" + username + "&password=" + password;
	}

	public LoginResponse Login(String username, String password)
	{
		SetLoginParameters(username, password);

		HttpClient httpclient = new DefaultHttpClient();
		HttpGet httpget = new HttpGet(serviceAddress + loginParameters);

		HttpResponse response;

		LoginResponse loginResponse = null;

		try
		{
			response = httpclient.execute(httpget);

			HttpEntity entity = response.getEntity();

			if(entity != null)
			{
				InputStream instream = entity.getContent();
				String result = convertStreamToString(instream);
				JSONObject json = new JSONObject(result);

				// Parsing
				JSONArray nameArray = json.names();
				JSONArray valArray = json.toJSONArray(nameArray);

				loginResponse = new LoginResponse(valArray.getBoolean(1), valArray.getString(0), valArray.getString(2));

				instream.close();
			}

		}
		catch(Exception e)
		{
			loginResponse = new LoginResponse();
			String sDummy = e.toString();
		}
		return loginResponse;
	}

	public Response SendAccelerations(String sSession, String measurementTime, double ax, double ay, double az)
	{
		setAccelerationParameters(sSession, measurementTime, ax, ay, az);

		HttpClient httpclient = new DefaultHttpClient();
		HttpGet httpget = new HttpGet(serviceAddress + accelerationParameters);

		HttpResponse response;

		Response accelerationResponse = null;

		try
		{
			response = httpclient.execute(httpget);

			HttpEntity entity = response.getEntity();

			if(entity != null)
			{
				InputStream instream = entity.getContent();
				String result = convertStreamToString(instream);
				JSONObject json = new JSONObject(result);

				// Parsing
				JSONArray nameArray = json.names();
				JSONArray valArray = json.toJSONArray(nameArray);

				accelerationResponse = new Response(valArray.getBoolean(0), valArray.getString(1));

				instream.close();
			}

		}
		catch(Exception e)
		{
			accelerationResponse = new Response();
			String sDummy = e.toString();
		}
		return accelerationResponse;
	}

	private static void setAccelerationParameters(String sSession, String measurementTime, double ax, double ay, double az)
	{
		accelerationParameters = sSession + "/measurementTime=" + measurementTime + "&accelerationX=" + ax + "&accelerationY=" + ay + "&accelerationZ=" + az;
		accelerationParameters = accelerationParameters.replaceAll(" ", "_");
	}

	public Response SendLocation(String sSession, String locationTime, double latitude, double longitude)
	{
		setLocationParameters(sSession, locationTime, latitude, longitude);

		HttpClient httpclient = new DefaultHttpClient();
		HttpGet httpget = new HttpGet(serviceAddress + locationParameters);

		HttpResponse response;

		Response locationResponse = null;

		try
		{
			response = httpclient.execute(httpget);

			HttpEntity entity = response.getEntity();

			if(entity != null)
			{
				InputStream instream = entity.getContent();
				String result = convertStreamToString(instream);
				JSONObject json = new JSONObject(result);

				// Parsing
				JSONArray nameArray = json.names();
				JSONArray valArray = json.toJSONArray(nameArray);

				locationResponse = new Response(valArray.getBoolean(0), valArray.getString(1));

				instream.close();
			}

		}
		catch(Exception e)
		{
			locationResponse = new Response();
			String sDummy = e.toString();
		}
		return locationResponse;
	}

	private static void setLocationParameters(String sSession, String locationTime, double latitude, double longitude)
	{
		///{strSessionString}/time={time}&lat={latitude}&long={longitude}
		locationParameters = sSession + "/time=" + locationTime + "&lat=" + latitude + "&long=" + longitude;
		locationParameters = locationParameters.replaceAll(" ", "_");
	}

	public ActivityStatusResponse GetActivity(String sSession)
	{
		setActivityRequestParameters(sSession);

		HttpClient httpclient = new DefaultHttpClient();
		HttpGet httpget = new HttpGet(serviceAddress + activityRequestParameters);

		HttpResponse response;

		ActivityStatusResponse activityStatusResponse = null;

		try
		{
			response = httpclient.execute(httpget);

			HttpEntity entity = response.getEntity();

			if(entity != null)
			{
				InputStream instream = entity.getContent();
				String result = convertStreamToString(instream);
				JSONObject json = new JSONObject(result);

				// Parsing
				JSONArray nameArray = json.names();
				JSONArray valArray = json.toJSONArray(nameArray);

				activityStatusResponse = new ActivityStatusResponse(valArray.getBoolean(0), valArray.getString(1), valArray.getString(2));

				instream.close();
			}

		}
		catch(Exception e)
		{
			activityStatusResponse = new ActivityStatusResponse();
			String sDummy = e.toString();
		}
		return activityStatusResponse;
	}

	private static void setActivityRequestParameters(String sSession)
	{
		activityRequestParameters = "/" + sSession + "/activityStatus";
	}
}</pre>
</div>
<div>

RestClient methods are called from CommunicationService class. The following example shows the method which retrieves the activity status:

</div>
<div>
<pre id="bt_plainText">private void requestActivity()
	{
		try
		{
			if(strSessionString != null)
			{
				ActivityStatusResponse response = restClient.GetActivity(strSessionString);
				connectionAvailable = response.isSuccessful();
				strActivity = response.getActivity();
				if(strActivity != null && strActivity != "")
				{
					announceActivityStatus();
				}

			}
		}
		catch(Exception e)
		{
			connectionAvailable = false;
		}
	}
The example above is just a brief overview of practical RESTful service realization using WCF and data exchange with Android client. More detailed explanations of each segment could be found at the given addresses.
References

A Guide to Designing and Building RESTful Web Services with WCF 3.5
Windows Communication Foundation Architecture
What Is Windows Communication Foundation?
 
3 Comments

Posted by on January 18, 2012 in Android, Mobile Development, WCF

 

Getting Started Building a WCF Web Service

This post is the first in a series of upcoming MSDN articles on creating a claims-aware web service and consuming it from SharePoint BCS.  In the short time that I’ve worked with claims-based authentication, what I experience is that while there are not very many steps to get it working, if you get anything wrong, then it just doesn’t work, and it takes some effort to figure out the problem.  My approach in these articles is to supply some procedures with small steps, with instructions all along the way to validate that what you have done so far works properly.  So the first step is to create a WCF web service, host it using IIS, and validate that it is working.

Getting Started Building a WCF Web Service
(This post)
Shows how to create a very simple web service using WCF.  Shows how to host this web service using IIS.
Determining Caller Identity within a WCF Web Service Enhances the example so that the Web service can authoritatively report on the identity of its caller.
Establishing Trust between a WCF Web Service and the SharePoint 2010 Security Token Service Configures the example developed in the previous article so that it uses a self-signed certificate to support a secure connection.
Consuming a Claims-Enabled WCF Web Service as an SharePoint 2010 External Content Type Walks through the procedure for consuming a claims-enabled web service as a SharePoint 2010 External Content Type.

These articles were written by Saji Varkey, and Bin Zhang, and me.  They will be published on MSDN sometime in the near future.  After they are published, I will update these posts to point to the MSDN articles.  Juan Balmori Labra was the program manager behind these articles.

This post shows how to create a very simple web service using Windows Communications Foundation (WCF).  There is one special characteristic of the web service that I present in this article, which is that while it is very simple, it can be consumed as an External Content Type (ECT) from Business Connectivity Services (BCS).  In addition, the procedure presented in this post shows how to host this web service using Internet Information Services (IIS).

This web service contains only two methods: a ‘finder’ to retrieve a collection of items, and a ‘specific finder’ to retrieve a single item.  The ‘database’ behind the collection is just an initialized list.  The ‘schema’ of this little ‘database’ is very simple.  It is a single flat table consisting of two fields – an integer CustomerID, and a stringCustomerName.  CustomerID is a unique ID.

return new List<Customer>()
{
new Customer
{
CustomerID = 1,
CustomerName = “Bob”,
},
new Customer
{
CustomerID = 2,
CustomerName = “Bill”,
},
new Customer
{
CustomerID = 3,
CustomerName = “Cheryl”,
},
};

After building and configuring this web service, you can use SharePoint Designer 2010 to create an ECT from it, and then view the data in a SharePoint list.

 

As you probably know, BCS in SharePoint server 2010 is read/write.  If you supply additional methods to create, update, and delete items, then you can fully maintain the data in a list.  I’m interested in keeping this web service absolutely as simple as possible, so this is only a read-only implementation.  My focus will be completely on the security and identity issues.  How the database is stored, where it is stored, or the details of the schema are irrelevant to the topic at hand.

The procedure presented here is for Windows Server 2008 R2 and Windows Server 2008.  You can build this web service using either Visual Studio 2010 or Visual Studio 2008.

You can build, run, and test the web service presented in this post on any development computer that is running IIS.  However, if you want to connect to this web service as an ECT using BCS, then build this example on a SharePoint 2010 development machine, so that the SharePoint 2010 server and the example web service are running on the same computer.  You can put this web service on a different machine, and consume it as an ECT, however, in that situation, you must either remove security, or you need to create a claims-aware web service.

As I mentioned, the procedure that I present here shows how to host the web service under IIS.  This is the way that most implementers of such a web service will want to host it.  Hosting it as a service of IIS gives lots of benefits such as process recycling, process health monitoring, and message based activation.

Building the Example

This procedure is for Windows Server 2008 or Windows Server 2008 R2.  In both cases, I started on a machine that had a fresh, patched install of the operating system.  I then installed the necessary roles and features so that Internet Information Services (IIS) was installed and running.  In addition, the procedures presented in this post require the .NET Framework 3.5.1, and either Visual Studio 2008 or Visual Studio 2010.

Installing WCF and IIS

Use Server Manager to install the Web Server (IIS) Role and the.NET Framework 3.5.1 feature.

To run this example, the only Role that is required is Web Server (IIS).

 

After adding the Web Server (IIS) role, the Roles wizard will ask you to select Role Services.  Select Application Development.

 

To install the .NET Framework, add the .NET Framework 3.5.1 Features.

 

When you are installing this feature on Windows Server 2008 (not R2), after selecting the .NET Framework 3.0 Features, select WCF Activation.  This is selected by default on Windows Server 2008 R2.

 

Both WCF and IIS must be installed for IIS-hosted WCF services to function correctly.  The procedures for installing WCF (as part of the .NET Framework 3.0) and IIS vary depending on the operating system that you are using.  If you are installing on an operating system other than Windows Server 2008 or Windows Server 2008 R2, seeMicrosoft .NET Framework 3.0 Redistributable Package to download and install the .NET Framework 3.0.  SeeInstalling IIS for further instructions in that area.

Registering the Service Model

To run this example, you need to register this version of WCF and update scriptmaps at the IIS metabase root.

1.       Start a Visual Studio Command Prompt.  Run as administrator.

 

Click Start => All Programs => Visual Studio 2010 => Visual Studio Tools => Visual Studio Command PromptRight-click, select Start as Administrator.

The Visual Studio command prompt is located in a similar place for Visual Studio 2008.

2.       Change directory to:

c:\Windows\Microsoft.NET\Framework\v3.0\Windows Communication Foundation

Enter:

cd “c:\Windows\Microsoft.NET\Framework\v3.0\Windows Communication Foundation”

3.       In the command prompt, enter:

ServiceModelReg -i

 

This didn’t need to be a Visual Studio command prompt, but the following step needs a Visual Studio command prompt, so for efficiency, I created one in this step.

Updating Script Maps

4.       In the command prompt, enter:

aspnet_regiis.exe -i

 

Creating a Web Service

1.       Create a directory, C:\MyWebService, which will contain the web service.  If you use a different directory than this, you will need to alter these procedures as appropriate.

2.       Start Visual Studio 2010 (or 2008).

3.       Click File => New => Project.

a.       For the installed template category, select WCF.

b.      For the template, select WCF Service Application.

c.       Target the .NET Framework 3.5.

d.      For the location of the project, browse to the directory that you created in step 1.

e.      Name the project CustomersService.

f.        Do not create a directory for the solution.

 

Note: Don’t forget to target the .NET Framework 3.5.  By default, Visual Studio will target the .NET Framework 4.0, and you must change to 3.5 for the procedure presented here to work.

4.       In the project, rename IService1.cs to ICustomers.cs.  Visual Studio 2010 will ask whether you would also like to perform a rename in this project of all references to the code element ‘IService1’?  Click Yes.  Actually, we’re going to replace all code in all modules, so it doesn’t matter whether you click Yes or No.

5.       In the project, rename Service1.svc to Customers.svc.  After renaming these items, the Solution Explorer will look like this.

6.       Replace Customers.svc with the following single line of markup.  Right click on Customers.svc, and selectView Markup.  Copy, paste, and save.
<%@ ServiceHost Language=”C#” Debug=”true” Service=”CustomersService.Customers”CodeBehind=”Customers.svc.cs” %>
7.       Replace Customers.svc.cs with the following code.

using System;
using System.Collections.Generic;
using System.Linq;

namespace CustomersService
{
public class Customers : ICustomers
{
// Finder
public List<Customer> GetAllCustomers()
{
return new List<Customer>()
{
new Customer
{
CustomerID = 1,
CustomerName = “Bob”,
},
new Customer
{
CustomerID = 2,
CustomerName = “Bill”,
},
new Customer
{
CustomerID = 3,
CustomerName = “Cheryl”,
},
};
}

// Specific finder
public Customer GetCustomerByID(int CustomerID)
{
return GetAllCustomers().FirstOrDefault(c => c.CustomerID == CustomerID);
}
}
}

8.       Replace ICustomers.cs with the following code.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;

namespace CustomersService
{
[ServiceContract]
public interface ICustomers
{
[OperationContract] //finder
List<Customer> GetAllCustomers();

[OperationContract] //specificFinder
Customer GetCustomerByID(int CustomerID);
}

[DataContract]
public class Customer
{
[DataMember]
public int CustomerID { get; set; }

[DataMember]
public string CustomerName { get; set; }
}
}

9.       Replace Web.config with the following markup.  In Solution Explorer, right-click on Web.config and selectEdit.  Copy, paste, and save.  Important note: this is the Web.config that configures this specific web service.  It resides at C:\MyWebService\CustomersService.

<?xml version=”1.0″?>
<configuration>
<system.serviceModel>
<services>
<service behaviorConfiguration=”CustomersService.Service1Behavior”
name=”CustomersService.Customers”>
<endpoint address=”” binding=”wsHttpBinding” contract=”CustomersService.ICustomers”>
<identity>
<dns value=”localhost” />
</identity>
</endpoint>
<endpoint address=”mex” binding=”mexHttpBinding” contract=”IMetadataExchange” />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name=”CustomersService.Service1Behavior”>
<!– To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment –>
<serviceMetadata httpGetEnabled=”true”/>
<!– To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information –>
<serviceDebug includeExceptionDetailInFaults=”false”/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>

10.   Build the application.

11.   Add an application to the default web site.

a.       Start Internet Information Services (IIS) Manager.  Click Start => All Programs => Administrative Tools =>Internet Information Services (IIS) Manager.

b.      In Internet Information Services (IIS) Manager, expand Sites, and right-click on Default Web Site, and selectAdd Application.

 

 

c.       In the Add Application dialog box, in the Alias field, enter Customers.  In the Physical Path field, browse toC:\MyWebService\CustomersService.  Click OK twice.

 

12.   Validate that the web service is running.  Start Internet Explorer, and browse tohttp://localhost/Customers/Customers.svc.  If the web service is running, you will see the following:

 

Another interesting approach to testing the Web service is to use the WCF test client.  Start a Visual Studio command prompt (or use the one that is open from the beginning of this procedure).  Enter wcftestclient to run the WCF test client.  Click File => Add Service.  Enter http://localhost/Customers/Customers.svc as the endpoint address, and click OK.

 

If the service was added successfully, you will see the methods that the service exposes.

 

Double-click on GetAllCustomers.  This opens a window that allows you to configure the request and invoke the request.  Click on Invoke to see the response from the Web service.

 

In the next article, we will add some Windows Identity Framework (WIF) features, which we can use to determine the identity of the caller.

 

Referenced by: http://blogs.msdn.com/b/ericwhite/archive/2010/05/11/getting-started-building-a-wcf-web-service.aspx

 
Leave a comment

Posted by on January 18, 2012 in C#, WCF

 

How to Hide Content until Someone ‘Likes’ Your Facebook Fan Page

Hiding content from Facebook users until they ‘Like’ your fan page is a great way to increase the amount of fans following your page by giving users extra incentive to actually want to ‘Like’ your fan page. By utilizing fb:visible-to-connection a handy piece of built in FBML code we will be able to easily hide content from users until they ‘Like’ your page and become a fan. While this technique is not new and there are already numerous tutorials around on the subject our approach is different. We have simplified our technique in this tutorial to help alleviate some of the confusion we noticed from other tutorials. We have also solved a major issue for page admin’s who cannot see the actual fan content while logged in, however you still must log out in order to test the non-fan content.

PLEASE NOTE: The tutorial below is for FBML only! To learn how to accomplish this for an iFrame, please check out our Fan Gate Reveal Tab Iframe version here:http://www.daddydesign.com/wordpress/how-to-use-a-fan-gate-on-your-iframe-tab-to-hide-content-until-someone-likes-your-facebook-fan-page/

Step 1: Building the Fan Content DIV

The first step is to build the DIV which will house all of your content that will be visible to your Facebook fans. In order for the non-fan content DIV to be able to cover up the fan content DIV when a user hasn’t ‘Liked’ your fan page a specific height must be used, this same height will also be used on the non-fan content DIV in Step 2. Also please note the usage of the attribute z-index; this will be addressed in Step 2.

CSS

1 .fan_content{
2 width: 520px;
3 height: 500px;
4 float: left;
5 position: relative;
6 background: #ccc;
7 z-index: 1;
8 }

XHTML

1 <div class="fan_content">Fan Content Goes Here</div>

Step 2: Building the Non-Fan Content DIV

The next step is to build the non-fan content DIV which will house your image or content telling users in whatever way you choose to ‘Like’ your fan page in order to view the hidden content. In Step 1 we set a specific height for our fan content DIV, we are going to use that same height on our non-fan content DIV in order to make sure we cover up all of the content we want to hide from non-fans. We will also use that same height and apply it as a negative number to our margin-top attribute; this will ensure that our non-fan content DIV covers up our content DIV exactly pixel for pixel. Remember in Step 1 we set our z-index attribute to 1, well on our non-fan content DIV we will set the z-index attribute to 0, this will ensure that when you are logged in as admin you will always see the fan content instead of the non-fan content.

CSS

1 .non_fan_content{
2 width: 520px;
3 height: 500px;
4 float: left;
5 position: relative;
6 background: #666;
7 margin-top: -500px;
8 z-index: 0;
9 }

XHTML

1 <div class="non_fan_content">Non-Fan Content Goes Here</div>

Step 3: Wrapping the Content DIVs

The next step is a relatively simple step and is just a coding preference to keep all of the content contained, it is totally optional. Apply the following CSS and wrap your previous two DIVs with the wrapper DIV. The benefit in doing this step is that by setting the overflow attribute to hidden we guarantee that all of our content stays contained within the wrapper DIV. Please note that if you’ve used any other wrapper DIVs in your code please make sure that none of the code conflicts.

CSS

1 .wrapper{
2 width: 100%;
3 float: left;
4 position: relative;
5 overflow: hidden;
6 }

XHTML

1 <div class=”wrapper”>
2    <div class="fan_content">Fan Content Goes Here</div>
3   <div class="non_fan_content">Non-Fan Content Goes Here</div>
4 </div>

Step 4: Making it Work with FBML’s fb:visible-to-connection

The last and final step is to make it all work using FBML’s fb:visible-to-connection code to show content depending on whether or not the Facebook user has ‘Liked’ your fan page. Basically all that needs to be done is wrap both of your content DIVs inside of the fb:visible-to-connection tag and then wrap all of your non-fan content inside of the fb:else tag. After you have your final code upload it to your Static FBML tab and test it while both logged in and logged out, while logged in your fan content should be visible and while logged out your non-fan content should be visible. It’s that simple!

1 <div class="wrapper">
2   <fb:visible-to-connection>
3     <div class="fan_content">Fan Content Goes Here</div>
4   <fb:else>
5     <div class="non_fan_content">Non-Fan Content Goes Here</div>
6   </fb:else>
7   </fb:visible-to-connection>
8 </div>

Complete Code

CSS

01 .wrapper{
02 width: 100%;
03 float: left;
04 position: relative;
05 overflow: hidden;
06 }
07 .fan_content{
08 width: 520px;
09 height: 500px;
10 float: left;
11 position: relative;
12 background: #ccc;
13 z-index: 9;
14 }
15 .non_fan_content{
16 width: 520px;
17 height: 500px;
18 float: left;
19 position: relative;
20 background: #666;
21 margin-top: -500px;
22 z-index: 0;
23 }

XHTML

1 <div class="wrapper">
2   <fb:visible-to-connection>
3     <div class="fan_content">Fan Content Goes Here</div>
4   <fb:else>
5     <div class="non_fan_content">Non-Fan Content Goes Here</div>
6   </fb:else>
7   </fb:visible-to-connection>
8 </div>

Please Note:

This tutorial will only work for Facebook Static FBML.

Troubleshooting

If you are having problems getting this tutorial to work please reread the tutorial and try again, if you still can not get it to work please leave us a comment below and we will respond as soon as possible.

 
Leave a comment

Posted by on January 16, 2012 in Facebook