Sachith Wickramaarachchi
Sachith Wickramaarachchi

Reputation: 5862

How pass dataset to WCF method as a parameter

In there i used this code to read data of excel file and it's work for me properly. But i need to save this dataset to database with WCF. So think pass the dataset to wcf method to achieve this.But how can i do this

this is i tried code with windows form application

 private void button1_Click(object sender, EventArgs e)
   {
       OpenFileDialog opn = new OpenFileDialog();
       opn.Filter = "Excel Files|*.xls;*.xlsx;*.xlsm";

        if (opn.ShowDialog() == DialogResult.Cancel)
            return;

            FileStream strm = new FileStream(opn.FileName, FileMode.Open);
            IExcelDataReader excldr = ExcelReaderFactory.CreateOpenXmlReader(strm);

            DataSet rslt = excldr.AsDataSet();

           // while (excldr.Read())
           // {
           //    Console.WriteLine(excldr.GetString(1));
           // }
  }

I need to pass DataSet rslt to WCF method and within WCF i think to write save data function.is this good practice or not ? So how i can i do this

Upvotes: 0

Views: 2546

Answers (3)

Yawar Murtaza
Yawar Murtaza

Reputation: 3885

After reading your comment I thought I should give you some example how to tackle this problem in a slightly better way.

My approach would be to initialise Request/Response DataContract objects that allows client to send the dataset and receive the acknowledgement more effectively.

Here is the DataContract classes:

The request object that client will instantiate and populate and send to the service:

[DataContract]
public class SaveDataSetRequest
{
    [DataMember]
    public DataSet Data { get; set; }

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

   // you can add more properties here in the future versions without effecting the existing clients.
}

The response object that service will instantiate and populate and send back to the client:

 [DataContract]
 public class SaveDataSetResponse
 {
    public string Message { get; set; }
 }

The service contract:

[ServiceContract]
public interface IDataService
{
    [OperationContract]
    SaveDataSetResponse SaveDataSet(SaveDataSetRequest request);
}

and its implementation:

public class DataService : IDataService
{
    public SaveDataSetResponse SaveDataSet(SaveDataSetRequest request)
    {
        SaveDataSetResponse response = new SaveDataSetResponse();
        try
        {
           // save or processes your data set from request.Data object,
            // once this operation is completed successfully then return the success message.
            response.Message = "Success";
        }
        catch (Exception ex)
        {
            // log your exception 
            response.Message = $"Unable to save / process the data. Reason: {ex.Message}";
        }

        return response;
    }
}

You will need to update the service config something like this (if you havent)

<endpoint
      address="http://localhost:8000/<namespace>/IDataService"
      binding="netTcpBinding"
      contract="<namespace>.IDataService"
      name="DataService">
</endpoint>

On the client, update the service reference (adding a new version of service dll or service url - WSDL), create an instance of client proxy class and call SaveDataSetResponse SaveDataSet(SaveDataSetRequest request) method. Make sure that the client config - endpoint is also updated with new contract if you are copying this code as is.

Some useful links:

  • I would recommend the following book on WCF if you are new or need a refresh:
  • If you have plural sight access then this course would be a good starting point.

Upvotes: 1

Sachith Wickramaarachchi
Sachith Wickramaarachchi

Reputation: 5862

I solved my problem :)

private void button2_Click(object sender, EventArgs e)
{
    ServiceReference1.Service2Client obj = new ServiceReference1.Service2Client();
    OpenFileDialog opn = new OpenFileDialog();
    opn.Filter = "Excel Files|*.xls;*.xlsx;*.xlsm";

    if (opn.ShowDialog() == DialogResult.Cancel)
        return;

    try
    {
        FileStream strm = new FileStream(opn.FileName, FileMode.Open);
        IExcelDataReader excldr = ExcelReaderFactory.CreateOpenXmlReader(strm);
        DataSet rslt = excldr.AsDataSet();
        obj.insertExecl(rslt);

    }
    catch (IOException x)
    {
        MessageBox.Show(x.Message);
    }
}

Service2.cs

public class Service2 : IService2
{
    public void insertExecl(DataSet rslt)
    {
        DataClasses1DataContext conn = new DataClasses1DataContext();

        foreach (DataTable table in rslt.Tables)
        {
            foreach (DataRow dr in table.Rows)
            {
                tblExcel addTbl = new tblExcel()
                {
                    SID = Convert.ToString(dr[0]),
                    Name = Convert.ToString(dr[1]),
                    Address = Convert.ToString(dr[2])
                };
                conn.tblExcels.InsertOnSubmit(addTbl);
            }
        }


        conn.SubmitChanges();

        //excldr.Close();
        //strm.Close();
        Console.WriteLine("successfully");

    }
}

IService2.cs

[ServiceContract]
public interface IService2
{
    [OperationContract]
    void insertExecl(DataSet rslt);
}

Upvotes: 0

KD2ND
KD2ND

Reputation: 321

Passing a DataTable or a DataSet through WCF is a highly debated topic. It can be done easily, however Personally i prefer to pass the data itself and not the metadata (columns and rows definitions, data relations etc.) I usually declare an object , expose it to WCF and transfer it.

For each of the tables in your DataSet You can do something like the following (not tested) :

 public class ExcelService : IExcelService
{
    public List<CustomExcelData> GetExcelData()
    {
        List<CustomExcelData> excelDataList = new List<CustomExcelData>();
        OpenFileDialog opn = new OpenFileDialog();
        opn.Filter = "Excel Files|*.xls;*.xlsx;*.xlsm";

        if (opn.ShowDialog() == DialogResult.Cancel)
            return null;

        FileStream strm = new FileStream(opn.FileName, FileMode.Open);
        IExcelDataReader excldr = ExcelReaderFactory.CreateOpenXmlReader(strm);

        DataSet rslt = excldr.AsDataSet();

        DataTable dt = rslt.Tables[0];

        if (dt != null && dt.Rows.Count > 0)
        {
            foreach (DataRow row in dt.Rows)
            {
                excelDataList.Add(new CustomExcelData(row));
            }
        }

        return excelDataList;
    }
}

and the interface :

[ServiceContract]
interface IExcelService
{
    [OperationContract]
    List<CustomExcelData> GetExcelData();
}

[DataContract]
public class CustomExcelData
{
    [DataMember]
    public string Name { get; set; }
    [DataMember]
    public string Address { get; set; }
    [DataMember]
    public DateTime BirthDate { get; set; }

    public CustomExcelData(DataRow row)
    {
        Name = row["NameField"].ToString();
        Address = row["AddressField"].ToString();
        BirthDate = DateTime.Parse(row["BirthDateField"].ToString());
    }

}

Upvotes: 1

Related Questions