Aracılığıyla paylaş


ile türetilmiş sınıfların özelliklerini seri hale getirme System.Text.Json

Bu makalede, türetilmiş sınıfların özelliklerini ad alanıyla serileştirmeyi System.Text.Json öğreneceksiniz.

Türetilmiş sınıfların özelliklerini seri hale getirme

.NET 7 ile başlayarak, System.Text.Json öznitelik ek açıklamalarıyla çok biçimli tür hiyerarşi serileştirmesini ve seri durumdan kaldırmayı destekler.

Öznitelik Açıklama
JsonDerivedTypeAttribute Tür bildirimine yerleştirildiğinde, belirtilen alt türün polimorfik serileştirmeye kabul edilmesi gerektiğini belirtir. Ayrıca bir tür ayrıştırıcısı belirtme özelliğini de kullanıma sunar.
JsonPolymorphicAttribute Bir tür bildirimine yerleştirildiğinde, türün çok biçimli olarak serileştirilmesi gerektiğini gösterir. Ayrıca, bu tür için çok biçimli serileştirme ve seri durumdan çıkarma yapılandırmaya yönelik çeşitli seçenekleri de kullanıma sunar.

Örneğin, bir WeatherForecastBase sınıfınız ve türetilmiş bir sınıfınız WeatherForecastWithCityolduğunu varsayalım:

[JsonDerivedType(typeof(WeatherForecastWithCity))]
public class WeatherForecastBase
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string? Summary { get; set; }
}
<JsonDerivedType(GetType(WeatherForecastWithCity))>
Public Class WeatherForecastBase
    Public Property [Date] As DateTimeOffset
    Public Property TemperatureCelsius As Integer
    Public Property Summary As String
End Class
public class WeatherForecastWithCity : WeatherForecastBase
{
    public string? City { get; set; }
}
Public Class WeatherForecastWithCity
    Inherits WeatherForecastBase
    Public Property City As String
End Class

Ve derleme zamanında yönteminin tür bağımsız değişkeninin Serialize<TValue> olduğunu WeatherForecastBasevarsayalım:

options = new JsonSerializerOptions
{
    WriteIndented = true
};
jsonString = JsonSerializer.Serialize<WeatherForecastBase>(weatherForecastBase, options);
options = New JsonSerializerOptions With {
    .WriteIndented = True
}
jsonString = JsonSerializer.Serialize(WeatherForecastBase, options)

Bu senaryoda, City nesne aslında bir WeatherForecastWithCity nesne olduğundan weatherForecastBase özelliği seri hale getirilir. Bu yapılandırma, özellikle çalışma zamanı türü olduğunda WeatherForecastWithCityiçin WeatherForecastBaseçok biçimli serileştirmeyi etkinleştirir:

{
  "City": "Milwaukee",
  "Date": "2022-09-26T00:00:00-05:00",
  "TemperatureCelsius": 15,
  "Summary": "Cool"
}

Yükün desteklendiği gibi WeatherForecastBase yuvarlanması destekleniyor olsa da, çalışma zamanı türü WeatherForecastWithCityolarak gerçekleşmez. Bunun yerine, bir çalışma zamanı türü WeatherForecastBaseolarak gerçekleştirilmesi gerekir:

WeatherForecastBase value = JsonSerializer.Deserialize<WeatherForecastBase>("""
    {
      "City": "Milwaukee",
      "Date": "2022-09-26T00:00:00-05:00",
      "TemperatureCelsius": 15,
      "Summary": "Cool"
    }
    """);

Console.WriteLine(value is WeatherForecastWithCity); // False
Dim value As WeatherForecastBase = JsonSerializer.Deserialize(@"
    {
      "City": "Milwaukee",
      "Date": "2022-09-26T00:00:00-05:00",
      "TemperatureCelsius": 15,
      "Summary": "Cool"
    }")

Console.WriteLine(value is WeatherForecastWithCity) // False

Aşağıdaki bölümde, türetilmiş türün yuvarlama özelliğini etkinleştirmek için meta verilerin nasıl ekleneceği açıklanmaktadır.

Polimorfik tip ayrımcıları

Polimorfik seri durumdan çıkarma özelliğini etkinleştirmek için türetilen sınıf için bir tür ayrıştırıcısı belirtmeniz gerekir:

[JsonDerivedType(typeof(WeatherForecastBase), typeDiscriminator: "base")]
[JsonDerivedType(typeof(WeatherForecastWithCity), typeDiscriminator: "withCity")]
public class WeatherForecastBase
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string? Summary { get; set; }
}

