C# Tutorials and offshore development in India
    Tutorials   Resources   Forum   Reviews   Communities   Interview   Jobs   Projects   Training   Your Ad Here    
Silverlight Games | Mentor | Code Converter | Articles | Code Factory | Computer Jokes | Members | Peer Appraisal | IT Companies | Bookmarks | Polls | Revenue Sharing | Lobby | Gift Shop |


Prizes & Awards
My Profile



Active Members
TodayLast 7 Days more...






Forums » .NET » WCF »

Error while passing sql parameters to stored procedure in WCF


Posted Date: 01 Nov 2009      Posted By: Hema      Member Level: Bronze     Points: 1   Responses: 4



Hi,

Kindly excuse if I am posting in the wrong place.

I am using Visual Studio 2008, .net framework 3.5, asp.net , c# and sql server 2005.

I am supposed to pass stored procedures from client to wcf service.

The WCF service should execute the stored procedure and return the result.

When I pass the stored procedure which does not have any parameter, it works, but the moment I pass any parameter, it throws error as below

There was an error while trying to serialize parameter http://tempuri.org/:sqlparams. The InnerException message was 'Type 'System.Data.SqlTypes.SqlInt32' with data contract name 'int:http://www.w3.org/2001/XMLSchema' is not expected. Add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.'. Please see InnerException for more details.

I provide the snapshot of the WCF service, The below is IService

namespace wcfstoredprocedure
{
[ServiceContract]
public interface IService1
{
[OperationContract]
Employee GetReturnValues(string storedprocedure, SqlParameter[] sqlparams);
}

[DataContract]
public class Employee
{
[DataMember]
private int empId;
public int EmpId
{
get { return empId; }
set { empId = value; }
}
[DataMember]
private string empName;
public string EmpName
{
get { return empName; }
set { empName = value; }
}
[DataMember]
private DateTime empJoinDate;
public DateTime EmpJoinDate
{
get { return empJoinDate; }
set { empJoinDate = value; }
}
[DataMember]
private int empOnDuty;
public int EmpOnDuty
{
get { return empOnDuty; }
set { empOnDuty = value; }
}

}
}

The Below code is of Service1.cs


namespace wcfstoredprocedure
{
// NOTE: If you change the class name "Service1" here, you must also update the reference to "Service1" in Web.config and in the associated .svc file.
public class Service1 : IService1
{
DataTable dt = new DataTable();
public Employee GetReturnValues(string storedprocedure, SqlParameter[] sqlparams)
{
Employee emp = new Employee();
using (SqlConnection sqlCon=new SqlConnection(@"server=ABC-415D0247602\SQLEXPRESS;integrated security=true;database=Employee"))
{
using (SqlCommand sqlCom = new SqlCommand("GetEmpDuty", sqlCon))
{

SqlDataAdapter da = new SqlDataAdapter(sqlCom);
da.Fill(dt);
}
}
emp.EmpId =Convert.ToInt32(dt.Rows[0]["Id"]);
emp.EmpJoinDate =Convert.ToDateTime(dt.Rows[0]["joindate"]);
emp.EmpName = dt.Rows[0]["Name"].ToString();
emp.EmpOnDuty = Convert.ToInt32(dt.Rows[0]["onduty"]);

return emp;
}
}
}



The below is the code for the Client


ServiceReference1.Employee sq = new WebApplicationstoredprocedure.ServiceReference1.Employee();
ServiceReference1.Service1Client sc = new WebApplicationstoredprocedure.ServiceReference1.Service1Client();
SqlParameter[] sqlparams=new SqlParameter[1];

sqlparams[0] = new SqlParameter("@Id", SqlDbType.Int);
sqlparams[0].Value = 1;
sq = sc.GetReturnValues("GetEmpDuty", sqlparams);
Response.Write(sq.empId.ToString());
Response.Write("<br>");
Response.Write(sq.empJoinDate.ToString());
Response.Write("<br>");
Response.Write(sq.empName.ToString());
Response.Write("<br>");
Response.Write(sq.empOnDuty.ToString());


Please do let me know where am I going wrong.

I tried to add [Serializable], but did not work.

Changed sqlparameters to object, but did not work.

Any suggestions







Responses

Author: Hari    01 Nov 2009Member Level: GoldRating: 2 out of 52 out of 5     Points: 2

Hi,

Firstly,passinf sqlparameter as an operation parameter reduces your interoperability greatly. You might want pass a datacontract as the operation parameter and use a translator to convert that into your busines entiy and pass it on to the DAL layer. That said, please find below a fix to your problem. When using sqlparameter in an operation, the "Add service reference" will not work. Firstly you need to add the following to your service class

