संकट
मैं .NET 5 के साथ ASP.NET कोर का उपयोग कर रहा हूं और System.Text.Json
धारावाहिक प्रकार का उपयोग कर रहा हूं जिसमें फ़ील्ड युक्त प्रकार हैं (जैसे System.Numerics.Vector3
(X, Y और Z फ़ील्ड हैं), हालांकि फ़ील्ड के साथ कोई भी प्रकार व्यवहार करता है मुझे भी)।
मैंने सत्यापित किया है कि पोस्टमैन पर एपीआई को कॉल करके फ़ील्ड ठीक से क्रमबद्ध हो जाते हैं, हालांकि स्वाशबकल द्वारा उत्पन्न स्वैगर एपीआई परिभाषा इसे ठीक से प्रतिबिंबित नहीं करती है। (परिभाषा सिर्फ एक खाली प्रकार दिखाती है)
रेप्रो
मैंने एक gist बनाया है जो इसे पुन: उत्पन्न करता है। यह /api/Test
पर एक HTTP प्राप्त विधि प्रदान करता है जो एक फ़ील्ड और एक संपत्ति के साथ Test
प्रकार की वस्तु देता है। दोनों तार हैं। डाकिया के माध्यम से इस एपीआई को कॉल करना दोनों के लिए सही मान देता है। स्वैगर यूआई को /swagger
पर या परिभाषा को /swagger/v1/swagger.json
पर देखने से ही संपत्ति का पता चलता है।
यह व्यवहार स्वैगर UI के उदाहरणों पर भी लागू होता है, जिसमें केवल गुण शामिल होते हैं।
अपेक्षित व्यवहार
दस्तावेज़ों के अनुसार स्वैगर जेनरेटर को स्वतः System.Text.Json
के व्यवहार की प्रतिलिपि बनानी चाहिए, जो स्पष्ट रूप से फ़ील्ड को क्रमबद्ध करने के लिए कॉन्फ़िगर किया गया है (देखें पंक्ति 47), इसलिए मैं उम्मीद करता हूं कि स्वैगर परिभाषा में फ़ील्ड शामिल हो।
सारांश
दोहराने के लिए, मैं सार्वजनिक क्षेत्रों के साथ एक प्रकार को क्रमबद्ध करने के लिए System.Text.Json
का उपयोग करता हूं। यह काम करता है, और मैं इसे इस तरह रखना पसंद करूंगा।
मैं एपीआई के दस्तावेज उत्पन्न करने के लिए स्वाशबकल का उपयोग करने का प्रयास करता हूं जो इन क्रमिकरणों को लौटाता है। यह केवल गुणों के लिए काम करता है, लेकिन फ़ील्ड के लिए नहीं।
क्या ऐसा कुछ और है जिसे काम करने के लिए स्पष्ट रूप से कॉन्फ़िगर करने की आवश्यकता है?
2 जवाब
ऐसा लगता है कि Swashbuckle दस्तावेज़ बनाने के लिए JsonSerializerOptions
का उपयोग नहीं करता है। मुझे मिला एक कामकाज मैन्युअल रूप से प्रकारों को संभालना है:
public class FieldsSchemaFilter : ISchemaFilter
{
public void Apply(OpenApiSchema schema, SchemaFilterContext context)
{
var fields = context.Type.GetFields();
if (fields == null) return;
if (fields.Length == 0) return;
foreach (var field in fields)
{
schema.Properties[field.Name] = new OpenApiSchema
{
// this should be mapped to an OpenApiSchema type
Type = field.FieldType.Name
};
}
}
}
फिर अपने Startup.cs ConfigureServices में:
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "WebApplication1", Version = "v1" });
c.SchemaFilter<FieldsSchemaFilter>();
});
आगे बढ़ते समय, आप SchemaFilterContext
(SchemaGenerator
) में प्रयुक्त JsonSerializerOptions
देखेंगे। IncludeFields
सत्य पर सेट है। डॉक्स के लिए अभी भी केवल गुणों का उपयोग किया जाता है, इसलिए मुझे लगता है कि इस तरह का एक फ़िल्टर आपकी सबसे अच्छी शर्त है।
इस मुद्दे का स्वैगर से कोई लेना-देना नहीं है, यह शुद्ध क्रमांकन मुद्दा है।
आपके पास 3 समाधान हैं:
- वेक्टर के लिए अपना खुद का अनुकूलित जेसन लिखें। (सिर्फ अवधारणा)
- आदिम प्रकार के साथ एक अनुकूलित वस्तु का प्रयोग करें और इसे मैप करें। (सिर्फ अवधारणा)
- Newtonsoft.Json (सुझाए गए समाधान) का प्रयोग करें
माइक्रोसॉफ्ट के संबंध में doc, System.Text.Json
आप तुलना सूची में देख सकते हैं कि System.Text.Json में कुछ सीमाएँ हो सकती हैं।
यदि आप चाहते हैं कि सुझाए गए समाधान सीधे समाधान 3 पर जाएं।
आइए कस्टम की पहली अवधारणा लेते हैं क्रमबद्ध। बीटीडब्ल्यू यह कस्टम उदाहरण सिर्फ प्रदर्शन के लिए है और पूर्ण समाधान नहीं है।
तो आप क्या कर सकते हैं निम्नलिखित है:
- एक कस्टम वेक्टर
CustomVector
मॉडल बनाएं। - एक कस्टम
VectorConverter
वर्ग बनाएं जोJsonConverter
का विस्तार करे। - कुछ मैपिंग जोड़ा गया।
VectorConverter
विशेषता को वेक्टर गुण में रखें।
यहाँ मेरा प्रयास है CustomVector:
public class CustomVector
{
public float? X { get; set; }
public float? Y { get; set; }
public float? Z { get; set; }
}
और कस्टम वेक्टर कनवर्टर:
public class VectorConverter : JsonConverter<Vector3>
{
public override Vector3 Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
// just for now
return new Vector3();
}
public override void Write(Utf8JsonWriter writer, Vector3 data, JsonSerializerOptions options)
{
// just for now
var customVector = new CustomVector
{
X = data.X,
Y = data.Y,
Z = data.Z
};
var result = JsonSerializer.Serialize(customVector);
writer.WriteStringValue(result);
}
}
और आप वेक्टर संपत्ति, निम्नलिखित विशेषता जोड़ा:
[JsonConverter(typeof(VectorConverter))]
public Vector3 Vector { get; set; }
यह निम्नलिखित परिणाम लौटाएगा:
अब यह समस्या का हिस्सा हल करता है, यदि आप एक वेक्टर ऑब्जेक्ट पोस्ट करना चाहते हैं, तो आपके पास एक और चुनौती होगी, जो आपके कार्यान्वयन तर्क पर भी निर्भर करती है।
इसलिए, मेरा दूसरा समाधान प्रयास आता है जहां हम अपने कस्टम वेक्टर का पर्दाफाश करते हैं और json में वेक्टर 3 को अनदेखा करते हैं और इसे हमारे कोड से वेक्टर 3 से/मैप करते हैं:
इसलिए हमने एक CustomVector
पेश किया है, हम इसे अपने वेक्टर3 में मैप करने के बजाय अपने मॉडल में वेक्टर3 के स्थान पर उपयोग कर सकते हैं।
public class Test
{
public string Field { get; set; }
public string Property { get; set; }
[JsonIgnore]
public Vector3 Vector { get; set; }
public CustomVector CustomVector { get; set; }
}
मैपिंग उदाहरण के साथ एक प्राप्त और पोस्ट विधि यहां दी गई है:
[HttpGet]
public Test Get()
{
var vector = new CustomVector() { X = 1, Y = 1, Z = 1 };
var test = new Test
{
Field = "Field",
Property = "Property",
CustomVector = vector
};
VectorMapping(test);
return test;
}
[HttpPost]
public Test Post(Test test)
{
VectorMapping(test);
return test;
}
private static void VectorMapping(Test test)
{
test.Vector = new Vector3
{
X = test.CustomVector.X.GetValueOrDefault(),
Y = test.CustomVector.Y.GetValueOrDefault(),
Z = test.CustomVector.Z.GetValueOrDefault()
};
}
पहले समाधान में नीचे की ओर, हमें एक पूर्ण अनुकूलित क्रमांकन लिखने की आवश्यकता है, और हमारे दूसरे समाधान में हमने अतिरिक्त मॉडल और मानचित्रण पेश किया है।
सुझाया समाधान
इसलिए मैं निम्नलिखित और तीसरे प्रयास का सुझाव देता हूं:
आपके पास जो कुछ भी है उसे अपने समाधान में रखें, बस अपने प्रोजेक्ट में nuget Swashbuckle.AspNetCore.Newtonsoft
जोड़ा, जैसे:
<PackageReference Include="Swashbuckle.AspNetCore.Newtonsoft" Version="5.6.3" />
और आपके स्टार्टअप में
services.AddSwaggerGenNewtonsoftSupport();
फायर अप, और यह दस्तावेज़ीकरण उत्पन्न करेगा, क्योंकि यह वेक्टर 3 और अन्य वर्ग प्रकारों को क्रमबद्ध और deserializing की अनुमति देता है जो System.Text.Json
द्वारा समर्थित नहीं हैं।
जैसा कि आप देख सकते हैं कि इसमें अब वेक्टर 3 को दस्तावेज़ीकरण में शामिल किया गया है:
मुझे पूरा यकीन है कि यह अन्य तरीकों से किया जा सकता है। तो इसे हल करने का यह मेरा प्रयास है।
संबंधित सवाल
नए सवाल
c#
C # (उच्चारण "तेज देखें") Microsoft द्वारा विकसित एक उच्च स्तरीय, सांख्यिकीय रूप से टाइप किया हुआ, बहु-प्रतिमान प्रोग्रामिंग भाषा है। C # कोड आमतौर पर Microsoft के .NET परिवार के टूल और रन-टाइम को लक्षित करता है, जिसमें .NET फ्रेमवर्क, .NET कोर और Xamarin अन्य शामिल हैं। C # या C # के औपचारिक विनिर्देश में लिखे गए कोड के बारे में प्रश्नों के लिए इस टैग का उपयोग करें।