Aracılığıyla paylaş


İleti Sözleşmeleri Kullanılıyor

Genellikle Windows Communication Foundation (WCF) uygulamaları oluştururken, geliştiriciler veri yapılarına ve serileştirme sorunlarına çok dikkat eder ve verilerin taşındığı iletilerin yapısıyla ilgilenmeleri gerekmez. Bu uygulamalar için parametreler veya dönüş değerleri için veri sözleşmeleri oluşturmak basittir. (Daha fazla bilgi için bkz. Hizmet Sözleşmelerinde Veri Aktarımı belirtme.)

Ancak, bazen SOAP iletisinin yapısı üzerinde tam denetim, içeriği üzerinde denetim kadar önemlidir. Bu, özellikle birlikte çalışabilirlik önemli olduğunda veya güvenlik sorunlarını ileti veya ileti bölümü düzeyinde özellikle denetlemek için geçerlidir. Bu gibi durumlarda, gereken tam SOAP iletisinin yapısını belirtmenize olanak tanıyan bir ileti sözleşmesi oluşturabilirsiniz.

Bu konuda, işleminiz için belirli bir ileti sözleşmesi oluşturmak üzere çeşitli ileti sözleşmesi özniteliklerinin nasıl kullanılacağı açıklanır.

İşlemlerde İleti Sözleşmelerini Kullanma

WCF, uzak yordam çağrısı (RPC) stilinde veya mesajlaşma stilindemodellenen işlemleri destekler. RPC stilinde bir işlemde herhangi bir serileştirilebilir türü kullanabilirsiniz ve birden çok parametre ve refout parametre gibi yerel çağrıların kullanabileceği özelliklere erişebilirsiniz. Bu stilde, seçilen serileştirme biçimi temel alınan iletilerdeki verilerin yapısını denetler ve WCF çalışma zamanı işlemi desteklemek için iletileri oluşturur. Bu, SOAP ve SOAP iletileri hakkında bilgi sahibi olmayan geliştiricilerin hızlı ve kolay bir şekilde hizmet uygulamaları oluşturmasını ve kullanmasını sağlar.

Aşağıdaki kod örneğinde RPC stilinde modellenmiş bir hizmet işlemi gösterilmektedir.

[OperationContract]  
public BankingTransactionResponse PostBankingTransaction(BankingTransaction bt);  

Normalde, bir veri sözleşmesi iletilerin şemasını tanımlamak için yeterlidir. Örneğin, yukarıdaki örnekte, temel alınan SOAP iletilerinin içeriğini tanımlamak için veri sözleşmeleri varsa BankingTransaction ve BankingTransactionResponse varsa çoğu uygulama için yeterlidir. Veri sözleşmeleri hakkında daha fazla bilgi için bkz . Veri Sözleşmelerini Kullanma.

Bununla birlikte, bazen SOAP iletisinin yapısının tel üzerinden nasıl iletilmiş olduğunu hassas bir şekilde kontrol etmek gerekir. Bunun için en yaygın senaryo, özel SOAP üst bilgileri eklemektir. Bir diğer yaygın senaryo, iletinin üst bilgileri ve gövdesi için güvenlik özelliklerini tanımlamaktır, yani bu öğelerin dijital olarak imzalanıp şifrelenmediğine karar vermektir. Son olarak, bazı üçüncü taraf SOAP yığınları iletilerin belirli bir biçimde olmasını gerektirir. Mesajlaşma stili işlemler bu denetimi sağlar.

Mesajlaşma stili bir işlem en fazla bir parametreye ve her iki türün de ileti türü olduğu bir dönüş değerine sahiptir; diğer bir ifadeyle, doğrudan belirli bir SOAP ileti yapısına seri hale getirilir. Bu, veya Message türüyle MessageContractAttribute işaretlenmiş herhangi bir tür olabilir. Aşağıdaki kod örneği, önceki RCP stiline benzer ancak mesajlaşma stilini kullanan bir işlemi gösterir.

Örneğin, ve BankingTransactionResponse her ikisi de ileti sözleşmeleri olan türlerseBankingTransaction, aşağıdaki işlemlerdeki kod geçerlidir.

[OperationContract]  
BankingTransactionResponse Process(BankingTransaction bt);  
[OperationContract]  
void Store(BankingTransaction bt);  
[OperationContract]  
BankingTransactionResponse GetResponse();  

Ancak, aşağıdaki kod geçersiz.