[KnownType(typeof(SqlParameter))]
[KnownType(typeof(SqlInt32))]
public class Service1 : IService1
{

Next use svcutil to generate your proxy and app.config and not "Add service reference". Assuming that your service url is as follows http://localhost:2632/Service1.svc?wsdl. Us ethe following command to generate your proxy and config file

G:\Program Files\Microsoft Visual Studio 9.0\VC>svcutil http://localhost:2632/Service1.svc?wsdl

Use the generated proxy and app.config to instantiate your client as follows. Note, svcutil generates its own SqlParameter class and you have to set the properties as below. I have uploaded a working sample

http://cid-05c2e50f2c5140c1.skydrive.live.com/self.aspx/.Public/TimeValidation.rar

Service1Client client = new Service1Client();

SqlParameter[] sqlparams = new SqlParameter[1];

sqlparams[0] = new SqlParameter();
sqlparams[0].DbType = DbType.Int32;
sqlparams[0].ParameterName = "@Id";
sqlparams[0].Value = 1;
sqlparams[0].Direction = ParameterDirection.Input;
sqlparams[0].SourceVersion = DataRowVersion.Default;
client.GetReturnValues("GetEmpDuty", sqlparams);



TimeValidation.rar
Author: Hema    01 Nov 2009Member Level: BronzeRating: 2 out of 52 out of 5     Points: 2

Hi,
Thanks Hari, for the response(that too on Sunday).

I modified the service class as below

namespace wcfstoredprocedure
{
// NOTE: If you change the class name "Service1" here, you must also update the reference to "Service1" in Web.config and in the associated .svc file.
[KnownType(typeof(SqlParameter))]
[KnownType(typeof(SqlInt32))]
public class Service1 : IService1
{
DataTable dt = new DataTable();
public Employee GetReturnValues(string storedprocedure, SqlParameter[] sqlparams)
{

Employee emp = new Employee();
using (SqlConnection sqlCon = new SqlConnection(@"server=ABC-415D0247602\SQLEXPRESS;integrated security=true;database=Employee"))
{
using (SqlCommand sqlCom = new SqlCommand(storedprocedure, sqlCon))
{
sqlCom.Parameters.Add(sqlparams);
sqlCom.ExecuteNonQuery();

}
}


return emp;
}
}
}


and the client as
protected void Page_Load(object sender, EventArgs e)
{
Service1Client s1 = new Service1Client();
SqlParameter[] sqlparams = new SqlParameter[4];

sqlparams[0] = new SqlParameter();
sqlparams[0].DbType = DbType.Int32;
sqlparams[0].ParameterName = "@Id";
sqlparams[0].Value = 4;
sqlparams[0].Direction = ParameterDirection.Input;
sqlparams[0].SourceVersion = DataRowVersion.Default;
sqlparams[1] = new SqlParameter();
sqlparams[1].DbType = DbType.String;
sqlparams[1].ParameterName = "@name";
sqlparams[1].Value = "bb";
sqlparams[1].Direction = ParameterDirection.Input;
sqlparams[1].SourceVersion = DataRowVersion.Default;
sqlparams[2] = new SqlParameter();
sqlparams[2].DbType = DbType.DateTime;
sqlparams[2].ParameterName = "@joindate";
sqlparams[2].Value = DateTime.Now;
sqlparams[2].Direction = ParameterDirection.Input;
sqlparams[2].SourceVersion = DataRowVersion.Default;
sqlparams[3] = new SqlParameter();
sqlparams[3].DbType = DbType.Boolean;
sqlparams[3].ParameterName = "@onduty";
sqlparams[3].Value = true;
sqlparams[3].Direction = ParameterDirection.Input;
sqlparams[3].SourceVersion = DataRowVersion.Default;
s1.GetReturnValues("InsertEmpDuty", sqlparams);


string j = "test";


}

I followed your svcutil regime and it works, but one minor hitch.
When I placed a breakpoint in the service I found all the values of parameters become NULL, and it throws error.

I changed the line
sqlCom.Parameters.Add(sqlparams);
to
sqlCom.Parameters.AddRange(sqlparams);

But then too all the values are passing as null. Any Idea why?



Author: Hari    03 Nov 2009Member Level: GoldRating: 4 out of 54 out of 54 out of 54 out of 5     Points: 6

Hi Please find below another sample. This is exactly like your scenario. I think the issue is fixed. the issue was with the namespace. http://cid-05c2e50f2c5140c1.skydrive.live.com/self.aspx/.Public/test2.rar


Author: Hema    03 Nov 2009Member Level: BronzeRating: 2 out of 52 out of 5     Points: 2

Thnx Hari. Solved it.


Post Reply
You must Sign In to post a response.
Next : Wcf communication
Previous : How to add reference of WCF service to a ASP.NET Page
Return to Discussion Forum
Post New Message
Category: WCF

Related Messages



dotNet Slackers

About Us    Contact Us    Privacy Policy    Terms Of Use