public class WeatherForecastWithCity : WeatherForecastBase
{
    public string? City { get; set; }
}
<JsonDerivedType(GetType(WeatherForecastBase), "base")>
<JsonDerivedType(GetType(WeatherForecastWithCity), "withCity")>
Public Class WeatherForecastBase
    Public Property [Date] As DateTimeOffset
    Public Property TemperatureCelsius As Integer
    Public Property Summary As String
End Class

Public Class WeatherForecastWithCity
    Inherits WeatherForecastBase
    Public Property City As String
End Class

Eklenen meta verilerle, özellikle de tür ayrıştırıcısıyla, seri hale getirici yükü temel türünden WeatherForecastBasetür olarak seri hale getirebilir ve seri durumdan WeatherForecastWithCity çıkarabilir. Serileştirme, tür ayrıştırıcı meta verileriyle birlikte JSON yayar:

WeatherForecastBase weather = new WeatherForecastWithCity
{
    City = "Milwaukee",
    Date = new DateTimeOffset(2022, 9, 26, 0, 0, 0, TimeSpan.FromHours(-5)),
    TemperatureCelsius = 15,
    Summary = "Cool"
}
var json = JsonSerializer.Serialize<WeatherForecastBase>(weather, options);
Console.WriteLine(json);
// Sample output:
//   {
//     "$type" : "withCity",
//     "City": "Milwaukee",
//     "Date": "2022-09-26T00:00:00-05:00",
//     "TemperatureCelsius": 15,
//     "Summary": "Cool"
//   }
Dim weather As WeatherForecastBase = New WeatherForecastWithCity With
{
    .City = "Milwaukee",
    .[Date] = New DateTimeOffset(2022, 9, 26, 0, 0, 0, TimeSpan.FromHours(-5)),
    .TemperatureCelsius = 15,
    .Summary = "Cool"
}
Dim json As String = JsonSerializer.Serialize(weather, options)
Console.WriteLine(json)
' Sample output:
'   {
'     "$type" : "withCity",
'     "City": "Milwaukee",
'     "Date": "2022-09-26T00:00:00-05:00",
'     "TemperatureCelsius": 15,
'     "Summary": "Cool"
'   }

Tür ayrıştırıcısı ile seri hale getirici yükü polimorfik olarak WeatherForecastWithCityseri durumdan çıkarabilir:

WeatherForecastBase value = JsonSerializer.Deserialize<WeatherForecastBase>(json);
Console.WriteLine(value is WeatherForecastWithCity); // True
Dim value As WeatherForecastBase = JsonSerializer.Deserialize(json)
Console.WriteLine(value is WeatherForecastWithCity) // True

Not

Varsayılan olarak, $type ayrımcı JSON nesnesinin başına yerleştirilmelidir ve $refgibi $id diğer meta veri özellikleriyle birlikte gruplandırılmalıdır. Ayrıştırıcıyı JSON nesnesinin $type ortasına yerleştiren bir dış API'deki verileri okuyorsanız olarak ayarlayın JsonSerializerOptions.AllowOutOfOrderMetadataProperties true:

JsonSerializerOptions options = new() { AllowOutOfOrderMetadataProperties = true };
JsonSerializer.Deserialize<Base>("""{"Name":"Name","$type":"derived"}""", options);

Çok büyük JSON nesnelerinin seri durumdan çıkarma akışlarını gerçekleştirirken aşırı arabelleğe alma (ve bellek dışı hatalara) neden olabileceğinden bu bayrağı etkinleştirirken dikkatli olun.

Tür ayrıştırıcı biçimlerini karıştırma ve eşleştirme

Tür ayrıştırıcı tanımlayıcıları veya int formlarında string geçerlidir, bu nedenle aşağıdakiler geçerlidir:

[JsonDerivedType(typeof(WeatherForecastWithCity), 0)]
[JsonDerivedType(typeof(WeatherForecastWithTimeSeries), 1)]
[JsonDerivedType(typeof(WeatherForecastWithLocalNews), 2)]
public class WeatherForecastBase { }