[OperationContract]  
bool Validate(BankingTransaction bt);  
// Invalid, the return type is not a message contract.  
[OperationContract]  
void Reconcile(BankingTransaction bt1, BankingTransaction bt2);  
// Invalid, there is more than one parameter.  

İleti sözleşmesi türü içeren ve geçerli desenlerden birini izlemeyen herhangi bir işlem için özel durum oluşturulur. Elbette, ileti sözleşmesi türlerini içermeyen işlemler bu kısıtlamalara tabi değildir.

Bir türün hem ileti sözleşmesi hem de veri sözleşmesi varsa, bir işlemde tür kullanıldığında yalnızca ileti sözleşmesi dikkate alınır.

İleti Sözleşmelerini Tanımlama

Bir tür için ileti sözleşmesi tanımlamak için (yani, tür ile SOAP zarfı arasındaki eşlemeyi tanımlamak için) türüne uygulayın MessageContractAttribute . Ardından, MessageHeaderAttribute öğesini SOAP üst bilgilerinde oluşturmak istediğiniz türün üyelerine uygulayın ve öğesini iletinin SOAP gövdesinin bölümlerine eklemek istediğiniz üyelere uygulayın MessageBodyMemberAttribute .

Aşağıdaki kod, ileti sözleşmesi kullanma örneği sağlar.

[MessageContract]  
public class BankingTransaction  
{  
  [MessageHeader] public Operation operation;  
  [MessageHeader] public DateTime transactionDate;  
  [MessageBodyMember] private Account sourceAccount;  
  [MessageBodyMember] private Account targetAccount;  
  [MessageBodyMember] public int amount;  
}  

Bu tür bir işlem parametresi olarak kullanılırken aşağıdaki SOAP zarfı oluşturulur:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">  
  <s:Header>  
    <h:operation xmlns:h="http://tempuri.org/" xmlns="http://tempuri.org/">Deposit</h:operation>  
    <h:transactionDate xmlns:h="http://tempuri.org/" xmlns="http://tempuri.org/">2012-02-16T16:10:00</h:transactionDate>  
  </s:Header>  
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">  
    <BankingTransaction xmlns="http://tempuri.org/">  
      <amount>0</amount>  
      <sourceAccount xsi:nil="true"/>  
      <targetAccount xsi:nil="true"/>  
    </BankingTransaction>  
  </s:Body>  
</s:Envelope>  

VE'nin transactionDateoperation SOAP üst bilgileri olarak göründüğüne ve SOAP gövdesinin ,targetAccount ve amountiçeren sourceAccountbir sarmalayıcı öğesinden BankingTransaction oluştuğuna dikkat edin.

genelMessageBodyMemberAttribute, özel, korumalı veya dahili olmasına bakılmaksızın ve'yi tüm alanlara, özelliklere ve olaylarına uygulayabilirsinizMessageHeaderAttribute.

, MessageContractAttribute SOAP iletisinin gövdesindeki sarmalayıcı öğesinin adını denetleyen WrapperName ve WrapperNamespace özniteliklerini belirtmenize olanak tanır. Varsayılan olarak, sarmalayıcı için ileti sözleşmesi türünün adı kullanılır ve ileti sözleşmesinin tanımlandığı http://tempuri.org/ ad alanı varsayılan ad alanı olarak kullanılır.

Not

KnownTypeAttribute öznitelikleri ileti sözleşmelerinde yoksayılır. KnownTypeAttribute gerekirse, söz konusu ileti sözleşmesini kullanan işleme yerleştirin.

Üst Bilgi ve Gövde Bölümü Adlarını ve Ad Alanlarını Denetleme

bir ileti sözleşmesinin SOAP gösteriminde, her üst bilgi ve gövde bölümü bir ada ve ad alanına sahip bir XML öğesiyle eşler.

Varsayılan olarak ad alanı, iletinin katıldığı hizmet sözleşmesinin ad alanıyla aynıdır ve ad, veya MessageBodyMemberAttribute özniteliklerinin uygulandığı üye adı MessageHeaderAttribute tarafından belirlenir.

ve (ve MessageBodyMemberAttributeMessageContractMemberAttribute.Namespace özniteliklerinin üst sınıfındaMessageHeaderAttribute) öğesini işleyerek MessageContractMemberAttribute.Name bu varsayılanları değiştirebilirsiniz.

Aşağıdaki kod örneğinde sınıfını göz önünde bulundurun.

[MessageContract]  
public class BankingTransaction  
{  
  [MessageHeader] public Operation operation;  
  [MessageHeader(Namespace="http://schemas.contoso.com/auditing/2005")] public bool IsAudited;  
  [MessageBodyMember(Name="transactionData")] public BankingTransactionData theData;  
}  

