Веб-ссылка VS2003 для службы WCF имеет дополнительный параметр "IdSpecified"

Я разрабатываю службу WCF с использованием VSTS 2008 +.Net 3.5 + С#, и он отлично работает, когда я также использую VSTS 2008 для разработки клиента (с помощью функции Add Service Reference для автоматически созданного прокси-кода веб-служб клиента). Разработанный WCF использует basicHttpBinding.

Проблема, с которой я столкнулся, заключается в том, что когда я использую Visual Studio.Net(Visual Studio 2003) для создания прокси-кода клиентских веб-сервисов, есть дополнительный входной параметр для метода OperationContract с именем IdSpecified (тип bool). Я проверил, что при указании IdSpecified в true значение параметра Id будет правильно передано на сервер WCF, но когда я укажу IdSpecified на false, независимо от того, какие значения я укажу для параметра Id, на стороне сервера WCF, Id будет всегда 0. Я также пробовал использовать тип входного параметра типа string, на стороне клиента нет такого дополнительного параметра ввода.

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

Здесь Visual Studio.Net автоматически создает прокси-код веб-служб на стороне клиента,

public StudentInfo Poll(int Id, [System.Xml.Serialization.XmlIgnoreAttribute()] bool IdSpecified)

Вот мой код сервера VSTS 2008 WCF,

[OperationContract]
StudentInfo Poll(int Id);

EDIT 1: вот часть автоматически сгенерированного кода на стороне клиента относительно метода опроса.

[return: System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public StudentInfo Poll(int Id, [System.Xml.Serialization.XmlIgnoreAttribute()] bool IdSpecified) {
    object[] results = this.Invoke("Poll", new object[] {
                Id,
                IdSpecified});
    return ((StudentInfo)(results[0]));
}

Ответ 1

Джордж,

Это поведение по дизайну и существует с .NET 1.0. Фактически, если бы вы создали веб-службу ASMX с VS2003 с такой же сигнатурой метода, вы бы нашли тот же результат.

Проблема связана с типами значений, которые отмечены в WSDL как не требуемые. Поскольку они являются типами значений, они не могут вернуть значение null (а VS2003 не имеет типов с нулевым значением). Решение, которое Microsoft реализовало, состояло в том, чтобы добавить отдельное логическое поле или свойство, которое вы можете задать, независимо от того, поставляете ли вы значение.

Это означает, что когда ваше приложение .NET 1.1 хочет вызвать службу, ему необходимо установить параметр IdSpecified:

using (WebReference1.PollService svc = new WebReference1.PollService()) {
    StudentInfo info = svc.Poll(id, true); // True to specify
}

Я не пробовал это, но почему бы вам не сделать:

[DataContract]
public class PollParameters {
    [DataMember(Required = true)]
    public int Id;
}

[OperationContract]
public StudentInfo Poll(PollParameters parameters);

Попробуйте и посмотрите, как выглядит прокси-сервер в VS2003.

Ответ 2

Вы можете попробовать использовать DataContract, а не простой целочисленный параметр. Контракт данных позволяет указать, требуется ли член или нет, который, если требуется член, может удалить этот странный дополнительный bool.