var json = JsonSerializer.Serialize<WeatherForecastBase>(new WeatherForecastWithTimeSeries());
Console.WriteLine(json);
// Sample output:
//   {
//    "$type" : 1,
//    Omitted for brevity...
//   }
<JsonDerivedType(GetType(WeatherForecastWithCity), 0)>
<JsonDerivedType(GetType(WeatherForecastWithTimeSeries), 1)>
<JsonDerivedType(GetType(WeatherForecastWithLocalNews), 2)>
Public Class WeatherForecastBase
End Class

Dim json As String = JsonSerializer.Serialize(Of WeatherForecastBase)(New WeatherForecastWithTimeSeries())
Console.WriteLine(json)
' Sample output:
'  {
'    "$type" : 1,
'    Omitted for brevity...
'  }

API, tür ayrıştırıcı yapılandırmalarını karıştırmayı ve eşleştirmeyi desteklese de önerilmez. Genel öneri, tüm string tür ayrımcılarını, tüm int tür ayrımcılarını veya hiç ayrımcı kullanmamaktır. Aşağıdaki örnek, tür ayrıştırıcı yapılandırmalarının nasıl karıştırılıp eşleştirilip eşleştirilip eşleştirileceğini gösterir:

[JsonDerivedType(typeof(ThreeDimensionalPoint), typeDiscriminator: 3)]
[JsonDerivedType(typeof(FourDimensionalPoint), typeDiscriminator: "4d")]
public class BasePoint
{
    public int X { get; set; }
    public int Y { get; set; }
}

public class ThreeDimensionalPoint : BasePoint
{
    public int Z { get; set; }
}

public sealed class FourDimensionalPoint : ThreeDimensionalPoint
{
    public int W { get; set; }
}
<JsonDerivedType(GetType(ThreeDimensionalPoint), 3)>
<JsonDerivedType(GetType(FourDimensionalPoint), "4d")>
Public Class BasePoint
    Public Property X As Integer
    Public Property Y As Integer
End Class

Public Class ThreeDimensionalPoint
    Inherits BasePoint
    Public Property Z As Integer
End Class

Public NotInheritable Class FourDimensionalPoint
    Inherits ThreeDimensionalPoint
    Public Property W As Integer
End Class

Yukarıdaki örnekte türün BasePoint tür ayrıştırıcısı yoktur, türün ThreeDimensionalPoint tür int ayrıştırıcısı ve FourDimensionalPoint türü ayrıştırıcısı vardır string .

Önemli

Polimorfik serileştirmenin çalışması için seri hale getirilmiş değerin türü, polimorfik taban türüne ait olmalıdır. Buna kök düzeyi değerleri serileştirilirken genel tür parametresi olarak, bildirilen serileştirilmiş özelliklerin türü olarak veya serileştirilmiş koleksiyonlardaki koleksiyon öğesi olarak temel türün kullanılması dahildir.

using System.Text.Json;
using System.Text.Json.Serialization;

PerformRoundTrip<BasePoint>();
PerformRoundTrip<ThreeDimensionalPoint>();
PerformRoundTrip<FourDimensionalPoint>();

static void PerformRoundTrip<T>() where T : BasePoint, new()
{
    var json = JsonSerializer.Serialize<BasePoint>(new T());
    Console.WriteLine(json);

    BasePoint? result = JsonSerializer.Deserialize<BasePoint>(json);
    Console.WriteLine($"result is {typeof(T)}; // {result is T}");
    Console.WriteLine();
}
// Sample output:
//   { "X": 541, "Y": 503 }
//   result is BasePoint; // True
//
//   { "$type": 3, "Z": 399, "X": 835, "Y": 78 }
//   result is ThreeDimensionalPoint; // True
//
//   { "$type": "4d", "W": 993, "Z": 427, "X": 508, "Y": 741 }
//   result is FourDimensionalPoint; // True
Imports System.Text.Json
Imports System.Text.Json.Serialization

