WCF services and silverlight

Associate
Joined
27 Jan 2005
Posts
1,324
Location
S. Yorks
Must admit I am new to all this and am right royally struggling.

I have an application and I need to query a legacy database, rules out using EF as it not supported for it, and return data to a datatable in Silverlight.

I have followed this example http://www.dreamincode.net/forums/topic/173124-silverlight-connecting-to-remote-database-wcf/

modified it slightly so the service creates a datable which works fine however I can't for the life of me work out how to pass it back to MainPage as a datatable - does anyone have any examples of how to do this, have tried various Microsoft forums and getting no results back.

regards,

Matt
 
Associate
Joined
1 Dec 2003
Posts
246
Location
High Wycombe
It would help to know what you have already, but what you want to do on the service side is create an object that you can send back when the WCF method is called.

I wouldn't send a DataTable across using WCF, it would be better to send an object across.

What you probably want to do is create a DataContract that the WCF service will send back to silverlight.

Following that example, you could create a DataContract for the names, in this case a Person.
Code:
[DataContract]
public class Person
{
    private string _Firstname;
    private string _Surname;

    [DataMember]
    public string Firstname
    {
        get { return _Firstname; }
        set { _Firstname= value; }
    }
    [DataMember]
    public string Surname
    {
        get { return _Surname; }
        set { _Surname= value; }
    }
}

Then instead of having an Operation Contract that returns a list of strings, you would return a list of People(Person) or A Person by id.
Code:
[OperationContract]
List<Person> GetPeople();

[OperationContract]
Person GetPerson(int id);

You will need to implement this in your service. But if you follow the layout of the example on D.I.C you should be able to understand it.
 
Associate
OP
Joined
27 Jan 2005
Posts
1,324
Location
S. Yorks
Hi,

Thanks for the reply.

Currently I have an interface:

Code:
namespace WCF_SF.Web
{
    [ServiceContract]
    public interface ISFWCFService
    {
        [OperationContract]
        List<List<string>> GetNames();
    }
}

Then I have the service:

Code:
namespace WCF_SF.Web
{
    public class WCFService : IWCFService
    {
        string AConnectionString = "some connection string";
        string IConnectionString = "some other connection string";
        
        public List<List<string>> GetNames()
        {
            List<List<string>> lstTable = new List<List<string>>();

            using (SqlConnection cn = new SqlConnection(AConnectionString))
            {
                using (SqlCommand cmd = cn.CreateCommand())
                {
                    cmd.CommandText = "some sql string";
                    cmd.CommandType = CommandType.Text;

                    cn.Open();

                    DataSet DataSet = new DataSet();

                    SqlConnection conn = new SqlConnection(AConnectionString);
                    SqlDataAdapter adapter = new SqlDataAdapter();

                    adapter.SelectCommand = new SqlCommand(cmd.CommandText, conn);

                    adapter.Fill(DataSet);

                    lstTable = conv_dt_to_list(DataSet.Tables[0]);                   
                }
            }

            return lstTable;
        }

        public List<List<string>> conv_dt_to_list(DataTable dt)
        {
            List<List<string>> lstTable = new List<List<string>>();
            // Convert datatable to a list of lists
            foreach (DataRow row in dt.Rows)
            {
                List<string> lstRow = new List<string>();
                foreach (var item in row.ItemArray)
                {
                    lstRow.Add(item.ToString().Replace("\r\n", string.Empty));
                }
                lstTable.Add(lstRow);
            }

            return lstTable;
        }
           
    }

So within the interface you are basically saying I need to create the structure of the data? Can it not be done dynamically?

regards,

Matt
 
Associate
Joined
1 Dec 2003
Posts
246
Location
High Wycombe
Yes, you would have to create the structure of the data yourself, if it was possible to use EF you could use the data structure that it creates.

Code:
namespace WCF_SF.Web
{
    [ServiceContract]
    public interface ISFWCFService
    {
        [OperationContract]
        List<Person> GetNames();

        [OperationContract]
        Person GetPerson(int id);
    }

    [DataContract]
    public class Person
    {
        private string _Firstname;
        private string _Surname;

