জসন.নেটে ব্যক্তিগত সেটটার set


94

আমি জানি বেসরকারী সেটারগুলি পরিচালনা করার একটি বৈশিষ্ট্য আছে তবে আমি এই ধরনের আচরণটি একটি ডিফল্ট হিসাবে চাই, এটি সম্পাদন করার কোনও উপায় আছে কি? উত্স টুইট থেকে বাদে। এটির জন্য যদি কোনও সেটিংস থাকে তবে দুর্দান্ত হবে।


4
আমি খুঁজছিলাম এই বা যে উত্তর।
— marbel82

উত্তর:


115

আমি এখানে আসল বৈশিষ্ট্যটি সন্ধান করতে এসেছি যা জিসন.এনইটি ডিজিটালাইজ করার সময় একটি পঠনযোগ্য সম্পত্তিকে জনবহুল করে তোলে এবং এটি সহজ [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; }।

19
শুধু একটি ক্ষুদ্র নোট: এটি দিয়ে কাজ করে {get;private set;}, না{get;}
— tymtam

8
একটু আপডেট। এখন এটি {get; with এর সাথেও কাজ করে}
— হাভ

4
@ হাভ এর পরে এটির সংস্করণটি কী? আমি সবেমাত্র v11.0.2 পরীক্ষা করেছি এবং এটি কাজ করে না {get;}
— tymtam

4
@tymtam আমি মনে করি এটি কেবল তখনই কাজ করে { get; }যদি প্রকারের নামের সাথে মেলে এমন একটি পরামিতি সহ কোনও নির্মাণকারীর থাকে।
— সায়েব আমিনী

4
@tymtam এই বিকল্পটি এবং একটি উদাহরণ দিয়ে উত্তর আপডেট করেছে।
— সায়েব আমিনী

77

আপডেট হয়েছে, নতুন উত্তর

আমি এর জন্য একটি উত্স বিতরণ নুগেট লিখেছি, এটি দুটি কাস্টম চুক্তি সমাধানকারীদের সাথে একটি একক ফাইল ইনস্টল করে:

  • প্রাইভেটসেটর কনট্র্যাক্ট রিসোলভার
  • প্রাইভেটসেটর ক্যামেলক্যাসপ্রোপার্টিনেমস কনট্র্যাক্ট রিসোলভার

নিউগেট ইনস্টল করুন:

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/


4
আপনার পোস্টটির সাথে সংযোগ স্থাপন করুন ড্যানিয়েল.ওয়ার্টহাইম.সি
— ২০১০ /

4
@ জাফিন ইউআরএল মারা গেছে, ড্যানিওলওয়ার্থিম.ওয়ার্ডপ্রেস.com / 2010 / 11 / 06/… এখন আছে
— ক্রিস মেরিসিক

4
দেখে মনে হচ্ছে অল্ট 2 অবশ্যই আজকাল যাওয়ার উপায়। অবচয়DefaultMembersSearchFlags করা হয়েছে ।
— টড মেনিয়ার

4
সি # 6 সহ, {get; }সমান নয় { get; private set; }। প্রথম উপায়ে property.GetSetMethod(true)ফেরত nullএবং দ্বিতীয়টির জন্য true। এটি আমাকে অবাক করে দিয়েছে। private set;প্রত্যাশা অনুযায়ী কাজ করার জন্য আপনার অবশ্যই ডিসরিয়ালাইজেশন থাকতে হবে।
— এমরগিনস

দেখে মনে হচ্ছে ইনস্টল-প্যাকেজ JsonNet.ContractResolvers এখন ব্যবহার করা উচিত। github.com/danielwertheim/jsonnet- কন্ট্রাক্ট্রোলস
— সারিবদ্ধ

14

@ ড্যানিয়েলের উত্তর (অল্ট 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()
};
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.