Module Program
    Sub Main()
        PerformRoundTrip(Of BasePoint)()
        PerformRoundTrip(Of ThreeDimensionalPoint)()
        PerformRoundTrip(Of FourDimensionalPoint)()
    End Sub

    Private Sub PerformRoundTrip(Of T As {BasePoint, New})()
        Dim json = JsonSerializer.Serialize(Of BasePoint)(New T())
        Console.WriteLine(json)

        Dim result As BasePoint = JsonSerializer.Deserialize(Of BasePoint)(json)
        Console.WriteLine($"result is {GetType(T)}; // {TypeOf result Is T}")
        Console.WriteLine()
    End Sub
End Module
' Sample output:
'   { "X": 649, "Y": 754 }
'   result is BasePoint; // True
'
'   { "$type": 3, "Z": 247, "X": 814, "Y": 56 }
'   result is ThreeDimensionalPoint; // True
'
'   { "$type": "4d", "W": 427, "Z": 193, "X": 112, "Y": 935 }
'   result is FourDimensionalPoint; // True

Tür ayrıştırıcı adını özelleştirme

Tür ayrıştırıcısının varsayılan özellik adıdır $type. Özellik adını özelleştirmek için aşağıdaki örnekte gösterildiği gibi öğesini kullanın JsonPolymorphicAttribute :

[JsonPolymorphic(TypeDiscriminatorPropertyName = "$discriminator")]
[JsonDerivedType(typeof(ThreeDimensionalPoint), typeDiscriminator: "3d")]
public class BasePoint
{
    public int X { get; set; }
    public int Y { get; set; }
}

public sealed class ThreeDimensionalPoint : BasePoint
{
    public int Z { get; set; }
}
<JsonPolymorphic(TypeDiscriminatorPropertyName:="$discriminator")>
<JsonDerivedType(GetType(ThreeDimensionalPoint), "3d")>
Public Class BasePoint
    Public Property X As Integer
    Public Property Y As Integer
End Class

Public Class ThreeDimensionalPoint
    Inherits BasePoint
    Public Property Z As Integer
End Class

Yukarıdaki kodda JsonPolymorphic özniteliği değerini yapılandırıyor TypeDiscriminatorPropertyName "$discriminator" . Tür ayrıştırıcı adı yapılandırıldığında, aşağıdaki örnekte JSON olarak seri hale getirilmiş tür gösterilir ThreeDimensionalPoint :

BasePoint point = new ThreeDimensionalPoint { X = 1, Y = 2, Z = 3 };
var json = JsonSerializer.Serialize<BasePoint>(point);
Console.WriteLine(json);
// Sample output:
//  { "$discriminator": "3d", "X": 1, "Y": 2, "Z": 3 }
Dim point As BasePoint = New ThreeDimensionalPoint With { .X = 1, .Y = 2, .Z = 3 }
Dim json As String = JsonSerializer.Serialize(Of BasePoint)(point)
Console.WriteLine(json)
' Sample output:
'  { "$discriminator": "3d", "X": 1, "Y": 2, "Z": 3 }

İpucu

Tür hiyerarşinizdeki bir JsonPolymorphicAttribute.TypeDiscriminatorPropertyName özellik ile çakişen bir kullanmaktan kaçının.

Bilinmeyen türetilmiş türleri işleme

Bilinmeyen türetilmiş türleri işlemek için temel türdeki bir ek açıklamayı kullanarak bu tür desteği kabul etmeniz gerekir. Aşağıdaki tür hiyerarşisini göz önünde bulundurun:

[JsonDerivedType(typeof(ThreeDimensionalPoint))]
public class BasePoint
{
    public int X { get; set; }
    public int Y { get; set; }
}

public class ThreeDimensionalPoint : BasePoint
{
    public int Z { get; set; }
}

public class FourDimensionalPoint : ThreeDimensionalPoint
{
    public int W { get; set; }
}
<JsonDerivedType(GetType(ThreeDimensionalPoint))>
Public Class BasePoint
    Public Property X As Integer
    Public Property Y As Integer
End Class

Public Class ThreeDimensionalPoint
    Inherits BasePoint
    Public Property Z As Integer
End Class

Public NotInheritable Class FourDimensionalPoint
    Inherits ThreeDimensionalPoint
    Public Property W As Integer
End Class