Bu örnekte, IsAudited üst bilgi kodda belirtilen ad alanındadır ve üyeyi temsil theData eden gövde bölümü adlı transactionDatabir XML öğesiyle temsil edilir. Aşağıda, bu ileti sözleşmesi için oluşturulan XML gösterilmektedir.

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">  
  <s:Header>  
    <h:IsAudited xmlns:h="http://schemas.contoso.com/auditing/2005" xmlns="http://schemas.contoso.com/auditing/2005">false</h:IsAudited>  
    <h:operation xmlns:h="http://tempuri.org/" xmlns="http://tempuri.org/">Deposit</h:operation>  
  </s:Header>  
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">  
    <AuditedBankingTransaction xmlns="http://tempuri.org/">  
      <transactionData/>  
    </AuditedBankingTransaction>  
  </s:Body>  
</s:Envelope>  

SOAP Gövde Parçalarının Sarmalanıp Sarmalanmadığını Denetleme

Varsayılan olarak, SOAP gövde parçaları sarmalanmış bir öğenin içinde serileştirilir. Örneğin, aşağıdaki kod iletinin HelloGreetingMessage ileti sözleşmesindeki HelloGreetingMessage türün adından MessageContractAttribute oluşturulan sarmalayıcı öğesini gösterir.

[MessageContract]
public class HelloGreetingMessage
{
  private string localGreeting;

  [MessageBodyMember(
    Name = "Salutations",
    Namespace = "http://www.examples.com"
  )]
  public string Greeting
  {
    get { return localGreeting; }
    set { localGreeting = value; }
  }
}

/*
 The following is the request message, edited for clarity.

  <s:Envelope>
    <s:Header>
      <!-- Note: Some header content has been removed for clarity.
      <a:Action>http://GreetingMessage/Action</a:Action>
      <a:To s:mustUnderstand="1"></a:To>
    </s:Header>
    <s:Body u:Id="_0" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
      <HelloGreetingMessage xmlns="Microsoft.WCF.Documentation">
        <Salutations xmlns="http://www.examples.com">Hello.</Salutations>
      </HelloGreetingMessage>
    </s:Body>
 </s:Envelope>
 */
<MessageContract> _
Public Class HelloGreetingMessage
    Private localGreeting As String

    <MessageBodyMember(Name:="Salutations", Namespace:="http://www.examples.com")> _
    Public Property Greeting() As String
        Get
            Return localGreeting
        End Get
        Set(ByVal value As String)
            localGreeting = value
        End Set
    End Property
End Class

'  
'   The following is the request message, edited for clarity.
'    
'    <s:Envelope>
'      <s:Header>
'        <!-- Note: Some header content has been removed for clarity.
'        <a:Action>http://GreetingMessage/Action</a:Action> 
'        <a:To s:mustUnderstand="1"></a:To>
'      </s:Header>
'      <s:Body u:Id="_0" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
'        <HelloGreetingMessage xmlns="Microsoft.WCF.Documentation">
'          <Salutations xmlns="http://www.examples.com">Hello.</Salutations>
'      </s:Body>
'   </s:Envelope>
'   

Sarmalayıcı öğesini bastırmak için özelliğini olarak falseayarlayınIsWrapped. Sarmalayıcı öğesinin adını ve ad alanını denetlemek için ve WrapperNamespace özelliklerini kullanınWrapperName.

Not

Sarmalanmamış iletilerde birden fazla ileti gövdesi parçasının olması WS-I Temel Profil 1.1 ile uyumlu değildir ve yeni ileti sözleşmeleri tasarlanırken önerilmez. Ancak, belirli birlikte çalışabilirlik senaryolarında birden fazla eşlenmemiş ileti gövdesi parçasına sahip olmak gerekebilir. İleti gövdesinde birden fazla veri aktaracaksanız varsayılan (sarmalanmış) modu kullanmanız önerilir. Eşlenmemiş iletilerde birden fazla ileti üst bilgisinin olması tamamen kabul edilebilir.

İleti Anlaşmaları İçinde Özel Türler Kullanma

