locked
passing datasets between client app and webservice RRS feed

  • Question

  • User-1565900434 posted

    I am working on creating a wcf webservice that will be called by our client application that will be
    either windows form based or a web page but that is really not of material importance here since both window form
    and webpage will be able to call this webservice. Actually I have already tested the webserivce from a test
    window form app I created and webservice returns the required data fine. The issue I am struggling with is to
    commit any changes made to the data sent by the webservice to the client app to the database.

    The webservice actaully returns a dataset that is consumed by the client app and results are displayed in a
    datagridview object and this part works fine, my problem is that I want to send the modified dataset back to
    webservice and use the webservice to update any changes to the database. This way I can make sure that client is
    completely independent of how data for client is retrieved and updated. Now I was able to populate the dataset
    inside my webservice and send it to client by setting the return type of the method in the webserivce
    that retrieves data to a
    dataset but I do not know how I can pass the modified dataset back to the webserivce and send the changes in
    the dataset back to the database. I am very new to .net and very very new to webservices but I somehow manage to
    retrieve the data and send it to requesting client but i need help on how to pass the modified dataset to the
    webservice and any help will be
    much appreciated. I am not even sure if it is possible to do this but I imagine that webservice is just a
    middle layer and if can retrieve data and send it to clinet it should be able to receive data coming from client
    as well.

    Monday, May 20, 2013 1:20 PM

Answers

  • User-1565900434 posted

    After waiting for few days and be determined to not to give up and find a solution (thanks to some other folks online for pointing in right direction) here is the complete solution along with code that will basically return an edited dataset (edited inside dgv) back to webservice and webservice will sucessfully process the changes and update the database, at this point I already have a dataset that was returned by my webservice and I bound that dataset to dgv in my clinet app and users are able to make changes to dgv, here is the code for that:

    notesDataSet = notesClient.GetPatientNotes("6236321.00");
    
    dataGridView1.DataSource = notesDataSet.Tables[0];

    This is the code I have in my save button in my client app:

     if (notesDataSet.HasChanges())
                {
                    DataSet editDataSet = notesDataSet.GetChanges();
                    notesClient.UpdatePatientNotes(editDataSet);
                }
                notesDataSet.AcceptChanges();

    the edited dataset editDataset is passed back to UpdatePatientNotes method in my webservice and that mehtod takes this edited dataset and updates the database table associated with this dataset, here is the code for that method:

    public void UpdatePatientNotes(DataSet editDataSet)
            {
                //string connStr = WebConfigurationManager.ConnectionStrings["Employees"].ConnectionString;
    
                //connectionString = ConfigurationManager.ConnectionStrings["DV_test"].ConnectionString;
    
                connectionString = "user id=xxx;" +
                                      "password=xxxx;server=xxx-xx-xx;" +
                                      "Trusted_Connection=no;" +
                                      "database=xxx; " +
                                      "connection timeout=30";
    
                using (var conn = new SqlConnection(connectionString))
                {
                    conn.Open();
    
                    string sql = "select * from attached_table where 1 = 0";
    
                    using(var da = new SqlDataAdapter(sql, conn))
                    {
    
                        var builder = new SqlCommandBuilder(da);
    
                        da.InsertCommand = builder.GetInsertCommand();
                        da.UpdateCommand = builder.GetUpdateCommand();
                        da.DeleteCommand = builder.GetDeleteCommand();
    
                        da.Update(editDataSet);
                    }
                }
            }

    Note that I have the connectionstring hardcoded for testing purposes but you could very well (and recommended) store your connectionstring in your configuration file and retrieve it via configurationmanager. This is all it takes and this shold work without any issues. I hope this will help somone out there. 



    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, May 22, 2013 9:51 AM

