KnownType attribute in WCF?
If we have classes related by inheritance, the wcf service generally accepts and returns the base type. If you expect the service to accept and return inherited types, then use KnownType attribute.
There are other ways of associating known types, which we will discuss in next lecture.
Code used in the demo:
SQL:
Alter tablePersonAdd
WorkerTypeint, AnnualSalaryint,Smesterint,Marksint
Alter procedureGetPerson
@Idint
as
Begin
SelectId, Name, Gender, DateOfBirth,
WorkerType,AnnualSalary,Smester,Marks
fromPersonwhereId = @Id
End
Alter procedureSavePerson
@Idint,
@Namenvarchar(50),
@Gendernvarchar(50),
@DateOfBirthDateTime,
@WorkerTypeint,
@AnnualSalaryint=null,
@Smesternvarchar(50)=null,
@Marks int=null
as
Begin
Insert intoPerson
values(@Id, @Name, @Gender, @DateOfBirth,
@WorkerType, @AnnualSalary, @Smester,
@Marks)
End
FullTimeEmployee.cs
namespaceEmployeeService
{
publicclassTeacher : Person
{
publicint Salary{ get; set; }
}
}
PartTimeEmployee.cs
namespaceEmployeeService
{
publicclassStudent : Person
{
publicstringSmester { get; set; }
publicint Marks { get; set; }
}}
Employee.cs
usingSystem;
usingSystem.Runtime.Serialization;
namespaceAcademicService
{
[KnownType(typeof(Teacher))]
[KnownType(typeof(Student))]
[DataContract(Namespace = "
publicclassPerson
{
privateint _id;
privatestring _name;
privatestring _gender;
privateDateTime _dateOfBirth;
[DataMember(Order = 1)]
publicint Id
{
get { return _id; }
set { _id = value; }
}
[DataMember(Order = 2)]
publicstring Name
{
get { return _name; }
set { _name = value; }
}
[DataMember(Order = 3)]
publicstring Gender
{
get { return _gender; }
set { _gender = value; }
}
[DataMember(Order = 4)]
publicDateTimeDateOfBirth
{
get { return _dateOfBirth; }
set { _dateOfBirth = value; }
}
[DataMember(Order = 5)]
publicPersonType Type { get; set; }
}
publicenumPersonType
{
Teacher = 1,
Student = 2
}
publicclassTeacher : Person
{
publicint Salary{ get; set; }
}
publicclassStudent : Person
{
publicstringSmester { get; set; }
publicint Marks { get; set; }
}
}
EmployeeService.cs
usingSystem;
usingSystem.Data;
usingSystem.Data.SqlClient;
usingSystem.Configuration;
namespaceAcademicService
{
publicclassAcademicService : IAcademicService
{
publicPersonGetPerson(int Id)
{
Personperson = null;
stringcs = "Data Source=.;Initial Catalog=KnownType;Integrated Security=True";
using (SqlConnection con = newSqlConnection(cs))
{
SqlCommandcmd = newSqlCommand("GetEmployee", con);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameterparameterId = newSqlParameter();
parameterId.ParameterName = "@Id";
parameterId.Value = Id;
cmd.Parameters.Add(parameterId);
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
if ((PersonType)reader["EmployeeType"] == PersonType.Teacher)
{
person = newTeacher
{
Id = Convert.ToInt32(reader["Id"]),
Name = reader["Name"].ToString(),
Gender = reader["Gender"].ToString(),
DateOfBirth = Convert.ToDateTime(reader["DateOfBirth"]),
Type = PersonType.Teacher,
Salary = Convert.ToInt32(reader["AnnualSalary"])
};
}
else
{
person = newStudent
{
Id = Convert.ToInt32(reader["Id"]),
Name = reader["Name"].ToString(),
Gender = reader["Gender"].ToString(),
DateOfBirth = Convert.ToDateTime(reader["DateOfBirth"]),
Type = PersonType.Student,
Smester = reader["Semester"].ToString(),
Marks = Convert.ToInt32(reader["Marks"]),
};
}
}
}
return person;
}
publicvoidSavePerson(Person person)
{
stringcs = "Data Source=.;Initial Catalog=KnownType;Integrated Security=True";
using (SqlConnection con = newSqlConnection(cs))
{
SqlCommandcmd = newSqlCommand("SaveEmployee", con);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameterparameterId = newSqlParameter
{
ParameterName = "@Id",
Value = person.Id
};
cmd.Parameters.Add(parameterId);
SqlParameterparameterName = newSqlParameter
{
ParameterName = "@Name",
Value = person.Name
};
cmd.Parameters.Add(parameterName);
SqlParameterparameterGender = newSqlParameter
{
ParameterName = "@Gender",
Value = person.Gender
};
cmd.Parameters.Add(parameterGender);
SqlParameterparameterDateOfBirth = newSqlParameter
{
ParameterName = "@DateOfBirth",
Value = person.DateOfBirth
};
cmd.Parameters.Add(parameterDateOfBirth);
SqlParameterparameterEmployeeType = newSqlParameter
{
ParameterName = "@EmployeeType",
Value = person.Type
};
cmd.Parameters.Add(parameterEmployeeType);
if (person.GetType() == typeof(Teacher))
{
SqlParameterparameterAnnualSalary = newSqlParameter
{
ParameterName = "@AnnualSalary",
Value = ((Teacher)person).Salary
};
cmd.Parameters.Add(parameterAnnualSalary);
}
else
{
SqlParameterparameterHourlyPay = newSqlParameter
{
ParameterName = "@Semester",
Value = ((Student)person).Smester,
};
cmd.Parameters.Add(parameterHourlyPay);
SqlParameterparameterHoursWorked = newSqlParameter
{
ParameterName = "@Marks",
Value = ((Student)person).Marks
};
cmd.Parameters.Add(parameterHoursWorked);
}
con.Open();
cmd.ExecuteNonQuery();
}
}
}
}WebForm1.aspx
tablestyle="font-family: Arial; border: 1px solid black;">
tr
td
bID</b
</td
td
asp:TextBoxID="txtID"runat="server">
</asp:TextBox
</td
</tr
tr
td
bName</b
</td
td
asp:TextBoxID="txtName"runat="server">
</asp:TextBox
</td
</tr
tr
td
bGender</b
</td
td
asp:TextBoxID="txtGender"runat="server">
</asp:TextBox
</td
</tr
tr
td
bDate Of Birth</b
</td
td
asp:TextBoxID="txtDateOfBirth"runat="server">
</asp:TextBox
</td
</tr
tr
td
bPerson Type</b
</td
td
asp:DropDownListID="ddlEmployeeType"runat="server"
OnSelectedIndexChanged="ddlEmployeeType_SelectedIndexChanged"
AutoPostBack="True">
asp:ListItemText="Select Person Type"Value="-1">
</asp:ListItem
asp:ListItemText="Teacher"Value="1">
</asp:ListItem
asp:ListItemText="Student"Value="2">
</asp:ListItem
</asp:DropDownList
</td
</tr
trid="trAnnualSalary"runat="server"visible="false">
td
bSalary</b
</td
td
asp:TextBoxID="txtAnnualSalary"runat="server">
</asp:TextBox
</td
</tr
trid="trHourlPay"runat="server"visible="false">
td
bSmester</b
</td
td
asp:TextBoxID="txtHourlyPay"runat="server">
</asp:TextBox
</td
</tr
trid="trHoursWorked"runat="server"visible="false">
td
bMarks</b
</td
td
asp:TextBoxID="txtHoursWorked"runat="server">
</asp:TextBox
</td
</tr
tr
td
asp:ButtonID="btnGet"runat="server"
Text="Get PErson"OnClick="btnGet_Click"/>
</td
td
asp:ButtonID="btnSave"runat="server"
Text="Save Person"OnClick="btnSave_Click"/>
</td
</tr
tr
tdcolspan="2">
asp:LabelID="lblMessage"runat="server"
ForeColor="Green"Font-Bold="true">
</asp:Label
</td
</tr
</table
WebForm1.aspx.cs
protectedvoidbtnGet_Click(object sender, EventArgs e)
{
AcademicService.AcademicServiceClient client =
newAcademicService.AcademicServiceClient();
AcademicService.Person person =
client.GetPerson(Convert.ToInt32(txtID.Text));
if (person.Type == AcademicService.PersonType.Teacher)
{
txtAnnualSalary.Text =
((AcademicService.Teacher)person).Salary.ToString();
trAnnualSalary.Visible = true;
trHourlPay.Visible = false;
trHoursWorked.Visible = false;
}
else
{
txtHourlyPay.Text =
((AcademicService.Student)person).Smester.ToString();
txtHoursWorked.Text =
((AcademicService.Student)person).Marks.ToString();
trAnnualSalary.Visible = false;
trHourlPay.Visible = true;
trHoursWorked.Visible = true;
}
ddlEmployeeType.SelectedValue = ((int)person.Type).ToString();
txtName.Text = person.Name;
txtGender.Text = person.Gender;
txtDateOfBirth.Text = person.DateOfBirth.ToShortDateString();
lblMessage.Text = "Person retrieved";
}
protectedvoidbtnSave_Click(object sender, EventArgs e)
{
AcademicService.AcademicServiceClient client = new
AcademicService.AcademicServiceClient();
AcademicService.Person person = null;
if (((AcademicService.PersonType)Convert.ToInt32(ddlEmployeeType.SelectedValue))
== AcademicService.PersonType.Teacher)
{
person = newAcademicService.Teacher
{
Id = Convert.ToInt32(txtID.Text),
Name = txtName.Text,
Gender = txtGender.Text,
DateOfBirth = Convert.ToDateTime(txtDateOfBirth.Text),
Type = AcademicService.PersonType.Teacher,
Salary = Convert.ToInt32(txtAnnualSalary.Text),
};
client.SavePerson(person);
lblMessage.Text = "Person saved";
}
elseif (((AcademicService.PersonType)Convert.ToInt32(ddlEmployeeType.SelectedValue))
== AcademicService.PersonType.Student)
{
person = newAcademicService.Student
{
Id = Convert.ToInt32(txtID.Text),
Name = txtName.Text,
Gender = txtGender.Text,
DateOfBirth = Convert.ToDateTime(txtDateOfBirth.Text),
Type = AcademicService.PersonType.Student,
Smester = txtHourlyPay.Text,
Marks = Convert.ToInt32(txtHoursWorked.Text),
};
client.SavePerson(person);
lblMessage.Text = "Person saved";
}
else
{
lblMessage.Text = "Please select Employee Type";
}
}
protectedvoidddlEmployeeType_SelectedIndexChanged(object sender, EventArgs e)
{
if (ddlEmployeeType.SelectedValue == "-1")
{
trAnnualSalary.Visible = false;
trHourlPay.Visible = false;
trHoursWorked.Visible = false;
}
elseif (ddlEmployeeType.SelectedValue == "1")
{
trAnnualSalary.Visible = true;
trHourlPay.Visible = false;
trHoursWorked.Visible = false;
}
else
{
trAnnualSalary.Visible = false;
trHourlPay.Visible = true;
trHoursWorked.Visible = true;
}
}
}
}