Здравствуйте.
Использую WCF для постороения распределенного приложения. Появилась проблема при передаче между клиентом и сервером сложного объекта.
Описание объекта:
Teacher
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
namespace TestCenter.BaseDatatype
{
[DataContract]
public class Teacher : User
{
[DataMember]
private Department department = new Department();
public Teacher()
{
this.pKey = -1;
}
public virtual Department Department { get; set;}
}
}
Department
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
namespace TestCenter.BaseDatatype
{
[DataContract]
public class Department : GroupGeneric
{
public Department()
{
pKey = -1;
}
public Department(int pKey, string name, string description)
{
this.pKey = pKey;
this.name = name;
this.description = description;
}
}
}
GroupGeneric
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using TestCenter.BaseDatatype;
namespace TestCenter.BaseDatatype
{
[DataContract]
[KnownType(typeof(Group))]
[KnownType(typeof(Department))]
public abstract class GroupGeneric
{
[DataMember]
protected int pKey;
[DataMember]
protected string name;
[DataMember]
protected string description;
[IgnoreDataMember]
static string valueMember = "PKey";
[IgnoreDataMember]
static string displayMember = "Name";
public virtual int PKey
{
get { return pKey; }
set { pKey = value; }
}
public virtual string Name
{
get { return name; }
set { name = value; }
}
public virtual string Description
{
get { return description; }
set { description = value; }
}
public static string DisplayMember
{
get { return GroupGeneric.displayMember; }
set { GroupGeneric.displayMember = value; }
}
public static string ValueMember
{
get { return GroupGeneric.valueMember; }
set { GroupGeneric.valueMember = value; }
}
static IEnumerable<Type> GetKnownTypes()
{
return new Type[] { typeof(Group), typeof(Department) };
}
}
}
описание серверной части
ITestCenterService
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using TestCenter.BaseDatatype;
using TestCenter;
using TestCenter.BaseDatatype.SingleChoice;
namespace TestCenter.BaseDatatype.Service
{
[ServiceContract(ProtectionLevel = System.Net.Security.ProtectionLevel.EncryptAndSign)]
public interface ITestCenterService
{
[OperationContract(ProtectionLevel = System.Net.Security.ProtectionLevel.EncryptAndSign)]
//[FaultContract(typeof(TrackedFault))]
Teacher AuthenticateTeacher(Credentials credentials);
}
}
TestCenterService
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
namespace TestCenterServiceLib
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple, IncludeExceptionDetailInFaults = false)]
[System.Security.SecurityCritical(System.Security.SecurityCriticalScope.Everything)]
public class TestCenterService : ITestCenterService
{
public Teacher AuthenticateTeacher(Credentials credentials)
{
//NHibernateAuthentification
using (var session = GetSessionFactory().OpenSession())
{
using (var tx = session.BeginTransaction())
{
Teacher teacherrrrr = null;
try
{
var teachers = from teacherr in session.Query<Teacher>()
where teacherr.Credentials.Login == credentials.Login
where teacherr.Credentials.Password == credentials.Password
select teacherr;
teacherrrrr = teachers.First();
tx.Commit();
OperationContext context = OperationContext.Current;
MessageProperties messageProperties = context.IncomingMessageProperties;
RemoteEndpointMessageProperty endpointProperty = messageProperties[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty;
string strHostName = Dns.GetHostEntry(endpointProperty.Address).HostName;
string name = teacherrrrr.FirstName + " " + teacherrrrr.SecondName + " " + teacherrrrr.LastName;
//!!!!!!!!!!!!!!!!!!!!//OnAuthUser(new AuthUserEventArgs(student, strHostName));
}
catch (InvalidOperationException ex)
{
TrackedFault tf = new TrackedFault(
Guid.NewGuid(),
"Відповідь сервера:"
+ System.Environment.NewLine
+ System.Environment.NewLine
+ "user with login '" + credentials.Login + "' and current password not found",
DateTime.Now);
throw new FaultException<TrackedFault>(
tf,
new FaultReason("InvalidOperationException"),
FaultCode.CreateReceiverFaultCode(new FaultCode("AuthenticateStudent")));
}
catch (FaultException ex)
{
List<FaultReasonText> frts = new List<FaultReasonText>();
frts.Add(new FaultReasonText(
"Відповідь сервера:"
+ System.Environment.NewLine
+ System.Environment.NewLine
+ "Помилка аутентифікації"));
throw new FaultException(new FaultReason(frts),
FaultCode.CreateReceiverFaultCode(new FaultCode("AuthenticateStudent")));
}
return teacherrrrr;
}
}
//NHibernateAuthentification
}
}
вызов на стороне клиента производится следующим образом
TeacherSideProxy
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
namespace TeacherSide
{
class TeacherSideProxy
{
private static void GetClientChannel(out ChannelFactory<ITestCenterService> channel, out ITestCenterService client)
{
NetTcpBinding binding = new NetTcpBinding() ;
binding.Security.Mode = SecurityMode.Transport;
Uri uri = new Uri(@"net.tcp://" + Settings.Default.ServerName + ":" + Settings.Default.ServerPort.ToString() + "/TestCenterServiceLib");
channel = new ChannelFactory<ITestCenterService>(binding, new EndpointAddress(uri.ToString()));
//channel.Credentials.ServiceCertificate
client = channel.CreateChannel();
}
internal static Teacher AuthenticateTeacher(Teacher user)
{
ChannelFactory<ITestCenterService> channel;
ITestCenterService client;
GetClientChannel(out channel, out client);
Teacher teacher = null;
try
{
teacher = client.AuthenticateTeacher(user.Credentials);
}
catch (FaultException<TrackedFault> tfexp)
{
throw new ServerErrorException(tfexp.Detail.Details);
}
catch (FaultException fex)
{
throw new ServerErrorException(fex.Message);
}
catch (EndpointNotFoundException ex)
{
throw new ServerNotFoundException("Помилка доступу до сервера");
}
catch (CommunicationException ex)
{
throw new ServerDisconnectedException("Сервер перервав зв'язок");
}
catch (TimeoutException ex)
{
throw new TimeoutException("Час очікування відповіді серевера закінчився");
}
finally
{
if (channel != null)
{
channel.Close();
}
}
return teacher;
}
}
}
Проблема вся в том, что на стороне сервера данные полные, а клиенту приходит объект, у которого значения поля Department равно null.
В чем проблема и как можно решить ее?
Надеюсь на помощь. Спасибо