Her bir ileti üst bilgisi ve ileti gövdesi bölümü, iletinin kullanıldığı hizmet sözleşmesi için seçilen serileştirme altyapısı kullanılarak serileştirilir (XML'ye dönüştürülür). Varsayılan serileştirme altyapısı olan XmlFormatter, veri sözleşmesine sahip olan herhangi bir türü açıkça ( System.Runtime.Serialization.DataContractAttribute) veya örtük olarak işleyebilir (ilkel bir tür olarak, öğesine sahip olarak System.SerializableAttributevb.). Daha fazla bilgi için bkz . Veri Sözleşmelerini Kullanma.

Yukarıdaki örnekte ve OperationBankingTransactionData türleri bir veri sözleşmesine sahip olmalıdır ve transactionDate serileştirilebilir çünkü DateTime ilkeldir (ve örtük bir veri sözleşmesi vardır).

Ancak, farklı bir serileştirme altyapısına geçmek mümkündür.XmlSerializer Böyle bir anahtar yaparsanız, ileti üst bilgileri ve gövde bölümleri için kullanılan tüm türlerin XmlSerializerkullanılarak serileştirilebilir olduğundan emin olmalısınız.

İleti Anlaşmaları İçinde Dizileri Kullanma

İleti sözleşmelerinde yinelenen öğe dizilerini iki şekilde kullanabilirsiniz.

Birincisi, dizide doğrudan bir MessageHeaderAttribute veya MessageBodyMemberAttribute kullanmaktır. Bu durumda, dizinin tamamı birden çok alt öğe içeren bir öğe (bir üst bilgi veya bir gövde parçası) olarak serileştirilir. Aşağıdaki örnekte sınıfını göz önünde bulundurun.

[MessageContract]  
public class BankingDepositLog  
{  
  [MessageHeader] public int numRecords;  
  [MessageHeader] public DepositRecord[] records;  
  [MessageHeader] public int branchID;  
}  

Bu, SOAP üst bilgileriyle sonuçlanır ve aşağıdakine benzer.

<BankingDepositLog>  
<numRecords>3</numRecords>  
<records>  
  <DepositRecord>Record1</DepositRecord>  
  <DepositRecord>Record2</DepositRecord>  
  <DepositRecord>Record3</DepositRecord>  
</records>  
<branchID>20643</branchID>  
</BankingDepositLog>  

Bunun bir alternatifi de kullanmaktır MessageHeaderArrayAttribute. Bu durumda, her dizi öğesi bağımsız olarak serileştirilir ve böylece her dizi öğesi aşağıdakine benzer bir üst bilgi içerir.

<numRecords>3</numRecords>  
<records>Record1</records>  
<records>Record2</records>  
<records>Record3</records>  
<branchID>20643</branchID>  

Dizi girdileri için varsayılan ad, özniteliklerin uygulandığı üyenin MessageHeaderArrayAttribute adıdır.

MessageHeaderArrayAttribute özniteliği öğesinden devralırMessageHeaderAttribute. Dizi olmayan özniteliklerle aynı özellik kümesine sahiptir; örneğin, bir üst bilgi dizisinin sırasını, adını ve ad alanını, tek bir üst bilgi için ayarladığınız şekilde ayarlamak mümkündür. Bir dizide Order özelliğini kullandığınızda, bu özellik dizinin tamamına uygulanır.

Koleksiyonlara değil, yalnızca dizilere uygulayabilirsiniz MessageHeaderArrayAttribute .

İleti Sözleşmelerinde Bayt Dizilerini Kullanma

Bayt dizileri, dizi olmayan özniteliklerle (MessageBodyMemberAttribute ve MessageHeaderAttribute) kullanıldığında dizi olarak değil, sonuçta elde edilen XML'de Base64 ile kodlanmış veriler olarak temsil edilen özel bir ilkel tür olarak kabul edilir.

dizi özniteliğiyle MessageHeaderArrayAttributebayt dizileri kullandığınızda, sonuçlar kullanılan seri hale getiriciye bağlıdır. Varsayılan seri hale getirici ile dizi, her bayt için ayrı bir giriş olarak temsil edilir. Ancak , XmlSerializer seçildiğinde (hizmet sözleşmesinde XmlSerializerFormatAttribute kullanılarak), bayt dizileri, dizi veya dizi dışı özniteliklerin kullanılıp kullanılmadığına bakılmaksızın Base64 verileri olarak değerlendirilir.

İletinin Bölümlerini İmzalama ve Şifreleme

İleti sözleşmesi, iletinin üst bilgilerinin ve/veya gövdesinin dijital olarak imzalanması ve şifrelenmesi gerekip gerekmediğini gösterebilir.

Bu, ve MessageBodyMemberAttribute özniteliklerinde özelliği MessageHeaderAttribute ayarlanarak MessageContractMemberAttribute.ProtectionLevel yapılır. özelliği türün System.Net.Security.ProtectionLevel bir numaralandırmasıdır ve (şifreleme veya imza yok), Sign (yalnızca dijital imza) veya EncryptAndSign (hem şifreleme hem de dijital imza) olarak ayarlanabilir None . Varsayılan değer: EncryptAndSign.

Bu güvenlik özelliklerinin çalışması için bağlamayı ve davranışları düzgün bir şekilde yapılandırmanız gerekir. Bu güvenlik özelliklerini doğru yapılandırma olmadan kullanırsanız (örneğin, kimlik bilgilerinizi sağlamadan bir iletiyi imzalamaya çalışırsanız), doğrulama zamanında bir özel durum oluşur.

İleti üst bilgileri için koruma düzeyi her üst bilgi için ayrı ayrı belirlenir.

İleti gövdesi parçaları için koruma düzeyi "minimum koruma düzeyi" olarak düşünülebilir. Vücut parçaları sayısından bağımsız olarak, gövdenin yalnızca bir koruma düzeyi vardır. Gövdenin koruma düzeyi, tüm gövde parçalarının en ProtectionLevel yüksek özellik ayarı tarafından belirlenir. Ancak, her gövde parçasının koruma düzeyini gereken gerçek minimum koruma düzeyine ayarlamanız gerekir.

Aşağıdaki kod örneğinde sınıfını göz önünde bulundurun.

[MessageContract]  
public class PatientRecord  
{  
   [MessageHeader(ProtectionLevel=None)] public int recordID;  
   [MessageHeader(ProtectionLevel=Sign)] public string patientName;  
   [MessageHeader(ProtectionLevel=EncryptAndSign)] public string SSN;  
   [MessageBodyMember(ProtectionLevel=None)] public string comments;  
   [MessageBodyMember(ProtectionLevel=Sign)] public string diagnosis;  
   [MessageBodyMember(ProtectionLevel=EncryptAndSign)] public string medicalHistory;  
}  

Bu örnekte üst recordID bilgi korunmaz, patientName ve signedSSN şifrelenir ve imzalanır. Açıklamaların ve tanılama gövde bölümlerinin daha düşük koruma düzeylerini belirtmesine rağmen, en az bir gövde parçası medicalHistoryolan , uygulanmıştır EncryptAndSign ve bu nedenle ileti gövdesinin tamamı şifrelenir ve imzalanır.

SOAP Eylemi

SOAP ve ilgili Web hizmetleri standartları, gönderilen her SOAP iletisi için mevcut olabilecek adlı Action bir özellik tanımlar. İşlemin OperationContractAttribute.Action ve OperationContractAttribute.ReplyAction özellikleri bu özelliğin değerini denetler.

SOAP Üst Bilgi Öznitelikleri

SOAP standardı, bir üst bilgide mevcut olabilecek aşağıdaki öznitelikleri tanımlar:

  • Actor/Role (Actor SOAP 1.1'de, Role SOAP 1.2'de)

  • MustUnderstand

  • Relay

Actor or Role özniteliği, belirli bir üst bilginin hedeflendiği düğümün Tekdüzen Kaynak Tanımlayıcısını (URI) belirtir. özniteliği, MustUnderstand üst bilgiyi işleyen düğümün bunu anlayıp anlamayacağını belirtir. Relay özniteliği, üst bilginin aşağı akış düğümlerine aktarılıp aktarılmayacağını belirtir. WCF, bu konunun devamında yer alan "İleti Sözleşmesi Sürüm Oluşturma" bölümünde belirtildiği gibi, gelen iletilerde öznitelik dışında MustUnderstand bu özniteliklerin herhangi bir işlemini gerçekleştirmez. Ancak, aşağıdaki açıklamada olduğu gibi bu öznitelikleri gerektiği gibi okumanızı ve yazmanızı sağlar.

İleti gönderirken, bu öznitelikler varsayılan olarak gösterilmez. Bunu iki şekilde değiştirebilirsiniz. İlk olarak, aşağıdaki kod örneğinde gösterildiği gibi , MessageHeaderAttribute.MustUnderstandve MessageHeaderAttribute.Relay özelliklerini değiştirerek MessageHeaderAttribute.Actoröznitelikleri statik olarak istediğiniz değerlere ayarlayabilirsiniz. (Özellik olmadığını Role unutmayın; SOAP 1.2 kullanıyorsanız özelliğin ayarlanması Actor özniteliğini gösterir Role ).

[MessageContract]  
public class BankingTransaction  
{  
  [MessageHeader(Actor="http://auditingservice.contoso.com", MustUnderstand=true)] public bool IsAudited;  
  [MessageHeader] public Operation operation;  
  [MessageBodyMember] public BankingTransactionData theData;  
}  

Bu öznitelikleri denetlemenin ikinci yolu, kod aracılığıyla dinamik olarak gerçekleştirilir. Bunu, istenen üst bilgi türünü türüne MessageHeader<T> kaydırarak (bu türü genel olmayan sürümle karıştırmadığınızdan emin olun) ve türünü ile MessageHeaderAttributebirlikte kullanarak elde edebilirsiniz. Ardından, aşağıdaki kod örneğinde gösterildiği gibi SOAP özniteliklerini ayarlamak için üzerindeki MessageHeader<T> özelliklerini kullanabilirsiniz.

[MessageContract]  
public class BankingTransaction  
{  
  [MessageHeader] public MessageHeader<bool> IsAudited;  
  [MessageHeader] public Operation operation;  
  [MessageBodyMember] public BankingTransactionData theData;  
}  
// application code:  
BankingTransaction bt = new BankingTransaction();  
bt.IsAudited = new MessageHeader<bool>();  
bt.IsAudited.Content = false; // Set IsAudited header value to "false"  
bt.IsAudited.Actor="http://auditingservice.contoso.com";  
bt.IsAudited.MustUnderstand=true;  

Hem dinamik hem de statik denetim mekanizmalarını kullanırsanız, statik ayarlar varsayılan olarak kullanılır, ancak daha sonra aşağıdaki kodda gösterildiği gibi dinamik mekanizma kullanılarak geçersiz kılınabilir.

[MessageHeader(MustUnderstand=true)] public MessageHeader<Person> documentApprover;  
// later on in the code:  
BankingTransaction bt = new BankingTransaction();  
bt.documentApprover = new MessageHeader<Person>();  
bt.documentApprover.MustUnderstand = false; // override the static default of 'true'  

Aşağıdaki kodda gösterildiği gibi dinamik öznitelik denetimiyle yinelenen üst bilgiler oluşturmaya izin verilir.

[MessageHeaderArray] public MessageHeader<Person> documentApprovers[];  

Alıcı tarafında, bu SOAP özniteliklerini okumak yalnızca türündeki MessageHeader<T> üst bilgi için sınıf kullanılıyorsa yapılabilir. Alınan iletideki Actoröznitelik ayarlarını bulmak için türün MessageHeader<T> üst bilgisinin , Relayveya MustUnderstand özelliklerini inceleyin.

bir ileti alındığında ve sonra geri gönderildiğinde, SOAP öznitelik ayarları yalnızca türdeki üst bilgiler MessageHeader<T> için gidiş dönüş yapar.

SOAP Gövde Parçalarının Sırası

Bazı durumlarda, vücut parçalarının sırasını kontrol etmeniz gerekebilir. Gövde öğelerinin sırası varsayılan olarak alfabetiktir, ancak özelliği tarafından MessageBodyMemberAttribute.Order denetlenebilir. Bu özellik, devralma senaryolarındaki davranış dışında özelliğiyle DataMemberAttribute.Order aynı semantike sahiptir (ileti sözleşmelerinde, temel tür gövde üyeleri türetilmiş tür gövde üyelerinden önce sıralanmaz). Daha fazla bilgi için bkz . Veri Üyesi Sırası.

Aşağıdaki örnekte, amount normalde ilk alfabetik olduğundan önce gelir. Ancak, Order özelliği üçüncü konuma yerleştirir.

[MessageContract]  
public class BankingTransaction  
{  
  [MessageHeader] public Operation operation;  
  [MessageBodyMember(Order=1)] public Account sourceAccount;  
  [MessageBodyMember(Order=2)] public Account targetAccount;  
  [MessageBodyMember(Order=3)] public int amount;  
}  

İleti Sözleşmesi Sürümü Oluşturma

Bazen ileti sözleşmelerini değiştirmeniz gerekebilir. Örneğin, uygulamanızın yeni bir sürümü iletiye ek üst bilgi ekleyebilir. Ardından, yeni sürümden eski sürüme gönderirken, sistemin diğer yöne doğru ilerlerken ek bir üst bilgi ve eksik üst bilgiyle ilgilenmesi gerekir.

Sürüm oluşturma üst bilgileri için aşağıdaki kurallar geçerlidir:

  • WCF eksik üst bilgilerine itiraz etmez; karşılık gelen üyeler varsayılan değerlerinde bırakılır.

  • WCF ayrıca beklenmeyen ek üst bilgileri de yoksayar. Bu kuralın tek özel durumu, ek üst bilginin gelen SOAP iletisinde olarak ayarlanmış true bir MustUnderstand özniteliği olmasıdır; bu durumda anlaşılması gereken bir üst bilgi işlenemediğinden bir özel durum oluşturulur.

İleti gövdeleri benzer sürüm oluşturma kurallarına sahiptir; hem eksik hem de ek ileti gövdesi bölümleri yoksayılır.

Devralma Konuları

Temel türün bir ileti sözleşmesi de olduğu sürece, ileti sözleşmesi türü başka bir türden devralabilir.

Diğer ileti sözleşmesi türlerinden devralan bir ileti sözleşme türü kullanarak bir ileti oluştururken veya bu iletiye erişirken aşağıdaki kurallar geçerlidir:

  • Devralma hiyerarşisindeki tüm ileti üst bilgileri, iletinin tam üst bilgi kümesini oluşturmak üzere bir araya toplanır.

  • Devralma hiyerarşisindeki tüm ileti gövdesi bölümleri, tam ileti gövdesini oluşturmak için bir araya toplanır. Gövde parçaları, her zamanki sıralama kurallarına göre ( MessageBodyMemberAttribute.Order özelliğe göre ve sonra alfabetik olarak) sıralanır ve devralma hiyerarşisindeki yerleriyle hiçbir ilgisi yoktur. İleti gövdesi bölümlerinin devralma ağacının birden çok düzeyinde gerçekleştiği ileti sözleşmesi devralmayı kullanmak kesinlikle önerilmez. Temel sınıf ve türetilmiş bir sınıf aynı ada sahip bir üst bilgi veya gövde bölümü tanımlarsa, bu üst bilgi veya gövde bölümünün değerini depolamak için en temel sınıftaki üye kullanılır.

Aşağıdaki kod örneğindeki sınıfları göz önünde bulundurun.

[MessageContract]  
public class PersonRecord  
{  
  [MessageHeader(Name="ID")] public int personID;  
  [MessageBodyMember] public string patientName;  
}  
  
[MessageContract]  
public class PatientRecord : PersonRecord  
{  
  [MessageHeader(Name="ID")] public int patientID;  
  [MessageBodyMember] public string diagnosis;  
}  

PatientRecord sınıfı adlı IDbir üst bilgi içeren bir ileti açıklar. Üst bilgi, en temel üye seçildiğinden patientID üyeye değil, öğesine karşılık gelirpersonID. Bu nedenle, patientID bu durumda alan işe yaramaz. İletinin gövdesi, alfabetik sıra olduğundan öğesinin ardından patientName öğesini içerirdiagnosis. Örnekte kesinlikle önerilmez bir desen gösterildiğine dikkat edin: hem temel hem de türetilmiş ileti sözleşmelerinin ileti gövdesi bölümleri vardır.

WSDL Ile İlgili Dikkat Edilmesi Gerekenler

İleti sözleşmeleri kullanan bir hizmetten Web Hizmetleri Açıklama Dili (WSDL) sözleşmesi oluştururken, tüm ileti sözleşmesi özelliklerinin sonuçta elde edilen WSDL'ye yansıtılmadığını unutmayın. Aşağıdaki noktalara bir göz atın:

  • WSDL, üst bilgi dizisi kavramını ifade edemez. kullanarak MessageHeaderArrayAttributebir üst bilgi dizisiyle ileti oluştururken, sonuçta elde edilen WSDL dizi yerine yalnızca bir üst bilgiyi yansıtır.

  • Sonuçta elde edilen WSDL belgesi bazı koruma düzeyi bilgilerini yansıtmayabilir.

  • WSDL'de oluşturulan ileti türü, ileti sözleşmesi türünün sınıf adıyla aynı ada sahiptir.

  • Aynı ileti sözleşmesini birden çok işlemde kullanırken, WSDL belgesinde birden çok ileti türü oluşturulur. Adlar, sonraki kullanımlar için "2", "3" gibi sayılar eklenerek benzersiz hale getirilir. WSDL'yi geri aktarırken, birden çok ileti sözleşmesi türü oluşturulur ve adları dışında aynı olur.

SOAP Kodlama ile İlgili Dikkat Edilmesi Gerekenler

WCF, XML'nin eski SOAP kodlama stilini kullanmanıza olanak tanır, ancak kullanılması önerilmez. Bu stili kullanırken (özelliği Encoded hizmet sözleşmesine uygulananda System.ServiceModel.XmlSerializerFormatAttribute olarak ayarlayarakUse), aşağıdaki ek noktalar geçerlidir:

  • İleti üst bilgileri desteklenmez; bu, özniteliğin MessageHeaderAttribute ve dizi özniteliğinin MessageHeaderArrayAttribute SOAP kodlamasıyla uyumsuz olduğu anlamına gelir.

  • İleti sözleşmesi sarmalanmazsa, yani özelliği IsWrapped olarak falseayarlanırsa, ileti sözleşmesinin yalnızca bir gövde parçası olabilir.

  • İstek iletisi sözleşmesi için sarmalayıcı öğesinin adı işlem adıyla eşleşmelidir. WrapperName Bunun için ileti sözleşmesinin özelliğini kullanın.

  • Yanıt iletisi sözleşmesi için sarmalayıcı öğesinin adı, 'Response' tarafından eklenen işlemin adıyla aynı olmalıdır. WrapperName Bunun için ileti sözleşmesinin özelliğini kullanın.

  • SOAP kodlaması nesne başvurularını korur. Örneğin, aşağıdaki kodu göz önünde bulundurun.

    [MessageContract(WrapperName="updateChangeRecord")]  
    public class ChangeRecordRequest  
    {  
      [MessageBodyMember] Person changedBy;  
      [MessageBodyMember] Person changedFrom;  
      [MessageBodyMember] Person changedTo;  
    }  
    
    [MessageContract(WrapperName="updateChangeRecordResponse")]  
    public class ChangeRecordResponse  
    {  
      [MessageBodyMember] Person changedBy;  
      [MessageBodyMember] Person changedFrom;  
      [MessageBodyMember] Person changedTo;  
    }  
    
    // application code:  
    ChangeRecordRequest cr = new ChangeRecordRequest();  
    Person p = new Person("John Doe");  
    cr.changedBy=p;  
    cr.changedFrom=p;  
    cr.changedTo=p;  
    

SOAP kodlamasını changedFrom kullanarak iletiyi seri hale getirdikten sonra kendi changedTo kopyalarını piçermez, bunun yerine öğesinin içindeki kopyaya changedBy işaret edin.

Başarım Değerlendirmeleri

Her ileti üst bilgisi ve ileti gövdesi bölümü diğerlerinden bağımsız olarak serileştirilir. Bu nedenle, her üst bilgi ve gövde bölümü için aynı ad alanları yeniden bildirilebilir. Özellikle iletinin kablodaki boyutu açısından performansı artırmak için, birden çok üst bilgiyi ve gövde parçasını tek bir üst bilgi veya gövde parçasında birleştirin. Örneğin, aşağıdaki kod yerine:

[MessageContract]  
public class BankingTransaction  
{  
  [MessageHeader] public Operation operation;  
  [MessageBodyMember] public Account sourceAccount;  
  [MessageBodyMember] public Account targetAccount;  
  [MessageBodyMember] public int amount;  
}  

Bu kodu kullanın.

[MessageContract]  
public class BankingTransaction  
{  
  [MessageHeader] public Operation operation;  
  [MessageBodyMember] public OperationDetails details;  
}  
  
[DataContract]  
public class OperationDetails  
{  
  [DataMember] public Account sourceAccount;  
  [DataMember] public Account targetAccount;  
  [DataMember] public int amount;  
}  

Olay Tabanlı Zaman Uyumsuz ve İleti Sözleşmeleri

Olay tabanlı zaman uyumsuz model durumu için tasarım yönergeleri, birden fazla değer döndürülürse bir değerin Result özellik olarak döndürüldüğünü ve diğerlerinin nesnede EventArgs özellik olarak döndürüldüğünü belirtir. Bunun bir sonucu, istemcinin olay tabanlı zaman uyumsuz komut seçeneklerini kullanarak meta verileri içeri aktarması ve işlemin birden fazla değer döndürmesi durumunda varsayılan EventArgs nesnenin özellik olarak Result bir değer döndürmesi ve kalan nesnenin EventArgs özellikleri olmasıdır.

İleti nesnesini özellik olarak Result almak ve döndürülen değerleri bu nesnede özellik olarak almak istiyorsanız komut seçeneğini kullanın /messageContract . Bu, yanıt iletisini nesne üzerinde EventArgs özelliği olarak Result döndüren bir imza oluşturur. Tüm iç dönüş değerleri daha sonra yanıt iletisi nesnesinin özellikleridir.

Ayrıca bkz.