Разное поведение между «Справочником услуг» и «Справочником по сети» - PullRequest
3 голосов
/ 15 июля 2009

У меня есть конечная точка WCF, как указано ниже,

<service name="MyApp.Server.Endpoint.Orange" behaviorConfiguration="MyTio.Server.Endpoint.OrangeBehavior">
  <endpoint address="" binding="basicHttpBinding" contract="Host.Server.Contract.IMyAppApi" bindingNamespace="http://host.com/myapp">
    <identity>
      <dns value="localhost"/>
    </identity>
  </endpoint>
  <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>

когда я добавляю «Service Refrence» в .NET 3.5, мы получаем следующий класс в прокси, который прекрасно работает:

    [System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="GetMemberBillersRequest", Namespace="http://schemas.datacontract.org/2004/07/Contract.MemberBillers")]
[System.SerializableAttribute()]
public partial class GetMemberBillersRequest : WCFClient.MyRequest {

    [System.Runtime.Serialization.OptionalFieldAttribute()]
    private int ApplicationIdField;

    [System.Runtime.Serialization.OptionalFieldAttribute()]
    private int ProductIdField;

    [System.Runtime.Serialization.DataMemberAttribute()]
    public int ApplicationId {
        get {
            return this.ApplicationIdField;
        }
        set {
            if ((this.ApplicationIdField.Equals(value) != true)) {
                this.ApplicationIdField = value;
                this.RaisePropertyChanged("ApplicationId");
            }
        }
    }

    [System.Runtime.Serialization.DataMemberAttribute()]
    public int ProductId {
        get {
            return this.ProductIdField;
        }
        set {
            if ((this.ProductIdField.Equals(value) != true)) {
                this.ProductIdField = value;
                this.RaisePropertyChanged("ProductId");
            }
        }
    }
}

проблема в том, что вы добавляете ссылку на тот же сервис, но в .NET 2.0

вы получаете следующий прокси для того же контракта:

    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "2.0.50727.3082")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://schemas.datacontract.org/2004/07/Contract.MemberBillers")]
public partial class GetMemberBillersRequest : MyRequest {

    private int applicationIdField;

    private bool applicationIdFieldSpecified;

    private int productIdField;

    private bool productIdFieldSpecified;

    /// <remarks/>
    public int ApplicationId {
        get {
            return this.applicationIdField;
        }
        set {
            this.applicationIdField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool ApplicationIdSpecified {
        get {
            return this.applicationIdFieldSpecified;
        }
        set {
            this.applicationIdFieldSpecified = value;
        }
    }

    /// <remarks/>
    public int ProductId {
        get {
            return this.productIdField;
        }
        set {
            this.productIdField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool ProductIdSpecified {
        get {
            return this.productIdFieldSpecified;
        }
        set {
            this.productIdFieldSpecified = value;
        }
    }
}

оба идентичны, за исключением того, что прокси, сгенерированный через .NET 2.0, имеет два дополнительных поля:

productIdFieldSpecified и applicationIdFieldSpecified. проблема с этими двумя полями состоит в том, что если вы не установите их вручную в значение true, соответствующие поля (ApplicationId, ProductId) не будут сериализованы и переданы на сервер!

Может кто-нибудь объяснить мне, что здесь происходит?

EDIT:

Я обнаружил, что это происходит только для типов int, а не для строк! вот данные договора на эту операцию

[DataContract]
public class GetMemberBillersRequest : MyRequest
{
    [DataMember]
    public int ApplicationId { get; set; }

    [DataMember]
    public int ProductId { get; set; }
}

Ответы [ 2 ]

3 голосов
/ 15 июля 2009

Это ожидаемое поведение, так было с .NET 1.0. Вы увидите это для любого примитивного типа, который является необязательным в схеме - либо атрибут с use = "option", либо элемент с minOccurs = "0".

Если атрибут или элемент отсутствовали, тогда сгенерированное свойство не может быть установлено в нуль. Вместо этого в поле * указано значение false. Проверьте это поле, прежде чем решить, присутствует ли «настоящий» или нет.

Точно так же, если вы хотите установить основное свойство, тогда вы должны установить для * указанного свойства значение true, иначе оно не будет отправлено.


Я уверен, что вы знаете, но я добавляю это для будущих читателей: Да, сейчас есть типы, которые можно обнулять. Однако с появлением WCF разработка веб-сервисов ASMX значительно замедлилась. Меня не удивляет, что обнуляемые свойства никогда не были реализованы для примитивных типов.

Кроме того, помните об этом: Microsoft: веб-службы ASMX являются «устаревшей технологией» .

1 голос
/ 15 июля 2009

Было бы полезно увидеть ваш сервисный код. Некоторое время я не пользовался ссылками на веб-службы, но полагаю, что если эти поля не являются обязательными, добавьте IsRequired = True в свой атрибут DataMemeber и создайте прокси повторно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...