2015-11-25 7 views
4

Мне дали wsdl, и мне нужно создать веб-сервис, следуя его спецификациям; Я использую Visual Studio 2010. Среди других есть также определение этого сложного типа:Webservice - Как передать информацию о часовом поясе в элементе datetime

<xsd:complexType name="Person"> 
     <xsd:sequence> 
      <xsd:element name="surname" type="xsd:string"/> 
      <xsd:element name="name" type="xsd:string"/> 
      <xsd:element name="birthDate" nillable="true" type="xsd:dateTime"/> 
     </xsd:sequence> 
    </xsd:complexType> 

Использование VS я получил следующий CS (я не помню exaclty, как я сделал, но я следовал инструкциям найдено в Интернете):

/// <remarks/> 
    [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.1")] 
    [System.SerializableAttribute()] 
    [System.Diagnostics.DebuggerStepThroughAttribute()] 
    [System.ComponentModel.DesignerCategoryAttribute("code")] 
    [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://XXX/Submitter/")] 
    public partial class Person { 
     private string surnameField; 
     private string nameField; 
     private System.Nullable<System.DateTime> birthDateField; 

     /// <remarks/> 
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)] 
     public string surname { 
      get { 
       return this.surnameField; 
      } 
      set { 
       this.surnameField = value; 
      } 
     } 
     /// <remarks/> 
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)] 
     public string name { 
      get { 
       return this.nameField; 
      } 
      set { 
       this.nameField = value; 
      } 
     } 
     /// <remarks/> 
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=true)] 
     public System.Nullable<System.DateTime> birthDate { 
      get { 
       return this.birthDateField; 
      } 
      set { 
       this.birthDateField = value; 
      } 
     } 

И все правильно: оно компилируется, запускается и дает ожидаемый результат; Единственная проблема заключается в том, что другая сторона, которая дала мне WSDL, при вызове моего веб-сервиса, рассчитывает получить поле РОЖДЕНИЯ, как

2013-02-15T17:28:00+01:00 

с информацией о часовом поясе, в то время как результат они получают, как

2015-11-17T18:30:11 

без временной зоны.

Моя проблема в том, что у меня есть тип DateTime?, и это тот, который я передаю моему объекту, созданному из класса; следует ли переопределять сериализацию или есть другое наиболее распространенное решение? Спасибо

+0

DateTime в порядке. Но он не содержит информацию о часовом поясе, поэтому вам придется хранить это отдельно. Возможно, вы захотите проверить объект DateTimeOffset. Вам нужно будет ответить на несколько вопросов для себя, чтобы правильно отправить правильную информацию ... Каков часовой пояс относительно? (т. е. клиент? ваш сервер? какое-то другое место?) И какой часовой пояс для даты, которую вы отправляете (если это не UTC), потому что вам нужно будет конвертировать. – MutantNinjaCodeMonkey

+0

@MutantNinjaCodeMonkey Моя проблема заключается не в том, как получить часовую зону, более того, поскольку это будет специальная интеграция, предназначенная только для одного клиента здесь, в Италии, и часовой пояс будет относиться к клиенту и серверу в том же здании (больничная среда). Моя текущая проблема заключается в том, как передавать эту информацию, когда wsdl говорит, что это должно быть дата и время, тип данных, не содержащий информацию о часовом поясе; Я даже не уверен, что смогу ... – Simone

ответ

2

К сожалению, существует значительное несоответствие между XSD и какие .NET поддерживает в веб-сервисов SOAP.

. NET имеет только два типа для такого рода информации - DateTime и DateTimeOffset. Технически было бы лучше, если бы xs:datetime сопоставил DateTimeOffset, но это не так, как это работает. Вместо этого xs:datetime сопоставляется с DateTime и в значительной степени зависит от свойства Kind значения, чтобы определить, как он сериализуется.

  • Когда DateTime.Kind является DateTimeKind.Unspecified, передается без смещения информации.

  • Когда DateTime.Kind является DateTimeKind.Utc, то Z передается, который является таким же, как +00:00.

  • Когда DateTime.Kind является DateTimeKind.Local, то передается местное смещение, соответствующее данной дате.

Вы можете применить вид с помощью DateTime.SpecifyKind, или если вы хотите, чтобы преобразовать значение в этом процессе, вы можете использовать .ToUniversalTime() или .ToLocalTime(). Или, если вы знаете, что значения относятся к определенному часовому поясу, вы можете использовать методы преобразования из объекта TimeZoneInfo. Если в результате получится что-то другое, кроме Unspecified, оно будет содержать смещение.

К сожалению, опцион не указан Произвольный офсет. Для этого потребуется тип DateTimeOffset, который не поддерживается службами SOAP.

Также учтите, что действительно тип xs:datetime является неправильным типом даты рождения. Он должен использовать xs:date, который является только датой, такой как "2013-02-15". В настоящее время нет такого типа, который поддерживает это в .NET, хотя в ближайшее время он появится, как Date в пакете System.Time в пакете corefxlab. Это будет полезно для таких сценариев, но это еще предстоит выяснить, если мы сможем вернуться и исправить сериализаторы SOAP для их использования.

Действительно, лучшая идея - не использовать XML и SOAP. Создайте свои веб-сервисы вокруг JSON и REST. Там вы можете полностью контролировать такие вещи.

+0

Отлично! Спасибо Мэтту – Simone

0

Возможно, вам стоит взглянуть на answer Jon Skeet. Он предлагает структуру, как это:

public struct DateTimeWithZone 
{ 
    private readonly DateTime utcDateTime; 
    private readonly TimeZoneInfo timeZone; 

    public DateTimeWithZone(DateTime dateTime, TimeZoneInfo timeZone) 
    { 
     utcDateTime = TimeZoneInfo.ConvertTimeToUtc(dateTime, timeZone); 
     this.timeZone = timeZone; 
    } 

    public DateTime UniversalTime { get { return utcDateTime; } } 

    public TimeZoneInfo TimeZone { get { return timeZone; } } 

    public DateTime LocalTime 
    { 
     get 
     { 
      return TimeZoneInfo.ConvertTime(utcDateTime, timeZone); 
     } 
    }   
} 
+0

Моя проблема заключается не в том, чтобы получить правильное время, связанное с часовым поясом, а скорее поместить эту информацию (часовой пояс) в данные datetime, которые я передаю, когда вызывается веб-сервис. Для того, что я понял, это решение просто корректирует дату и время, используя tiemezoneinfo. В любом случае завтра утром я попробую, когда другая сторона будет присутствовать :) – Simone

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