Yapılandırma açıkça için FourDimensionalPointdesteğini kabul etmediğinden, örneğini FourDimensionalPoint BasePoint seri hale getirme girişimi bir çalışma zamanı özel durumuyla sonuçlanır:

JsonSerializer.Serialize<BasePoint>(new FourDimensionalPoint()); // throws NotSupportedException
JsonSerializer.Serialize(Of BasePoint)(New FourDimensionalPoint()) ' throws NotSupportedException

Aşağıdaki gibi belirtilebilen sabit listesi kullanarak JsonUnknownDerivedTypeHandling varsayılan davranışı değiştirebilirsiniz:

[JsonPolymorphic(
    UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FallBackToBaseType)]
[JsonDerivedType(typeof(ThreeDimensionalPoint))]
public class BasePoint
{
    public int X { get; set; }
    public int Y { get; set; }
}

public class ThreeDimensionalPoint : BasePoint
{
    public int Z { get; set; }
}

public class FourDimensionalPoint : ThreeDimensionalPoint
{
    public int W { get; set; }
}
<JsonPolymorphic(
    UnknownDerivedTypeHandling:=JsonUnknownDerivedTypeHandling.FallBackToBaseType)>
<JsonDerivedType(GetType(ThreeDimensionalPoint))>
Public Class BasePoint
    Public Property X As Integer
    Public Property Y As Integer
End Class

Public Class ThreeDimensionalPoint
    Inherits BasePoint
    Public Property Z As Integer
End Class

Public NotInheritable Class FourDimensionalPoint
    Inherits ThreeDimensionalPoint
    Public Property W As Integer
End Class

Temel türe geri dönmek yerine, en yakın bildirilen türetilmiş türün sözleşmesine geri dönmek için ayarını kullanabilirsiniz FallBackToNearestAncestor :

[JsonPolymorphic(
    UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FallBackToNearestAncestor)]
[JsonDerivedType(typeof(BasePoint))]
public interface IPoint { }

public class BasePoint : IPoint { }

public class ThreeDimensionalPoint : BasePoint { }
<JsonPolymorphic(
    UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FallBackToNearestAncestor)>