All replies

  • User-851967432 posted

    Well the return type of your method would be Dataset. 

    You would simply call the service method, run the CRUD code. From there you would have to query the database again to return the new dataset.

    Monday, May 20, 2013 2:42 PM
  • User-1565900434 posted

    thank you for your reply, u made it sound very simple which it is possible that it is, but I am new to the whole thing and I am trying to understand what you mean. 

    the client app and webservice are two diffrent apps communicating with each other via the service contract. do u mean that I have a method in my webserivce that takes a dataset as parm and then call this method from the client and pass the modified dataset to it. If your answer is yes then I will be passing back the original dataset that was sent to the client as a result of the service request in the first place, but now users have modifed data and will these modifications be part of the dataset if I simply send this dataset back to the update method in webservice. Also will I be able to run the CRUD statemetns on the dataset I pass to this method? can u please explain what u mean? thanks

    Monday, May 20, 2013 3:14 PM
  • User-851967432 posted

    Once you consume the service, it is no different than a local class and you can treat it as such.

    So whichever method you're calling to pass the data can both commit data to the database and query the database and return the new dataset.

    Monday, May 20, 2013 3:22 PM
  • User-1565900434 posted

    you are abs right once the service is consumed then it is just like local class but i think at this point it will help if I can ask my question (again i m sorry) with the actual code I am using:

    this is the mehtod from my webservice that returns the dataset:

    public DataSet GetPatientNotes(string masterKey)
            {
                DataSet data = new DataSet();
                if (!string.IsNullOrEmpty(masterKey))
                {
                    DataService.SoaDataClient dataClient = new DataService.SoaDataClient();
    
                    data = dataClient.GetDataSet(string.Format("select * from [DentalVisionTest].[dbo].progress_note_patient where master_key = '{0}'", masterKey), "DV_test");
                }
    
                return data;
            }


    this is the code that actually calls the above method from my client app and displays data in the dataset in a datagridview:

    private void Form1_Load(object sender, EventArgs e)
            {
                PatientNotes.PatientNotesClassClient notesClient = new PatientNotes.PatientNotesClassClient();
                notesDataSet = notesClient.GetPatientNotes("6236321.00");
    
                dataGridView1.DataSource = notesDataSet.Tables[0];
            }



    
    

    GetPatientNotes is the name of the mehtod in my webservice and form1_load event actually calls this method, now r u saying that i update and commit data from inside getPatientNotes method once I have returned the dataset to the calling mehtod, because if I do that GetPatientNotes does not know anything about the changes user have made and if I update it form form1_load event, although it is possible but it kills the whole purpose of keeping the client layer separate from the service layer, so can u please explain what you mean? thanks

    Monday, May 20, 2013 3:57 PM
  • User-851967432 posted

    Ok I think I'm a little confused. So far, it looks like you have the web service reading your dataset and populating the gridview and all is well there. Now you want to update the records and repopulate the gridview through the web service?

    If yes, then you will need a method in the web service that accepts the new records in some form, and performs the update.

    Something like this:

    notesClient.UpdatePatientNotes("ds);
    Now if you create this method, it can have a return type of dataset so you can make the call and rebind the datasource as follows:
    myGridView.DataSource = notesClient.UpdatePatientNotes("ds);
    Make sense?
    Monday, May 20, 2013 4:11 PM
  • User-1565900434 posted

    OK: Adam thank u very much for staying on this with me I believe now we r getting somewhere, you are ight that
    I should create UpdatePatientNotes in my webservice and pass the new records to it in some form and update the
    database, but how I have it working right now is acutally opposite of how you have described it in your reply,
    the webservice simply returns dataset, client app takes this dataset and binds it to a gridview and then changes
    are made to datagridview, webservice knows nothing about the changes at this point, my questions are:

    Can i take the same dataset "notesDataSet" from form1_load event and pass it to my new updatepatientnotes method that I will create in my webservice and if I do that will it have the changes user made to this dataset via gridveiw if answer is yes then I can focus on writing the updatepatientnotes method in my webservice

    The other question is that lets say I can pass the modifed dataset back to the service but will I have to create a link between the dataset and the table that will get updated via an adapter? 

    hope my questions makes sense.

    Monday, May 20, 2013 4:58 PM
  • User-1565900434 posted

    After waiting for few days and be determined to not to give up and find a solution (thanks to some other folks online for pointing in right direction) here is the complete solution along with code that will basically return an edited dataset (edited inside dgv) back to webservice and webservice will sucessfully process the changes and update the database, at this point I already have a dataset that was returned by my webservice and I bound that dataset to dgv in my clinet app and users are able to make changes to dgv, here is the code for that:

    notesDataSet = notesClient.GetPatientNotes("6236321.00");
    
    dataGridView1.DataSource = notesDataSet.Tables[0];

    This is the code I have in my save button in my client app:

     if (notesDataSet.HasChanges())
                {
                    DataSet editDataSet = notesDataSet.GetChanges();
                    notesClient.UpdatePatientNotes(editDataSet);
                }
                notesDataSet.AcceptChanges();

    the edited dataset editDataset is passed back to UpdatePatientNotes method in my webservice and that mehtod takes this edited dataset and updates the database table associated with this dataset, here is the code for that method:

    public void UpdatePatientNotes(DataSet editDataSet)
            {
                //string connStr = WebConfigurationManager.ConnectionStrings["Employees"].ConnectionString;
    
                //connectionString = ConfigurationManager.ConnectionStrings["DV_test"].ConnectionString;
    
                connectionString = "user id=xxx;" +
                                      "password=xxxx;server=xxx-xx-xx;" +
                                      "Trusted_Connection=no;" +
                                      "database=xxx; " +
                                      "connection timeout=30";
    
                using (var conn = new SqlConnection(connectionString))
                {
                    conn.Open();
    
                    string sql = "select * from attached_table where 1 = 0";
    
                    using(var da = new SqlDataAdapter(sql, conn))
                    {
    
                        var builder = new SqlCommandBuilder(da);
    
                        da.InsertCommand = builder.GetInsertCommand();
                        da.UpdateCommand = builder.GetUpdateCommand();
                        da.DeleteCommand = builder.GetDeleteCommand();
    
                        da.Update(editDataSet);
                    }
                }
            }

    Note that I have the connectionstring hardcoded for testing purposes but you could very well (and recommended) store your connectionstring in your configuration file and retrieve it via configurationmanager. This is all it takes and this shold work without any issues. I hope this will help somone out there. 



    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, May 22, 2013 9:51 AM