WCF-сервис Powershell всегда имеет свойство DateTime.Min (01.01.0001)

Я обнаружил странное поведение вызова службы WCF из скрипта Powershell. Используя команду "New-WebServiceProxy" из Powershell 2.0, вы получаете возможность отправлять запросы в веб-службу из сценария PS. Но у меня есть некоторые проблемы с объектами System.DateTime на стороне сервиса, значение на стороне сервера всегда DateTime.Min.

Поэтому я создал небольшой тестовый сервис сценарий и могу воспроизвести эту ошибку. Я использовал "стандартный" WCF-проект из VS2010 и расширил класс "DataContract" свойством DateTime:

[DataContract]
public class CompositeType
{
    bool boolValue = true;
    string stringValue = "Hello ";

    [DataMember]
    public bool BoolValue
    {
        get { return boolValue; }
        set { boolValue = value; }
    }

    [DataMember]
    public string StringValue
    {
        get { return stringValue; }
        set { stringValue = value; }
    }

    [DataMember]
    public DateTime Datum { get; set; }
} 

Скрипт Powershell для вызова сервиса:

cls 
$serv = New-WebServiceProxy  -uri 'http://localhost:50176/TestService.svc?wsdl' -     Namespace wt
$data = [wt.CompositeType](New-Object wt.CompositeType)
$data.StringValue = "abcd"
$data.BoolValue = $true
$data.Datum = Get-Date
$serv.GetDataUsingDataContract($data)

При необходимости я могу выслать вам ссылку на Dropbox для заархивированного проекта.

С уважением Уве

1 ответ

Решение

Раньше я никогда не использовал PowerShell, но подумал, что давно поищу этот вопрос!

Прокси-объект $ data может иметь свойство date, но, несмотря на то, что ваш код выглядит так, как он делает, $data - это не реальный объект, а его XML-прокси.

Если вы введете команду "$data", вы увидите, что выглядит как версия объекта XmlSerialized (имеет свойства xxSpecified для bool и DateTime). Он отражает изменения, сделанные, например, "$data.Datum = Get-Date".

Прокси десериализован обратно к экземпляру MyCompositeType, когда вы вызываете GetUsingDataContract (так как он передается в качестве параметра и отправляется с использованием XML), что вы можете увидеть, установив контрольные точки в свойстве get / setters перед его вызовом.

Как часть этой десериализации, только StringValue делает это, потому что сериализация Xml для других свойств будет включать только те значения, для которых "xxxSpecified" имеет значение true.

Если вы установите свойства "xxxSpecified" в прокси, они будут корректно сериализованы.

Но лучшее решение - изменить их атрибут DataMember на:

[DataMember(IsRequired=true)]

Который должен просто работать с кодом, который вы получили.

Другие вопросы по тегам