<JsonDerivedType(GetType(BasePoint)>
Public Interface IPoint
End Interface

Public Class BasePoint
    Inherits IPoint
End Class

Public Class ThreeDimensionalPoint
    Inherits BasePoint
End Class

Yukarıdaki örneğe benzer bir yapılandırmayla ThreeDimensionalPoint , tür olarak BasePointseri hale getirilir:

// Serializes using the contract for BasePoint
JsonSerializer.Serialize<IPoint>(new ThreeDimensionalPoint());
' Serializes using the contract for BasePoint
JsonSerializer.Serialize(Of IPoint)(New ThreeDimensionalPoint())

Ancak, en yakın üste geri düşmek "elmas" belirsizlik olasılığını kabul eder. Örnek olarak aşağıdaki tür hiyerarşisini göz önünde bulundurun:

[JsonPolymorphic(
    UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FallBackToNearestAncestor)]
[JsonDerivedType(typeof(BasePoint))]
[JsonDerivedType(typeof(IPointWithTimeSeries))]
public interface IPoint { }

public interface IPointWithTimeSeries : IPoint { }

public class BasePoint : IPoint { }

public class BasePointWithTimeSeries : BasePoint, IPointWithTimeSeries { }
<JsonPolymorphic(
    UnknownDerivedTypeHandling:=JsonUnknownDerivedTypeHandling.FallBackToNearestAncestor)>
<JsonDerivedType(GetType(BasePoint))>
<JsonDerivedType(GetType(IPointWithTimeSeries))>
Public Interface IPoint
End Interface

Public Interface IPointWithTimeSeries
    Inherits IPoint
End Interface

Public Class BasePoint
    Implements IPoint
End Class

Public Class BasePointWithTimeSeries
    Inherits BasePoint
    Implements IPointWithTimeSeries
End Class

Bu durumda, BasePointWithTimeSeries türü ya da BasePoint IPointWithTimeSeries her ikisi de doğrudan ataları olduğundan seri hale getirilebilir. Bu belirsizlik, örneğini NotSupportedException BasePointWithTimeSeries olarak IPointseri hale getirme girişiminde bulunulmasına neden olur.

// throws NotSupportedException
JsonSerializer.Serialize<IPoint>(new BasePointWithTimeSeries());
' throws NotSupportedException
JsonSerializer.Serialize(Of IPoint)(New BasePointWithTimeSeries())

Sözleşme modeliyle çok biçimliliği yapılandırma

Çok biçimliliği yapılandırmak için öznitelik ek açıklamalarının pratik olmadığı veya imkansız olduğu kullanım örnekleri (büyük etki alanı modelleri, çapraz derleme hiyerarşileri veya üçüncü taraf bağımlılıklarındaki hiyerarşiler gibi) için sözleşme modelini kullanın. Sözleşme modeli, aşağıdaki örnekte gösterildiği gibi tür başına dinamik olarak polimorfik yapılandırma sağlayan özel DefaultJsonTypeInfoResolver bir alt sınıf oluşturarak tür hiyerarşisinde çok biçimliliği yapılandırmak için kullanılabilecek bir API kümesidir:

public class PolymorphicTypeResolver : DefaultJsonTypeInfoResolver
{
    public override JsonTypeInfo GetTypeInfo(Type type, JsonSerializerOptions options)
    {
        JsonTypeInfo jsonTypeInfo = base.GetTypeInfo(type, options);

        Type basePointType = typeof(BasePoint);
        if (jsonTypeInfo.Type == basePointType)
        {
            jsonTypeInfo.PolymorphismOptions = new JsonPolymorphismOptions
            {
                TypeDiscriminatorPropertyName = "$point-type",
                IgnoreUnrecognizedTypeDiscriminators = true,
                UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FailSerialization,
                DerivedTypes =
                {
                    new JsonDerivedType(typeof(ThreeDimensionalPoint), "3d"),
                    new JsonDerivedType(typeof(FourDimensionalPoint), "4d")
                }
            };
        }

        return jsonTypeInfo;
    }
}
Public Class PolymorphicTypeResolver
    Inherits DefaultJsonTypeInfoResolver

    Public Overrides Function GetTypeInfo(
        ByVal type As Type,
        ByVal options As JsonSerializerOptions) As JsonTypeInfo

        Dim jsonTypeInfo As JsonTypeInfo = MyBase.GetTypeInfo(type, options)
        Dim basePointType As Type = GetType(BasePoint)

        If jsonTypeInfo.Type = basePointType Then
            jsonTypeInfo.PolymorphismOptions = New JsonPolymorphismOptions With {
                .TypeDiscriminatorPropertyName = "$point-type",
                .IgnoreUnrecognizedTypeDiscriminators = True,
                .UnknownDerivedTypeHandling =
                    JsonUnknownDerivedTypeHandling.FailSerialization
            }
            jsonTypeInfo.PolymorphismOptions.DerivedTypes.Add(
                New JsonDerivedType(GetType(ThreeDimensionalPoint), "3d"))
            jsonTypeInfo.PolymorphismOptions.DerivedTypes.Add(
                New JsonDerivedType(GetType(FourDimensionalPoint), "4d"))
        End If

        Return jsonTypeInfo
    End Function
End Class

Ek polimorfik serileştirme ayrıntıları

  • Polimorfik serileştirme, aracılığıyla JsonDerivedTypeAttributeaçıkça kabul edilen türetilmiş türleri destekler. Bildirilmeyen türler bir çalışma zamanı özel durumuyla sonuçlanır. Özelliği yapılandırılarak JsonPolymorphicAttribute.UnknownDerivedTypeHandling davranış değiştirilebilir.
  • Türetilmiş türlerde belirtilen polimorfik yapılandırma, temel türlerdeki polimorfik yapılandırma tarafından devralınmıyor. Temel türün bağımsız olarak yapılandırılması gerekir.
  • Hem hem de interface class türleri için polimorfik hiyerarşiler desteklenir.
  • Tür ayrımcılarını kullanan polimorfizm yalnızca nesneler, koleksiyonlar ve sözlük türleri için varsayılan dönüştürücüleri kullanan tür hiyerarşileri için desteklenir.
  • Çok biçimlilik meta veri tabanlı kaynak oluşturmada desteklenir, ancak hızlı yol kaynak oluşturmada desteklenmez.

Ayrıca bkz.