2016-11-10 3 views
0

Я отлаживаю службу wcf, которая в основном подключается к моему sql db, собирает данные и возвращает данные в списках (к вызывающему, когда вызывается, то есть). Тем не менее, мой клиент (вызывающий) получает нулевые данные, хотя, когда я просматриваю код wcf, он возвращает данные.Вызов службы WCF возвращает данные, но приемник получает нуль

Вот код клиента, который вызывает вызов службы wcf. Обратите внимание, что здесь, когда я поставил точку останова и посмотреть на

GetServerUpdatesSyncOthers

после возвращения вызова, мои списки все нуль, когда они не должны быть (да клиент в VB. чистый, но обслуживание ФОС в C#)

Dim svc As PocketPCServerClient = GetServiceClient() 

    Dim updates As ServerUpdatesSyncDTO = svc.GetServerUpdatesSyncOthers(myDeviceId, timestamps.ToArray, operatorName, Me.IdMethodName(idMethod), idMethodValue, destinationHub, withLocationGroup) 

Для записи, ServerUpdatesSyncDTO выглядит это на стороне клиента:

<DataContract()> 
Public Class ServerUpdatesSyncDTO 
Public Const EMPLOYEES_PROCESS_MAXIMUM_NONE As Integer = 0 
Public Const EMPLOYEES_PROCESS_MAXIMUM_ALL As Integer = -1 

<DataMember()> 
Public Property SystemDateTimeUtc As DateTime 
<DataMember()> 
Public Property SyncTimestamps As List(Of SyncTimestampDTO) 
<DataMember()> 
Public Property DeviceSettings As List(Of DeviceSettingDTO) 
<DataMember()> 
Public Property Couriers As List(Of CourierDTO) 
<DataMember()> 
Public Property Validation As List(Of ValidationDTO) 
<DataMember()> 
Public Property NameVariants As List(Of String) 
<DataMember()> 
Public Property NameScrubs As List(Of String) 
<DataMember()> 
Public Property Notes As List(Of String) 
<DataMember()> 
Public Property Notifications As List(Of NotifyDTO) 
<DataMember()> 
Public Property Locations As List(Of LocationDTO) 
<DataMember()> 
Public Property UpsValids As List(Of UpsValidDTO) 
<DataMember()> 
Public Property StatusCodes As List(Of StatusCodeDTO) 
<DataMember()> 
Public Property HubRecon As List(Of String) 
<DataMember()> 
Public Property HubNames As List(Of String) 
<DataMember()> 
Public Property ExtCustomFieldNames As CustomFieldHeadersDTO 
<DataMember()> 
Public Property HoldPickupLocations As List(Of HoldPickupDTO) 
<DataMember()> 
Public Property EmployeeUpdates As List(Of EmployeeDTO) 
<DataMember()> 
Public Property EmployeeInserts As List(Of EmployeeDTO) 
<DataMember()> 
Public Property EmployeeDeletes As List(Of EmployeeDTO) 
<DataMember()> 
Public Property EmployeesProcessMore As Boolean 
<DataMember()> 
Public Property EmployeesProcessMoreIdGreaterThan As String 
End Class 

А на стороне службы WCF, С # версия ServerUpdatesSyncDTO:

[DataContract] 
public class ServerUpdatesSyncDTO 
{ 
    public const int EMPLOYEES_PROCESS_MAXIMUM_NONE = 0; 
    public const int EMPLOYEES_PROCESS_MAXIMUM_ALL = -1; 

     [DataMember] 
     public DateTime SystemDateTimeUtc { get; set; } 
     [DataMember] 
     public List<SyncTimestampDTO> SyncTimestamps { get; set; } 
     [DataMember] 
     public List<DeviceSettingDTO> DeviceSettings { get; set; } 
     [DataMember] 
     public List<CourierDTO> Couriers { get; set; } 
     [DataMember] 
     public List<ValidationDTO> Validation { get; set; } 
     [DataMember] 
     public List<string> NameVariants { get; set; } 
     [DataMember] 
     public List<string> NameScrubs { get; set; } 
     [DataMember] 
     public List<string> Notes { get; set; } 
     [DataMember] 
     public List<NotifyDTO> Notifications { get; set; } 
     [DataMember] 
     public List<LocationDTO> Locations { get; set; } 
     [DataMember] 
     public List<UpsValidDTO> UpsValids { get; set; } 
     [DataMember] 
     public List<StatusCodeDTO> StatusCodes { get; set; } 
     [DataMember] 
     public List<EmployeeDTO> EmployeeUpdates { get; set; } 
     [DataMember] 
     public List<EmployeeDTO> EmployeeInserts { get; set; } 
     [DataMember] 
     public List<EmployeeDTO> EmployeeDeletes { get; set; } 
     [DataMember] 
     public bool EmployeesProcessMore { get; set; } 
     [DataMember] 
     public string EmployeesProcessMoreIdGreaterThan { get; set; } 
     [DataMember] 
     public List<string> HubRecon { get; set; } 
     [DataMember] 
     public List<string> HubNames { get; set; } 
     [DataMember] 
     public CustomFieldHeadersDTO ExtCustomFieldNames { get; set; } 
     [DataMember] 
     public List<HoldPickupDTO> HoldPickupLocations { get; set; } 
    } 

Наконец, метод службы WCF, которая вызывается клиентом. Имейте в виду, я могу установить точку останова здесь и пройти, и я вижу, что этот метод возвращает достоверные данные, без исключений, каждый раз. Например, один из элементов, список курьеров. У меня есть 48 из них в моем списке на стороне wcf, когда он возвращается, но клиент показывает null для Couriers в «обновлениях» после возврата вызова.

public ServerUpdatesSyncDTO GetServerUpdatesSyncOthers(string deviceId, List<SyncTimestampDTO> syncTimestamps, string operatorName, string locationCriteriaType, string locationCriteria, string destinationHub, bool withLocationGroup) 
    { 
     var thisMethodName = MethodBase.GetCurrentMethod().Name; 
     CurrentTaskName = thisMethodName; 
     CurrentDeviceId = deviceId; 

     if (string.IsNullOrWhiteSpace(deviceId)) 
      throw new FaultException(string.Format("Argument null [{0}]", "deviceId")); 
     if (syncTimestamps == null) 
      throw new FaultException(string.Format("Argument null [{0}]", "syncTimestamps")); 
     if (string.IsNullOrWhiteSpace(operatorName)) 
      throw new FaultException(string.Format("Argument null [{0}]", "operatorName")); 
     if (locationCriteriaType.ToUpper() != LOCATION_ID_METHOD_BY_EMPLOYEE && locationCriteriaType.ToUpper() != LOCATION_ID_METHOD_BY_NAME) 
      throw new FaultException(string.Format("locationCriteriaType [{0}] is invalid. Valid values are {1} or {2}", locationCriteriaType, LOCATION_ID_METHOD_BY_EMPLOYEE, LOCATION_ID_METHOD_BY_NAME)); 
     if (string.IsNullOrWhiteSpace(locationCriteria) & locationCriteriaType != LOCATION_ID_METHOD_BY_EMPLOYEE) 
      throw new FaultException(string.Format("Argument null [{0}]", "locationCriteria")); 

     var result = new ServerUpdatesSyncDTO(); 

     try 
     { 
      WriteServerLog(SERVER_TASK_BEGIN); 
      using (var conn = GetSQLConnection()) 
      { 
       var homeLocationCode = 0; 
       var loginLocationCode = 0; 
       List<int> groupLocationCodes; 

       if ((locationCriteriaType == LOCATION_ID_METHOD_BY_EMPLOYEE) && (string.IsNullOrWhiteSpace(locationCriteria))) 
       { 
        locationCriteria = operatorName; 
       } 

       loginLocationCode = GetLocationCode(conn, null, locationCriteriaType, locationCriteria); 
       groupLocationCodes = GetGroupLocationCodes(conn, null, loginLocationCode); 

       if (locationCriteriaType == LOCATION_ID_METHOD_BY_EMPLOYEE) 
       { 
        homeLocationCode = loginLocationCode; 
       } 
       else 
       { 
        homeLocationCode = GetLocationCode(conn, null, LOCATION_ID_METHOD_BY_EMPLOYEE, operatorName); 
       } 

       var lastUpdateUtc = GetLocationSyncDateTimeUtc(loginLocationCode, syncTimestamps); 
       result.Couriers = GetCourierUpdates(conn, lastUpdateUtc, loginLocationCode); 
       result.Validation = GetValidationUpdates(conn, lastUpdateUtc, loginLocationCode); 
       result.HubNames = GetHubNames(conn, lastUpdateUtc, loginLocationCode); 

       result.NameVariants = GetNameVariantUpdates(conn, lastUpdateUtc); 
       result.NameScrubs = GetNameScrubUpdates(conn, lastUpdateUtc); 
       result.Notes = GetNotesUpdates(conn, loginLocationCode); 
       result.Notifications = GetNotifyUpdates(conn, lastUpdateUtc); 
       result.Locations = GetLocationUpdates(conn, lastUpdateUtc); 
       result.UpsValids = GetUpsValidUpdates(conn, lastUpdateUtc); 
       result.StatusCodes = GetStatusCodeUpdates(conn, lastUpdateUtc); 
       result.ExtCustomFieldNames = GetExtendedCustomFieldHeaderUpdates(conn, lastUpdateUtc); 

       if (Properties.Settings.Default.HoldForPickupUpdates) 
       { 
        result.HoldPickupLocations = GetHoldPickupUpdates(conn); 
       } 
       else 
       { 
        result.HoldPickupLocations = new List<HoldPickupDTO>(); 
       } 

       if (!string.IsNullOrWhiteSpace(destinationHub)) 
       { 
        result.HubRecon = GetHubReconUpdates(conn, destinationHub); 
       } 
       else 
       { 
        result.HubRecon = new List<string>(); 
       } 

       result.DeviceSettings = GetDeviceSettingUpdates(conn, loginLocationCode, deviceId); 

       result.SystemDateTimeUtc = DateTime.Now.ToUniversalTime(); 
       result.SyncTimestamps = GetSyncTimestampUpdates(result.SystemDateTimeUtc, syncTimestamps, loginLocationCode, groupLocationCodes, withLocationGroup); 

      } 

      WriteServerLog(SERVER_TASK_COMPLETE, true, true); 
      return result; 

     } 
     catch (FaultException ex) 
     { 
      throw ex; 
     } 
     catch (Exception ex) 
     { 
      string exText = FormatException(ex, string.Format("{0}:{1}", Assembly.GetExecutingAssembly().GetName().Name, thisMethodName)); 
      WriteServerLog(thisMethodName, ServerLogDTO.LogTypeEnum.Critical, exText, ServerLogDTO.EventDataFormatEnum.MultilineText); 
      throw new FaultException(exText); 
     } 
    } 

Итак, я полагаю, что в то время как это должно быть хорошо для клиента, чтобы быть В.Б и услуга ФОС, должна быть какая-то несоответствие, что VB не любит, когда он получает возвращаемые данные? Я просто этого не вижу. Типы данных все одинаковы, и они оба являются списками.

Заранее благодарим за помощь!

+0

Моя рекомендация состоит в том, чтобы создать образцы данных и сериализовать их в xml с помощью vat datacontract ....затем возьмите те же данные и сериализуйте их в xml с помощью C# datacontract .... затем получите инструмент diff и сравните xml, если они разные, вам нужно будет внести изменения в свои контракты, чтобы сделать их одинаковыми – Mick

+0

Также есть причина, по которой вы не создали библиотеку классов для своего datacontract, а затем ссылались на эту сборку на своем клиенте, а не на дублирование datacontract? – Mick

+0

Мик, спасибо за предложение, имеет прекрасный смысл, попробует сейчас. Я предполагаю что-то вроде этого http://stackoverflow.com/questions/11142280/how-to-serialize-deserialize-ac-sharp-wcf-datacontract-to-from-xml –

ответ

0

Я нашел проблему. Как правило, клиент имеет ссылку на службу с помощью службы wcf, где он может вывести WSDL из службы и создать для вас класс клиента. Для этого перейдите в раздел Ссылки> Добавить ссылку на службу и укажите адрес веб-службы.

Есть две вещи, которые следует отметить с этим, оба из которых были проблемой для меня. 1. Вы можете щелкнуть правой кнопкой мыши ссылку на службу и выполнить обновление. Это приведет к отключению и обновлению служебной ссылки. Это необходимо, если в службу WCF были внесены изменения, чтобы клиенты, ссылающиеся на указанную службу, также обновлялись. В противном случае интерфейс будет отличаться, и все не будет работать. 2. Когда вы добавляете или редактируете ссылку на службу, есть варианты выбора типа используемых вами коллекций. По умолчанию мой был выбран как массивы. Однако в службе WCF я не использовал массивы, а скорее списки. Если существует несоответствие с кодом службы/клиента, коллекции будут нарушены. Если вы обновите ссылку на службу, вы должны получить предупреждения, но в моем случае я также не обновил ссылку на службу.

Поэтому после того, как я обновил ссылку на службу, я также выбрал, что использовал списки, а не массивы. После этого все работает так, как ожидалось.

Надеюсь, это поможет.

Смежные вопросы