Я пытаюсь получить список клиентов с сервера (сервер, использующий fluentNHibernate). Объект клиента выглядит следующим образом:
[DataContract]
//[KnownType(typeof(System.Collections.Generic.List<ContactPerson>))]
//[KnownType(typeof(System.Collections.Generic.List<Address>))]
//[KnownType(typeof(System.Collections.Generic.List<BatchRequest>))]
//[KnownType(typeof(System.Collections.Generic.List<Discount>))]
[KnownType(typeof(EClientType))]
[KnownType(typeof(EComType))]
public class Client
{
#region Properties
[DataMember]
public virtual int ClientID { get; set; }
[DataMember]
public virtual EClientType ClientType { get; set; }
[DataMember]
public virtual string RegisterID {get; set;}
[DataMember]
public virtual string HerdCode { get; set; }
[DataMember]
public virtual string CompanyName { get; set; }
[DataMember]
public virtual bool InvoicePerBatch { get; set; }
[DataMember]
public virtual EComType ResultsComType { get; set; }
[DataMember]
public virtual EComType InvoiceComType { get; set; }
//[DataMember]
//public virtual IList<ContactPerson> Contacts { get; set; }
//[DataMember]
//public virtual IList<Address> Addresses { get; set; }
//[DataMember]
//public virtual IList<BatchRequest> Batches { get; set; }
//[DataMember]
//public virtual IList<Discount> Discounts { get; set; }
#endregion
#region Overrides
public override bool Equals(object obj)
{
var other = obj as Client;
if (other == null)
return false;
return other.GetHashCode() == this.GetHashCode();
}
public override int GetHashCode()
{
return ClientID.GetHashCode() | ClientType.GetHashCode() | RegisterID.GetHashCode() |
HerdCode.GetHashCode() | CompanyName.GetHashCode() | InvoicePerBatch.GetHashCode() |
ResultsComType.GetHashCode() | InvoiceComType.GetHashCode();// | Contacts.GetHashCode() |
//Addresses.GetHashCode() | Batches.GetHashCode() | Discounts.GetHashCode();
}
#endregion
}
Я уже пытался удалить подсписки, хотя даже с этой упрощенной версией клиента я все еще сталкиваюсь с проблемой.
Мое свободное отображение:
public class ClientMap : ClassMap<Client>
{
public ClientMap()
{
Table("Clients");
Id(p => p.ClientID);
Map(p => p.ClientType).CustomType<EClientType>(); ;
Map(p => p.RegisterID);
Map(p => p.HerdCode);
Map(p => p.CompanyName);
Map(p => p.InvoicePerBatch);
Map(p => p.ResultsComType).CustomType<EComType>();
Map(p => p.InvoiceComType).CustomType<EComType>();
//HasMany<ContactPerson>(p => p.Contacts)
// .KeyColumns.Add("ContactPersonID")
// .Inverse()
// .Cascade.All();
//HasMany<Address>(p => p.Addresses)
// .KeyColumns.Add("AddressID")
// .Inverse()
// .Cascade.All();
//HasMany<BatchRequest>(p => p.Batches)
// .KeyColumns.Add("BatchID")
// .Inverse()
// .Cascade.All();
//HasMany<Discount>(p => p.Discounts)
// .KeyColumns.Add("DiscountID")
// .Inverse()
// .Cascade.All();
}
Клиентский метод, показанный ниже, подключается к серверу. Сервер получает список, и в объекте все выглядит правильно, тем не менее, когда он возвращается, клиент ничего не получает (он получает объект List, но в нем ничего нет.
При этом метод вызова:
public List<s.Client> GetClientList()
{
try
{
s.DataServiceClient svcClient = new s.DataServiceClient();
svcClient.Open();
List<s.Client> clients = new List<s.Client>();
clients = svcClient.GetClientList().ToList<s.Client>();
svcClient.Close(); //when receiving focus from server, the clients object has a count of 0
return clients;
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
return null;
}
и метод сервера:
public IList<Client> GetClientList()
{
var clients = new List<Client>();
try
{
using (var session = SessionHelper.OpenSession())
{
clients = session.Linq<Client>().Where(p => p.ClientID > 0).ToList<Client>();
}
}
catch (Exception e)
{
EventLog.WriteEntry("eCOWS.Data", e.Message);
}
return clients; //returns a list with 1 client in it
}
Интерфейс метода сервера:
[UseNetDataContractSerializer]
[OperationContract]
IList<Client> GetClientList();
Для окончательной справки, вот мои клиентские записи app.config:
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_IDataService" listenBacklog="10" maxConnections="10"
transferMode="Buffered" transactionProtocol="OleTransactions"
maxReceivedMessageSize="2147483647" maxBufferSize="2147483647"
receiveTimeout="00:10:00" sendTimeout="00:10:00">
<readerQuotas maxDepth="51200000" maxStringContentLength="51200000"
maxArrayLength="51200000" maxBytesPerRead="51200000"
maxNameTableCharCount="51200000" />
<security mode="Transport"/>
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://localhost:9000/eCOWS/DataService"
binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IDataService"
contract="eCowsDataService.IDataService" name="NetTcpBinding_IDataService"
behaviorConfiguration="eCowsEndpointBehavior">
</endpoint>
<endpoint address="MEX"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</client>
<behaviors>
<endpointBehaviors>
<behavior name="eCowsEndpointBehavior">
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
и мой сервер app.config:
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="netTcpBinding"
maxConnections="10" listenBacklog="10"
transferMode="Buffered" transactionProtocol="OleTransactions"
maxBufferSize="2147483647" maxReceivedMessageSize="2147483647"
sendTimeout="00:10:00" receiveTimeout="00:10:00">
<readerQuotas maxDepth="51200000" maxStringContentLength="51200000"
maxArrayLength="51200000" maxBytesPerRead="51200000"
maxNameTableCharCount="51200000" />
<security mode="Transport"/>
</binding>
</netTcpBinding>
</bindings>
<services>
<service name="eCows.Data.Services.DataService" behaviorConfiguration="eCowsServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:9001/eCOWS/" />
<add baseAddress="net.tcp://localhost:9000/eCOWS/" />
</baseAddresses>
</host>
<endpoint address="DataService"
binding="netTcpBinding"
contract="eCows.Data.Services.IDataService"
behaviorConfiguration="eCowsEndpointBehaviour">
</endpoint>
<endpoint address="MEX"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="eCowsEndpointBehaviour">
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="eCowsServiceBehavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceThrottling maxConcurrentCalls="10" maxConcurrentSessions="10"/>
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
<behavior name="MexBehaviour">
<serviceMetadata />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Я использую, чтобы столкнуться с ошибками «сокет закрыт / сеть или тайм-аут», и трассировка ясно показала, что при обратном вызове он искал конечную точку прослушивания, но не смог ее найти. Во всяком случае, после добавления UseNetSerializer эта ошибка исчезла, но теперь я просто ничего не получаю.
PS. Если я добавлю все закомментированные элементы списка, я все равно извлеку запись из БД, но также ничего не получу на клиенте.
Если я удалю [UseNetDataContractSerializer], я получу следующие ошибки в svclog:
ПРЕДУПРЕЖДЕНИЕ. Описание Faulted System.ServiceModel.Channels.ServerSessionPreambleConnectionReader+ServerFramingDuplexSessionChannel
ВНИМАНИЕ: Описание Faulted System.ServiceModel.Channels.ServiceChannel
ОШИБКА: Initializing[eCows.Data.Models.Client#3] — не удалось лениво инициализировать набор ролей: eCows.Data.Models.Client.Addresses, сеанс или сеанс не был закрыт
...
ОШИБКА: не удалось найти элемент конечной точки по умолчанию, который ссылается на контракт «ILogbookManager» в разделе конфигурации клиента ServiceModel. Это может быть связано с тем, что для вашего приложения не найден файл конфигурации или с тем, что в клиентском элементе не удалось найти элемент конечной точки, соответствующий этому контракту.
Если я добавлю .Not.LazyLoad к элементам сопоставления списка, я вернусь к тому, что не буду получать ошибки, но также не буду получать информацию о клиенте.