        [DataMember]
        public string Firstname
        {
            get { return _Firstname; }
            set { _Firstname= value; }
        }
        [DataMember]
        public string Surname
        {
            get { return _Surname; }
            set { _Surname= value; }
        }
    }
}
Code:
namespace WCF_SF.Web
{
    public class WCFService : IWCFService
    {
        string AConnectionString = "some connection string";
        string IConnectionString = "some other connection string";

        
        
        public List<Person> GetNames()
        {
            List<Person> People = new List<Person>();

            using (SqlConnection cn = new SqlConnection(AConnectionString))
            {
                using (SqlCommand cmd = cn.CreateCommand())
                {
                    SqlDataAdapter personAdapter = new SqlDataAdapter(
                        "SELECT * FROM dbo.Person", customerConnection);                 

                    DataSet people = new DataSet();

                    personAdapter.Fill(people, "Person");

                    Person newPerson = null;
                    foreach( DataRow row in people.Tables["Person"].Rows)
                    {
                        newPerson = new Person();

                        // Should do some error checking here as well.

                        newPerson.FirstName = row["FirstName"];
                        newPerson.Surname = row["Surname"];

                        People.Add(newPerson);
                    }
                }
            }

            return People;
        }

        public Person GetPerson(int id)
        {
                // Similar to above.
        }           
    }

That's something similar to how I would do it. Not sure on the DataRow has been a while since I have touched that.

Then on the other side you should be able to just set the data for the table to be equal to what is returned from WCF
 
Associate
OP
Joined
27 Jan 2005
Posts
1,324
Location
S. Yorks
All working reasonably well now, but I have a query re "public Person GetPerson(int id)", how do I query for the person with that ID - confused weather to requery the data again or query the Person?

regards,

Matt

Yes, you would have to create the structure of the data yourself, if it was possible to use EF you could use the data structure that it creates.

Code:
namespace WCF_SF.Web
{
    [ServiceContract]
    public interface ISFWCFService
    {
        [OperationContract]
        List<Person> GetNames();

        [OperationContract]
        Person GetPerson(int id);
    }

    [DataContract]
    public class Person
    {
        private string _Firstname;
        private string _Surname;

        [DataMember]
        public string Firstname
        {
            get { return _Firstname; }
            set { _Firstname= value; }
        }
        [DataMember]
        public string Surname
        {
            get { return _Surname; }
            set { _Surname= value; }
        }
    }
}
Code:
namespace WCF_SF.Web
{
    public class WCFService : IWCFService
    {
        string AConnectionString = "some connection string";
        string IConnectionString = "some other connection string";

        
        
        public List<Person> GetNames()
        {
            List<Person> People = new List<Person>();

            using (SqlConnection cn = new SqlConnection(AConnectionString))
            {
                using (SqlCommand cmd = cn.CreateCommand())
                {
                    SqlDataAdapter personAdapter = new SqlDataAdapter(
                        "SELECT * FROM dbo.Person", customerConnection);                 

                    DataSet people = new DataSet();

                    personAdapter.Fill(people, "Person");

                    Person newPerson = null;
                    foreach( DataRow row in people.Tables["Person"].Rows)
                    {
                        newPerson = new Person();

                        // Should do some error checking here as well.

                        newPerson.FirstName = row["FirstName"];
                        newPerson.Surname = row["Surname"];

                        People.Add(newPerson);
                    }
                }
            }

            return People;
        }

        public Person GetPerson(int id)
        {
                // Similar to above.
        }           
    }

That's something similar to how I would do it. Not sure on the DataRow has been a while since I have touched that.

Then on the other side you should be able to just set the data for the table to be equal to what is returned from WCF
 
Associate
OP
Joined
27 Jan 2005
Posts
1,324
Location
S. Yorks
Am now at the point where I need to pass a variable to the WCF service and it aint working.

I have modded the interface:

Code:
        [OperationContract]
        List<AProjectData> GetAProjectInfo();
    
        [OperationContract]
        AProjectData GetAProjectInfoCode2(string strcode)

I have created a function to receive the parameter but, how do I pass the variable from the web form to do this?

regards,

Matt
 
Associate
OP
Joined
27 Jan 2005
Posts
1,324
Location
S. Yorks
I have regenerated the client, but how do I send it from the client side?

e.g. On my web page I have a combobox, when the combobox changes its value I want the query to search for the results based around this new value.

regards,

Matt
 
Back
Top Bottom