আমি জানি বেসরকারী সেটারগুলি পরিচালনা করার একটি বৈশিষ্ট্য আছে তবে আমি এই ধরনের আচরণটি একটি ডিফল্ট হিসাবে চাই, এটি সম্পাদন করার কোনও উপায় আছে কি? উত্স টুইট থেকে বাদে। এটির জন্য যদি কোনও সেটিংস থাকে তবে দুর্দান্ত হবে।
আমি জানি বেসরকারী সেটারগুলি পরিচালনা করার একটি বৈশিষ্ট্য আছে তবে আমি এই ধরনের আচরণটি একটি ডিফল্ট হিসাবে চাই, এটি সম্পাদন করার কোনও উপায় আছে কি? উত্স টুইট থেকে বাদে। এটির জন্য যদি কোনও সেটিংস থাকে তবে দুর্দান্ত হবে।
উত্তর:
আমি এখানে আসল বৈশিষ্ট্যটি সন্ধান করতে এসেছি যা জিসন.এনইটি ডিজিটালাইজ করার সময় একটি পঠনযোগ্য সম্পত্তিকে জনবহুল করে তোলে এবং এটি সহজ [JsonProperty], উদাহরণস্বরূপ:
[JsonProperty]
public Guid? ClientId { get; private set; }
কেবল এমন একটি কনস্ট্রাক্টর সরবরাহ করুন যার সাথে আপনার সম্পত্তির সাথে মিল রয়েছে একটি প্যারামিটার:
public class Foo
{
public string Bar { get; }
public Foo(string bar)
{
Bar = bar;
}
}
এখন এটি কাজ করে:
string json = "{ \"bar\": \"Stack Overflow\" }";
var deserialized = JsonConvert.DeserializeObject<Foo>(json);
Console.WriteLine(deserialized.Bar); // Stack Overflow
আমি যেহেতু সম্ভব এই পদ্ধতির পছন্দ করি:
{ get; private set; }এবং ন্যায়বিচারের সাথে কাজ করে { get; }।{get;private set;}, না{get;}
{ get; }যদি প্রকারের নামের সাথে মেলে এমন একটি পরামিতি সহ কোনও নির্মাণকারীর থাকে।
আমি এর জন্য একটি উত্স বিতরণ নুগেট লিখেছি, এটি দুটি কাস্টম চুক্তি সমাধানকারীদের সাথে একটি একক ফাইল ইনস্টল করে:
নিউগেট ইনস্টল করুন:
Install-Package JsonNet.PrivateSettersContractResolvers.Source
তারপরে কেবল যে কোনও সমাধানকারী ব্যবহার করুন:
var settings = new JsonSerializerSettings
{
ContractResolver = new PrivateSetterContractResolver()
};
var model = JsonConvert.DeserializeObject<Model>(json, settings);
আপনি এটি সম্পর্কে এখানে পড়তে পারেন: http://danielwertheim.se/json-net-private-setters-nuget/
গিটহাব রেপো: https://github.com/danielwertheim/jsonnet-privatesetterscontractresolvers
দুটি বিকল্প রয়েছে যা সমস্যার সমাধান করতে পারে।
অল্ট 1: ডিসিরিয়াজারগুলিতে
ContractResolver.DefaultMembersSearchFlags =
DefaultMembersSearchFlags | BindingFlags.NonPublic;
ডিফল্ট সিরিয়ালাইজেশন বিকল্পটি সকল ধরণের শ্রেণীর সদস্যকে সমর্থন করে। অতএব এই সমাধান ক্ষেত্র সহ সমস্ত প্রাইভেট সদস্যদের প্রকার ফেরত দেবে। আমি ব্যক্তিগত বেসরকারীদের সমর্থন করতে আগ্রহী।
Alt2: একটি কাস্টম কন্ট্রাক্ট রিসলভার তৈরি করুন:
অতএব এটি সর্বোত্তম বিকল্প কারণ আমরা কেবলমাত্র বৈশিষ্ট্যগুলি পরীক্ষা করি।
public class SisoJsonDefaultContractResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(
MemberInfo member,
MemberSerialization memberSerialization)
{
//TODO: Maybe cache
var prop = base.CreateProperty(member, memberSerialization);
if (!prop.Writable)
{
var property = member as PropertyInfo;
if (property != null)
{
var hasPrivateSetter = property.GetSetMethod(true) != null;
prop.Writable = hasPrivateSetter;
}
}
return prop;
}
}
আরও তথ্যের জন্য, আমার পোস্টটি পড়ুন: http://danielwertheim.se/json-net-private-setters/
{get; }সমান নয় { get; private set; }। প্রথম উপায়ে property.GetSetMethod(true)ফেরত nullএবং দ্বিতীয়টির জন্য true। এটি আমাকে অবাক করে দিয়েছে। private set;প্রত্যাশা অনুযায়ী কাজ করার জন্য আপনার অবশ্যই ডিসরিয়ালাইজেশন থাকতে হবে।
@ ড্যানিয়েলের উত্তর (অল্ট 2) স্পট রয়েছে, তবে প্রাইভেট সেটার এবং গেটার উভয়ের পক্ষে কাজ করার জন্য আমার এটির প্রয়োজন ছিল (আমি এমন একটি এপিআই নিয়ে কাজ করছি যার মধ্যে কেবল কয়েকটি লেখার মতো জিনিস রয়েছে, যেমন user.password।) এখানে আমি কী শেষ করেছি:
public class NonPublicPropertiesResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) {
var prop = base.CreateProperty(member, memberSerialization);
if (member is PropertyInfo pi) {
prop.Readable = (pi.GetMethod != null);
prop.Writable = (pi.SetMethod != null);
}
return prop;
}
}
এভাবে নিবন্ধিত:
JsonConvert.DefaultSettings = () => new JsonSerializerSettings {
ContractResolver = new NonPublicPropertiesResolver()
};