Veri Sözleşmesi Sürümü Oluşturma
Uygulamalar geliştikçe, hizmetlerin kullandığı veri sözleşmelerini de değiştirmeniz gerekebilir. Bu konuda, veri sözleşmelerinin nasıl sürüme ekli olduğu açıklanmaktadır. Bu konu başlığında, veri sözleşmesi sürüm oluşturma mekanizmaları açıklanmaktadır. Tam bir genel bakış ve açıklayıcı sürüm oluşturma kılavuzu için bkz . En İyi Yöntemler: Veri Sözleşmesi Sürüm Oluşturma.
Hataya Neden Olan ve Bölünemeyen Değişikliklere Karşı
Veri sözleşmesinde yapılan değişiklikler bozulabilir veya bölünemez. Bir veri sözleşmesi bölünemez bir şekilde değiştirildiğinde, sözleşmenin eski sürümünü kullanan bir uygulama daha yeni sürümü kullanarak bir uygulamayla iletişim kurabilir ve sözleşmenin daha yeni sürümünü kullanan bir uygulama eski sürümü kullanarak bir uygulamayla iletişim kurabilir. Öte yandan, hataya neden olan bir değişiklik, bir veya her iki yönde iletişimi engeller.
Bir türe yapılan ve iletim ve alınma şeklini etkilemeyen değişiklikler bölünemez. Bu tür değişiklikler veri sözleşmesini değiştirmez, yalnızca temel alınan türü değiştirir. Örneğin, öğesinin özelliğini DataMemberAttribute eski sürüm adına ayarlarsanızName, bir alanın adını bölünemez bir şekilde değiştirebilirsiniz. Aşağıdaki kod, bir veri sözleşmesinin 1. sürümünü gösterir.
// Version 1
[DataContract]
public class Person
{
[DataMember]
private string Phone;
}
' Version 1
<DataContract()> _
Public Class Person
<DataMember()> _
Private Phone As String
End Class
Aşağıdaki kodda bölünemez bir değişiklik gösterilmektedir.
// Version 2. This is a non-breaking change because the data contract
// has not changed, even though the type has.
[DataContract]
public class Person
{
[DataMember(Name = "Phone")]
private string Telephone;
}
' Version 2. This is a non-breaking change because the data contract
' has not changed, even though the type has.
<DataContract()> _
Public Class Person
<DataMember(Name:="Phone")> _
Private Telephone As String
End Class
Bazı değişiklikler iletilen verileri değiştirir, ancak hataya neden olabilir veya olmayabilir. Aşağıdaki değişiklikler her zaman hataya neden oluyor:
özelliğini DataMemberAttributekullanarak Order veri üyelerinin sırasını değiştirme.
Veri üyesini yeniden adlandırma.
Veri üyesinin veri sözleşmesini değiştirme. Örneğin, veri üyesinin türünü bir tamsayıdan dizeye veya "Müşteri" adlı veri sözleşmesine sahip bir türden "Person" adlı veri sözleşmesine sahip bir türe değiştirme.
Aşağıdaki değişiklikler de mümkündür.
Veri Üyeleri Ekleme ve Kaldırma
Çoğu durumda, katı şema geçerliliği (eski şemada doğrulayan yeni örnekler) gerektirmediğiniz sürece veri üyesi eklemek veya kaldırmak hataya neden olan bir değişiklik değildir.
Ek alanı olan bir tür, eksik alanı olan bir türe seri durumdan çıkarıldığında, ek bilgiler yoksayılır. (Yuvarlama amacıyla da depolanabilir; daha fazla bilgi için bkz. İletme Uyumlu Veri Sözleşmeleri).
Alanı eksik olan bir tür, ek alanı olan bir türe seri durumdan çıkarıldığında, ek alan varsayılan değerinde (genellikle sıfır veya null
) bırakılır. (Varsayılan değer değiştirilebilir; daha fazla bilgi için bkz. Sürüme Dayanıklı Serileştirme Geri Çağırmaları.)
Örneğin, CarV1
sınıfını bir istemcide ve CarV2
sınıfını bir hizmette veya sınıfını bir hizmette ve CarV2
sınıfını da bir istemcide kullanabilirsinizCarV1
.
// Version 1 of a data contract, on machine V1.
[DataContract(Name = "Car")]
public class CarV1
{
[DataMember]
private string Model;
}
// Version 2 of the same data contract, on machine V2.
[DataContract(Name = "Car")]
public class CarV2
{
[DataMember]
private string Model;
[DataMember]
private int HorsePower;
}
' Version 1 of a data contract, on machine V1.
<DataContract(Name:="Car")> _
Public Class CarV1
<DataMember()> _
Private Model As String
End Class
' Version 2 of the same data contract, on machine V2.
<DataContract(Name:="Car")> _
Public Class CarV2
<DataMember()> _
Private Model As String
<DataMember()> _
Private HorsePower As Integer
End Class
Sürüm 2 uç noktası, sürüm 1 uç noktasına başarıyla veri gönderebilir. Veri sözleşmesinin Car
2. sürümünü seri hale getirmek, aşağıdakine benzer şekilde XML verir.
<Car>
<Model>Porsche</Model>
<HorsePower>300</HorsePower>
</Car>
V1'de seri durumdan çıkarma altyapısı, alan için HorsePower
eşleşen bir veri üyesi bulamaz ve bu verileri atar.
Ayrıca sürüm 1 uç noktası, sürüm 2 uç noktasına veri gönderebilir. Veri sözleşmesinin Car
1. sürümünü seri hale getirmek, aşağıdakine benzer şekilde XML verir.
<Car>
<Model>Porsche</Model>
</Car>
Sürüm 2 seri durumdan çıkarıcı, gelen XML'de eşleşen veri olmadığından alanın ne olarak ayarlandığını HorsePower
bilmiyor. Bunun yerine, alan varsayılan 0 değerine ayarlanır.
Gerekli Veri Üyeleri
bir veri üyesi, özelliğini DataMemberAttributetrue
olarak ayarlayarak IsRequired gerekli olarak işaretlenebilir. Seri durumdan çıkarılırken gerekli veriler eksikse, veri üyesini varsayılan değerine ayarlamak yerine bir özel durum oluşturulur.
Gerekli bir veri üyesi eklemek hataya neden olan bir değişikliktir. Başka bir deyişle, daha yeni tür yine de eski türe sahip uç noktalara gönderilebilir, ancak tam tersi olmaz. Önceki sürümlerde gerekli olarak işaretlenmiş bir veri üyesinin kaldırılması da hataya neden olan bir değişikliktir.
özellik değerini olarak false
true
değiştirmek hataya neden olmaz, ancak türün IsRequired önceki sürümlerinde söz konusu veri üyesi yoksa değerini olarak değiştirmek false
true
hataya neden olabilir.
Not
özelliği olarak true
ayarlanmış olsa IsRequired da, gelen veriler null veya sıfır olabilir ve bu olasılığı işlemek için bir tür hazırlanmalıdır. Kötü gelen verilere karşı koruma sağlamak için güvenlik mekanizması olarak kullanmayın IsRequired .
Atlanmış Varsayılan Değerler
DataMemberAttribute özniteliğindeki false
özelliğini, Veri Üyesi Varsayılan Değerleri'nde açıklandığı gibi olarak ayarlamak EmitDefaultValue
mümkündür (önerilmez). Bu ayar ise false
, varsayılan değerine (genellikle null veya sıfır) ayarlanırsa veri üyesi gösterilmez. Bu, farklı sürümlerdeki gerekli veri üyeleriyle iki şekilde uyumlu değildir:
Bir sürümde gerekli olan bir veri üyesiyle yapılan veri sözleşmesi, veri üyesinin
EmitDefaultValue
olarak ayarlandığıfalse
farklı bir sürümden varsayılan (null veya sıfır) verileri alamaz.olarak ayarlanmış
false
gerekli bir veri üyesiEmitDefaultValue
, varsayılan (null veya sıfır) değerini seri hale getirmek için kullanılamaz, ancak seri durumdan çıkarmada böyle bir değer alabilir. Bu, yuvarlama sorunu oluşturur (veriler içinde okunabilir, ancak aynı veriler daha sonra yazılamaz). Bu nedenle, bir sürümdeyse veEmitDefaultValue
bu sürümdeysefalse
IsRequired
true
, veri sözleşmesinin hiçbir sürümünün gidiş dönüşe neden olmayan bir değer üretemeyeceği şekilde, aynı bileşim diğer tüm sürümler için geçerli olmalıdır.
ŞemaYla İlgili Dikkat Edilmesi Gerekenler
Veri sözleşmesi türleri için hangi şemanın üretildiğine ilişkin bir açıklama için bkz . Veri Sözleşmesi Şema Başvurusu.
WCF'nin veri sözleşmesi türleri için ürettiği şema, sürüm oluşturma için hiçbir sağlama yapmaz. Yani, bir türün belirli bir sürümünden dışarı aktarılan şema yalnızca bu sürümde bulunan veri üyelerini içerir. Arabirimin IExtensibleDataObject uygulanması bir tür için şemayı değiştirmez.
Veri üyeleri varsayılan olarak isteğe bağlı öğeler olarak şemaya aktarılır. Yani, minOccurs
(XML özniteliği) değeri 0 olarak ayarlanır. Gerekli veri üyeleri 1 olarak ayarlanmış şekilde dışarı aktarılır minOccurs
.
Şemaya sıkı sıkıya bağlı kalınması gerekiyorsa, bölünemez olarak kabul edilen değişikliklerin çoğu aslında hataya neden olur. Yukarıdaki örnekte, yalnızca öğesini içeren Model
bir CarV1
örnek şemaya CarV2
göre doğrulanır (her ikisi Model
de ve Horsepower
içerir, ancak her ikisi de isteğe bağlıdır). Ancak bunun tersi doğru değildir: bir CarV2
örnek şemada doğrulamada CarV1
başarısız olur.
Yuvarlama işlemi bazı ek konuları da kapsar. Daha fazla bilgi için İletme Uyumlu Veri Sözleşmeleri'ndeki "Şema Konuları" bölümüne bakın.
İzin Verilen Diğer Değişiklikler
Arabirimi uygulamak IExtensibleDataObject bölünemez bir değişikliktir. Ancak, uygulanan sürümden IExtensibleDataObject önceki tür sürümleri için yuvarlama desteği yoktur. Daha fazla bilgi için bkz . İletme Uyumlu Veri Sözleşmeleri.
Listelemeler
Sabit listesi üyesi eklemek veya kaldırmak hataya neden olan bir değişikliktir. Bir sabit listesi üyesinin adı değiştirildiğinde, sözleşme adı özniteliği kullanılarak eski sürümdekiyle aynı tutulmadığı sürece hataya neden EnumMemberAttribute
oluyor. Daha fazla bilgi için bkz . Veri Sözleşmelerinde Numaralandırma Türleri.
Koleksiyonlar
Koleksiyon türlerinin çoğu veri sözleşmesi modelinde birbiriyle değiştirilebilir olduğundan koleksiyon değişikliklerinin çoğu bölünemez. Ancak, özelleştirilmemiş bir koleksiyonu özelleştirmek veya tam tersi, hataya neden olan bir değişikliktir. Ayrıca koleksiyonun özelleştirme ayarlarını değiştirmek de hataya neden olan bir değişikliktir; diğer bir ifadeyle, veri sözleşmesi adını ve ad alanını değiştirme, yinelenen öğe adı, anahtar öğesi adı ve değer öğesi adı. Koleksiyon özelleştirmesi hakkında daha fazla bilgi için bkz . Veri Sözleşmelerindeki Koleksiyon Türleri.
Doğal olarak, bir koleksiyonun içindekiler veri sözleşmesini değiştirmek (örneğin, tamsayı listesinden dize listesine geçmek) hataya neden olan bir değişikliktir.