@{ var displayName = User.Identity.GetUserDisplayName(); var photoUrl = PhotoService.GetCurrentUserPhotoUrl(); }
- استفاده از WCF Proxy
- استفاده از ChannelFactory
قصد دارم طی یک مقایسه کوتاه این دو روش را بررسی کنیم:
WCF Proxy:
Proxy در واقع یک کلاس CLR است که به عنوان نماینده یک اینترفیس که از نوع Service Contract است مورد استفاده قرار میگیرد. یا به زبان ساده تر، یک Proxy در واقع نماینده Service Contract ای که سمت سرور پیاده سازی شده است در سمت کلاینت خواهد بود. Proxy تمام متد یا Operation Contractهای سمت سرور را داراست به همراه یک سری متدها و خواص دیگر برای مدیریت چرخه طول عمر سرویس، هم چنین اطلاعات مربوط به وضعیت سرویس و نحوه اتصال آن به سرور. ساخت Proxy به دو روش امکان پذیر است:
- با استفاده از امکانات AddServiceReference موجود در Visual Studio. کافیست از پنجره معروف زیر با استفاده از یک URL سرویس مورد نظر را به پروژه سمت کلاینت خود اضافه نمایید
همچنین میتوانید از قسمت Advanced نیز برای تنظیمات خاص مورد نظر خود(مثل تولید کد برای متدهای Async یا تعیین نوع Collectionها در هنگام انتقال داده و ...) استفاده نمایید.
- با استفاده از SvcUtil.exe . کاربرد svcutil.exe در موارد Metadata Export، Service Validtation، XmlSerialization Type Generator و Metadata Download و ... خلاصه میشود. با استفاده از Vs.Net Command Promptو svcutil میتوان به سرویس مورد نظر دسترسی داشت.مثال
svcutil.exe /language:vb /out:generatedProxy.vb /config:app.config http://localhost:8000/ServiceModelSamples/service
ChannelFactory:
ChannelFactory یک کلاس تعبیه شده در دات نت میباشد که به وسیله یک اینترفیس که به عنوان تعاریف سرویس سمت سرور است یک نمونه از سرویس مورد نظر را برای ما خواهد ساخت. اما به خاظر داشته باشید از این روش زمانی میتوان استفاده کرد که دسترسی کامل به سمت سرور و کلاینت داشته باشید.
برای آشنایی با نحوه پیاده سازی به این روش نیز میتوانید از این مقاله کمک بگیرید.
مثال:
public static TChannel CreateChannel() { IBookService service; var endPointAddress = new EndpointAddress( "http://localhost:7000/service.svc" ); var httpBinding = new BasicHttpBinding(); ChannelFactory<TChannel> factory = new ChannelFactory<TChannel>( httpBinding, endPointAddress ); instance= factory.CreateChannel(); return instance; }
در نتیجه برای ساخت یک سرویس به روش ChannelFactory باید مراحل زیر را طی نمایید:
- یک نمونه از WCF Binding بسازید
- یک نمونه از کلاس EndPointAddress به همراه آدرس سرویس مورد نظر در سمت سرور بسازید(البته میتوان این مرحله را نادیده گرفت و آدرس سرویس را مستقیما به نمونه ChannelFactory به عنوان پارامتر پاس داد)
- یک نمونه از کلاس ChannelFactory یا استفاده از EndPointAddress بسازید
- با استفاده از ChannelFactory یک نمونه از Channel مورد نظر را فراخوانی نمایید(فراخوانی متد CreateChannel)
تفاوتهای دو روش
Proxy | ChannelFactory |
فقط نیاز به یک URL برای ساخت سرویس مورد نظر دارد. بقیه مراحل توسط ابزارهای مرتبط انجام خواهد شد | شما نیاز به دسترسی مستقیم به اسمبلی حاوی Service Contract پروژه خود دارید. |
استفاده از این روش بسیار آسان و ساده است | پیاده سازی آن پیچیدگی بیشتر دارد |
فهم مفاهیم این روش بسیار راحت است | نیاز به دانش اولیه از مفاهیم WCF برای پیاده سازی دارد |
زمانی که میزان تغییرات در کلاسهای مدل و Entityها زیاد باشد این روش بسیار موثر است.(مدیریت تغییرات در WCF) | زمانی که اطمینان دارید که مدل و entityها پروژه زیاد تغییر نخواهند کرد و از طرفی نیاز به کد نویسی کمتر در سمت کلاینت دارید، این روش موثرتر خواهد بود |
فقط به اینترفیس هایی که دارای ServiceContractAttribute هستند دسترسی خواهیم داشت. | به تمام اینترفیسهای تعریف شده در بخش Contracts دسترسی داریم. |
فقط به متدهای که دارای OperationContractAttribute هستند دسترسی خواهیم داشت. | به تمام متدهای عمومی سرویس دسترسی داریم. |
آیا میتوان از روش AddServiceReference تعبیه شده در Vs.Net، برای ساخت ChannelFactory استفاده کرد؟
بله! کافیست هنگام ساخت سرویس، در پنجره AddServiceReference از قسمت Advanced وارد برگه تنظیمات شوید. سپس تیک مربوط به قسمت های Reused Type in referenced assemblies و Reused Types in specified referenced assemblies را بزنید. بعد از لیست پایین، اسمبلیهای مربوط به Domain Model و هم چنین Contractهای سمت سرور را انتخاب نمایید. در این حالت شما از روش Channel Factory برای ساخت سرویس WCF استفاده کرده اید.
ASP.NET MVC #2
MVC چیست و اساس کار آن چگونه است؟
الگوی MVC در سالهای اول دهه 70 میلادی در شرکت زیراکس توسط خالقین زبان اسمالتاک که جزو اولین زبانهای شیءگرا محسوب میشود، ارائه گردید. نام MVC از الگوی Model-View-Controller گرفته شده و چندین دهه است که در صنعت تولید نرم افزار مورد استفاده میباشد. هدف اصلی آن جدا سازی مسئولیتهای اجزای تشکیل دهنده «لایه نمایشی» برنامه است.
این الگو در سال 2004 برای اولین بار در سکویی به نام Rails به کمک زبان روبی جهت ساخت یک فریم ورک وب MVC مورد استفاده قرار گرفت و پس از آن به سایر سکوها مانند جاوا، دات نت (در سال 2007)، PHP و غیره راه یافت.
تصاویری را از این تاریخچه در ادامه ملاحظه میکنید؛ از دکتر Trygve Reenskaug تا شرکت زیراکس و معرفی آن در Rails به عنوان اولین فریم ورک وب MVC.
C در MVC معادل Controller است. کنترلر قسمتی است که کار دریافت ورودیهای دنیای خارج را به عهده دارد؛ مانند پردازش یک درخواست HTTP ورودی.
زمانیکه کنترلر این درخواست را دریافت میکند، کار وهله سازی Model را عهده دار خواهد شد و حاوی اطلاعاتی است که نهایتا در اختیار کاربر قرار خواهد گرفت تا فرآیند پردازش درخواست رسیده را تکمیل نماید. برای مثال اگر کاربری جهت دریافت آخرین اخبار به سایت شما مراجعه کرده است، در اینجا کار تهیه لیست اخبار بر اساس مدل مرتبط به آن صورت خواهد گرفت. بنابراین کنترلرها، پایه اصلی و مدیر ارکستر الگوی MVC محسوب میشوند.
در ادامه، کنترلر یک View را جهت نمایش Model انتخاب خواهد کرد. View در الگوی MVC یک شیء ساده است. به آن میتوان به شکل یک قالب که اطلاعاتی را از Model دریافت نموده و سپس آنها را در مکانهای مناسبی در صفحه قرار میدهد، نگاه کرد.
نتیجه استفاده از این الگو، ایزوله سازی سه جزء یاد شده از یکدیگر است. برای مثال View نمیداند و نیازی ندارد که بداند چگونه باید از لایه دسترسی به اطلاعات کوئری بگیرد. یا برای مثال کنترلر نیازی ندارد بداند که چگونه و در کجا باید خطایی را با رنگی مشخص نمایش دهد. به این ترتیب انجام تغییرات در لایه رابط کاربری برنامه در طول توسعه کلی سیستم، سادهتر خواهد شد.
همچنین در اینجا باید اشاره کرد که این الگو مشخص نمیکند که از چه نوع فناوری دسترسی به اطلاعاتی باید استفاده شود. میتوان از بانکهای اطلاعاتی، وب سرویسها، صفها و یا هر نوع دیگری از اطلاعات استفاده کرد. به علاوه در اینجا در مورد نحوه طراحی Model نیز قیدی قرار داده نشده است. این الگو تنها جهت ساخت بهتر و اصولی «رابط کاربری» طراحی شده است و بس.
تفاوت مهم پردازشی ASP.NET MVC با ASP.NET Web forms
اگر پیشتر با ASP.NET Web forms کار کرده باشید اکنون شاید این سؤال برایتان وجود داشته باشد که این سیستم جدید در مقایسه با نمونه قبلی، چگونه درخواستها را پردازش میکند.
همانطور که مشاهده میکنید، در وب فرمها زمانیکه درخواستی دریافت میشود، این درخواست به یک فایل موجود در سیستم مثلا default.aspx ارسال میگردد. سپس ASP.NET یک کلاس وهله سازی شده معرف آن صفحه را ایجاد کرده و آنرا اجرا میکند. در اینجا چرخه طول عمر صفحه مانند page_load و غیره رخ خواهد داد. جهت انجام این وهله سازی، View به فایل code behind خود گره خورده است و جدا سازی خاصی بین این دو وجود ندارد. منطق صفحه به markup آن که معادل است با یک فایل فیزیکی بر روی سیستم، کاملا مقید است. در ادامه، این پردازش صورت گرفته و HTML نهایی تولیدی به مرورگر کاربر ارسال خواهد شد.
در ASP.NET MVC این نحوه پردازش تغییر کرده است. در اینجا ابتدا درخواست رسیده به یک کنترلر هدایت میشود و این کنترلر چیزی نیست جز یک کلاس مجزا و مستقل از هر نوع فایل ASPX ایی در سیستم. سپس این کنترلر کار پردازش درخواست رسیده را شروع کرده، اطلاعات مورد نیاز را جمع آوری و سپس به View ایی که انتخاب میکند، جهت نمایش نهایی ارسال خواهد کرد. در اینجا View این اطلاعات را دریافت کرده و نهایتا در اختیار کاربر قرار خواهد داد.
آشنایی با قرارداد یافتن کنترلرهای مرتبط
تا اینجا دریافتیم که نحوه پردازش درخواستها در ASP.NET MVC بر مبنای کلاسها و متدها است و نه بر مبنای فایلهای فیزیکی موجود در سیستم. اگر درخواستی به سیستم ارسال میشود، در ابتدا، این درخواست جهت پردازش، به یک متد عمومی موجود در یک کلاس کنترلر هدایت خواهد شد و نه به یک فایل فیزیکی ASPX (برخلاف وب فرمها).
همانطور که در تصویر مشاهده میکنید، در ابتدای پردازش یک درخواست، آدرسی به سیستم ارسال خواهد شد. بر مبنای این آدرس، نام کنترلر که در اینجا زیر آن خط قرمز کشیده شده است، استخراج میگردد (برای مثال در اینجا نام این کنترلرProducts است). سپس فریم ورک به دنبال کلاس این کنترلر خواهد گشت. اگر آنرا در اسمبلی پروژه بیابد، از آن خواهد خواست تا درخواست رسیده را پردازش کند؛ در غیراینصورت پیغام 404 یا یافت نشد، به کاربر نمایش داده میشود.
اما فریم ورک چگونه این کلاس کنترلر درخواستی را پیدا میکند؟
در زمان اجرا، اسمبلی اصلی پروژه به همراه تمام اسمبلیهایی که به آن ارجاعی دارند جهت یافتن کلاسی با این مشخصات اسکن خواهند شد:
1- این کلاس باید عمومی باشد.
2- این کلاس نباید abstract باشد (تا بتوان آنرا به صورت خودکار وهله سازی کرد).
3- این کلاس باید اینترفیس استاندارد IController را پیاده سازی کرده باشد.
4- و نام آن باید مختوم به کلمه Controller باشد (همان مبحث Convention over configuration یا کار کردن با یک سری قرار داد از پیش تعیین شده).
برای مثال در اینجا فریم ورک به دنبال کلاسی به نام ProductsController خواهد گشت.
شاید تعدادی از برنامه نویسهای ASP.NET MVC تصور کنند که فریم ورک در پوشهی استانداردی به نام Controllers به دنبال این کلاس خواهد گشت؛ اما در عمل زمانیکه برنامه کامپایل میشود، پوشهای در این اسمبلی وجود نخواهد داشت و همه چیز از طریق Reflection مدیریت خواهد شد.
اطلاعات خود در مورد ارثبری را محک بزنید
gRPC + ASP.NET Core as a Migration Path for WCFs in .NET Core
Feature | WCF | ASP.Net Core + gRPC |
Platforms | Windows | Windows, Linux, MacOS |
Protocols | LRPC/Named Pipes/HTTP/TCP/MSMQ | Binary (GRPC) + HTTP2 (TCP/Named Pipes/LRPC) .AddProtocol(“ncacn_ip_tcp”, “8080”) .AddProtocol(“ncacn_np”, @”\pipe\MyService”) .AddProtocol(“ncalrpc”, “MyService”) By removing the ASP.NET Core stack and just using .NET Core |
Injected Aspects | Behaviors | ASP.NET Core DI Middleware/ gRPC interceptors |
Distributed Transactions | *Yes – [TransactionFlow], transactionscopes, and supported bindings | *No |
Transport Security | SSL/TLS | SSL/TLS |
Message Security | Certificates/credentials | Certificates/credentials https://docs.microsoft.com/en-us/aspnet/core/grpc/authn-and-authz?view=aspnetcore-3.0 |
Windows Authentication | Kerberos/NTLM | AAD Sync/ASFS + ASP.NET Core middleware |
Proxies/Contracts | Service Contracts/Data Contracts | Protocol Buffers |
Proxy-less Communication | WCF Channel Factory | † Protobuf-Net.GRPC |
ASP.NET MVC
- ASP.NET MVC #1
- ASP.NET MVC #2
- ASP.NET MVC #3
- ASP.NET MVC #4
- ASP.NET MVC #5
- ASP.NET MVC #6
- ASP.NET MVC #7
- ASP.NET MVC #8
- ASP.NET MVC #9
- ASP.NET MVC #10
- ASP.NET MVC #11
- ASP.NET MVC #12
- ASP.NET MVC #13
- ASP.NET MVC #14
- ASP.NET MVC #15
- ASP.NET MVC #16
- ASP.NET MVC #17
- ASP.NET MVC #18
- ASP.NET MVC #19
- ASP.NET MVC #20
- ASP.NET MVC #21
- ASP.NET MVC #22
- ASP.NET MVC #23
- ASP.NET MVC #24
- نحوه ارتقاء برنامههای موجود MVC3 به MVC4
- تغییرات بوجود آمده در Bundling and Minification -MVC4
- تغییرات بوجود آمده در Mobile Features-MVC4
- تغییرات بوجود آمده در Single Page Application (SPA)-MVC4
- تغییرات بوجود آمده در Razor -MVC4
- Globalization در ASP.NET MVC
- Globalization در ASP.NET MVC - قسمت دوم
- Globalization در ASP.NET MVC - قسمت سوم
- Globalization در ASP.NET MVC - قسمت چهارم
- Globalization در ASP.NET MVC - قسمت پنجم
- Globalization در ASP.NET MVC - قسمت ششم
- Globalization در ASP.NET MVC - قسمت هفتم
- بررسی تغییرات ASP.NET MVC 5 beta1
- مسیریابی (Routing) در ASP.NET MVC 5.x
- Attribute Routing در ASP.NET MVC 5
- قابلیت Attribute Routing در ASP.NET MVC 5
- یک تکنیک جالب در نحوه نام گذاری فیلدهای دیتابیس به منظور استفاده بهینه از فایلهای T4 در MVC 5
- نگاهی به هویت سنجی کاربران در ASP.NET MVC 5
- سفارشی کردن ASP.NET Identity در MVC 5
- افزودن تصدیق ایمیل به ASP.NET Identity در MVC 5
- ایجاد کپچایی (captcha) سریع و ساده در ASP.NET MVC 5
- توزیع یک اپلیکیشن ASP.NET MVC 5 روی Windows Azure
- معماری لایه بندی نرم افزار #1
- معماری لایه بندی نرم افزار #2
- معماری لایه بندی نرم افزار #3
- معماری لایه بندی نرم افزار #4
- CheckBoxList در ASP.NET MVC
- RadioButtonList در ASP.NET MVC
- مدیریت محل اعمال Google analytics در ASP.NET MVC
- استفاده از HttpGet در ASP.NET MVC، آری یا خیر؟!
- اثر وجود سشن بر پردازش موازی در ASP.NET
- استفاده از دکمههای CSS توئیتر در ASP.NET MVC
- نحوه صحیح تولید Url در ASP.NET MVC
- استفاده از OpenID در وب سایت جهت احراز هویت کاربران
- متدهای کمکی مفید در پروژههای asp.net mvc
- T4MVC : یکی از الزامات مدیریت پروژههای ASP.NET MVC
- مقدمه ای بر AutoMapper
- بهبود سرعت نمایش صفحات در ASP.NET MVC با حذف View Engines اضافی
- محدود کردن کاربرها به آپلود فایلهایی خاص در ASP.NET MVC
- ارسال فایل در ASP.NET MVC و اعتبار سنجی سمت کاربر
- فعال سازی قسمت ارسال فایل و تصویر ویرایشگر آنلاین RedActor در ASP.NET MVC
- معرفی پروژه Orchard
- مباحث تکمیلی مدلهای خود ارجاع دهنده در EF Code first
- سازگار کردن لینکهای قدیمی یک سایت با ساختار جدید آن در ASP.NET MVC
- CAPTCHAfa
- نکتهای در استفاده از AutoMapper
- یکپارچه سازی CKEditor با Lightbox
- تهیه خروجی RSS در برنامههای ASP.NET MVC
- ایجاد Helper سفارشی جهت نمایش ویدئو در ASP.NET MVC
- ساخت DropDownListهای مرتبط به کمک jQuery Ajax در MVC
- استفاده از دکمههای CSS توئیتر در ASP.NET MVC - قسمت دوم
- با ASP.MVC چه مزایایی را به دست خواهیم آورد
- نحوه اضافه کردن Auto-Complete به جستجوی لوسین در ASP.NET MVC و Web forms
- مقابله با پسوردهایی که ساده حدس زده میشوند
- غیرفعال کردن کش مرورگر در MVC
- Best Practice هایی برای ASP.NET MVC - قسمت اول
- چک لیست تهیه یک برنامه ASP.NET MVC
- استفاده از FluentValidation در ASP.NET MVC
- نحوه اجباری کردن استفاده از WWW در ASP.NET MVC
- نمایش رکوردها به ترتیب اولویت به کمک jQuery UI sortable در ASP.NET MVC
- کنترل عمومی فایلهای آپلودی در ASP.NET MVC
- هدایت خودکار کاربر به صفحه لاگین در حین اعمال Ajax ایی
- مدیریت سفارشی سطوح دسترسی کاربران در MVC
- بهبود SEO در ASP.NET MVC
- ایجاد قسمتهای Toggle در سایت با jQuery
- آشنایی و بررسی ابزار MiniProfiler
- استفاده از Flash Uploader در ASP.NET MVC
- استایل دهی به ستونهای header در WebGrid
- ELMAH و حملات XSS
- آموزش MEF#2(استفاده از MEF در Asp.Net MVC)
- نحوه استفاده از ViewModel در ASP.NET MVC
- مخفی کردن کوئری استرینگها در ASP.NET MVC توسط امکانات Routing
- توزیع پروژههای ASP.NET MVC بدون ارائه فایلهای View آن
- حذف هدرهای مربوط به وب سرور از طریق برنامه نویسی
- ایجاد helper برای Nivo Slider در Asp.net Mvc
- آشنایی با Fluent Html Helpers در MVC
- نحوه استفاده از افزونه Firebug برای دیباگ برنامههای ASP.NET مبتنی بر jQuery
- عدم امکان تغییر اطلاعات مدل در HTML Helpers پس از Postback در ASP.NET MVC
- اضافه کردن Watermark به تصاویر یک برنامه ASP.NET MVC در صورت لینک شدن در سایتی دیگر
- چگونگی رسیدگی به Null property در AutoMapper
- return File در ASP.NET MVC و نامهای یونیکد
- تولید SiteMap استاندارد و ایجاد یک ActionResult اختصاصی برای Return کردن SiteMap تولید شده
- نحوه ایجاد یک تصویر امنیتی (Captcha) با حروف فارسی در ASP.Net MVC
- الگوی PRG در ASP.NET MVC
- اعتبارسنجی سایتهای چند زبانه در ASP.NET MVC - قسمت اول
- آغاز به کار با Twitter Bootstrap در ASP.NET MVC
- استفاده از Twitter Bootstrap در کارهای روزمره طراحی وب
- نگاهی به اجزای تعاملی Twitter Bootstrap
- اعمال کلاسهای ویژه اعتبارسنجی Twitter bootstrap به فرمهای ASP.NET MVC
- ویرایش قالب پیش فرض Add View در ASP.NET MVC برای سازگار سازی آن با Twitter bootstrap
- استفاده از افزونه Typeahead مجموعه Twitter Bootstrap در ASP.NET MVC
- استفاده از modal dialogs مجموعه Twitter Bootstrap برای گرفتن تائید از کاربر
- Bundling and Minifying Inline Css and Js
- نمایش فرمهای مودال Ajax ایی در ASP.NET MVC به کمک Twitter Bootstrap
- MVC vs 3-Tier Pattern
- پلاگین جستجو با jquery و twitter bootstrap
- نمایش خطاهای اعتبارسنجی سمت کاربر ASP.NET MVC به شکل Tooltip به کمک Twitter bootstrap
- نمایش خطاهای اعتبارسنجی سمت کاربر ASP.NET MVC به شکل Popover به کمک Twitter bootstrap
- ساخت قالبهای نمایشی و ادیتور دکمه سه وضعیتی سازگار با Twitter bootstrap در ASP.NET MVC
- پیاده سازی Open Search در ASP.NET MVC
- Best Practice ی برای تأیید اعتبار کردن کاربران در ASP.NET MVC 4
- هدایت درخواست فایلهای استاتیک در ASP.NET MVC به یک کنترلر
- ModelBinder سفارشی در ASP.NET MVC
- ایجاد لینک با یک تصویر بوسیله Html Helper
- بارگزاری PartialView با استفاده از jQuery در زمان اجرا
- یافتن اکشن متدهای به اشتباه کش شده در ASP.NET MVC
- مروری مقدماتی بر ساخت برنامههای موبایل در MVC4
- اجرای برنامههای ASP.NET توسط Mono در Ubuntu
- اجرای برنامههای ASP.NET به کمک وب سرور Apache توسط Mono در Ubuntu
- فعالسازی استفاده از Session در ASP.NET MVC 4 API Controller ها
- ساخت منوهای چند سطحی در ASP.NET MVC
- طراحی ValidationAttribute دلخواه و هماهنگ سازی آن با ASP.NET MVC
- بهینه سازی برنامههای وب ASP.NET برای موتورهای جستجو (SEO)
- CheckBoxList برای فیلد Enum Flags مدل در ASP.Net MVC
- چطور مسیریابیهای ASP.NET MVC را دیباگ کنیم؟
- ذخیره TreeView ساخته شده توسط KendoUI در Asp.net MVC
- تنظیمات امنیتی Glimpse
- سفارشی سازی Binding یک خصوصیت از طریق Attributes
- Bundle کردن فایلهای LESS در MVC
- TwitterBootstrapMVC
- بررسی خطای Circular References در ASP.NET MVC Json Serialization
- ایجاد یک فیلتر سفارشی جهت تعیین Layout برای کنترلر و یا اکشن متد
- حذف فضاهای خالی در خروجی صفحات ASP.NET MVC
- جلوگیری از درج صفحات سایت در سایتی دیگر از طریق iframeها
- مشکل اعتبار سنجی jQuery validator در Bootstrap tabs
- افزودن هدرهای Content Security Policy به برنامههای ASP.NET
- امکان اعتبارسنجی با تاخیر در ASP.NET 4.5
- معرفی ASP.NET Identity
- متدهای احراز هویت در VS 2013
- توسعه اپلیکیشنهای ASP.NET با Windows Azure Active Directory
- ساخت یک اپلیکیشن ساده ToDo با ASP.NET Identity
- دریافت اطلاعات بیشتر از Social Providerها در VS 2013
- معرفی کتابخانه Postal برای ASP.NET MVC
- استفاده از Web Fonts در اپلیکیشنهای ASP.NET MVC
- استفاده از Awesomium.NET در برنامههای وب
- خواندن اطلاعات از سرور و نمایش آن توسط Angular در ASP.NET MVC
- آموزش Backload (آپلود چندین فایل به طور همزمان با آجاکس )
- یافتن اکشن متدهای Post ایی در ASP.NET MVC که فیلتر CSRF ندارند
- ایجاد سیستم وضعیت آب و هوا مانند گوگل (بخش اول)
- استفاده از #F در پروژههای MVC4
- توسعه کنترلر و مدل در F# MVC4
- تعامل با پایگاه داده با استفاده از EntityFramework در پروژههای F# MVC 4
- انجام کارهای زمانبندی شده در برنامههای ASP.NET توسط DNT Scheduler
- بررسی خروجی IsAjaxRequest در درخواستهای http$ توسط AngularJS
- بارگذاری فایلهای ایستا از پوشهی Views در ASP.NET MVC
- هدایت خودکار آدرسهای یافت نشد در یک سایت ASP.NET MVC به جستجوی سایت
- راههای متفاوت رندر لایهها در ASP.NET MVC
- پروژه Microsoft.AspNet.Mvc.Futures و تولید مسیرهای Strongly typed
- ASP.NET MVC و Identity 2.0 : مفاهیم پایه
- ارسال PingBack در ASP.NET
- Identity 2.0 : تایید حسابهای کاربری و احراز هویت دو مرحله ای
- مدیریت درخواستهای شرطی در ASP.NET MVC
- استفاده از Froala WYSIWYG Editor در ASP.NET
- استفاده از نگارش سوم Google Analytics API در سرویسهای ویندوز یا برنامههای وب
- بهینه سازی فایلهای js و css در برنامههای ASP.NET با استفاده از Combres - قسمت اول
- استفاده از pjax بجای ajax در ASP.NET MVC
- استفاده از افزونهی jsTree در ASP.NET MVC
- تفاوت ViewData و ViewBag و TempData و Session در MVC
- استفاده از چند فرم در کنار هم در ASP.NET MVC
- انجام کارهای پس زمینه در ASP.NET 4.5.2
- نمایش اخطارها و پیامهای بوت استرپ به کمک TempData در ASP.NET MVC
- صفحه بندی و مرتب سازی خودکار اطلاعات به کمک jqGrid در ASP.NET MVC
- فرمت کردن اطلاعات نمایش داده شده به کمک jqGrid در ASP.NET MVC
- فعال سازی و پردازش جستجوی پویای jqGrid در ASP.NET MVC
- استفاده از چند Routing در یک پروژه ASP.NET MVC بدون درد و خونریزی
- فعال سازی و پردازش صفحات پویای افزودن، ویرایش و حذف رکوردهای jqGrid در ASP.NET MVC
- رمزنگاری خودکار فیلدهای مخفی در ASP.NET MVC
- استفاده ازExpressionها جهت ایجاد Strongly typed view در ASP.NET MVC
- سفارشی سازی عناصر صفحات پویای افزودن و ویرایش رکوردهای jqGrid در ASP.NET MVC
- تهیه خروجی PDF و اکسل از حاصل جستجوی پویای jqGrid به کمک PDF Report
- Ajax.BeginForm و ارسال فایل به سرور در ASP.NET MVC
- آپلود فایل توسط فرمهای پویای jqGrid
- اختصاصی کردن Razor برای #C در MVC با استفاده از Extension Method
- روشی سریع برای ایجاد RSS و Sitemap در ASP.NET MVC
- اعتبارسنجی سفارشی سمت کاربر و سمت سرور در jqGrid
- OutputCache در ASP.NET MVC
- فعال سازی و پردازش Inline Add در jqGrid
- بهینه سازی سرعت یافت ویوها با سفارشی سازی Lookup Caching در Razor View Engine
- گروه بندی اطلاعات در jqGrid
- نمایش Subgrid در jqGrid
- ایجاد زیر گریدهای چند سطحی در jqGrid
- نمایش ساختارهای درختی توسط jqGrid
- سازگارسازی کلاسهای اعتبارسنجی Twitter Bootstrap 3 با فرمهای ASP.NET MVC
- اعتبارسنجی در فرمهای ASP.NET MVC با Remote Validation
- قالبهای سفارشی برای HtmlHelperها
- ارسال ویدیو بصورت Async توسط Web Api
- اعتبار سنجی سمت کاربر wysiwyg-editorها در ASP.NET MVC
- بررسی مقدمات کتابخانهی JSON.NET
- تنظیمات و نکات کاربردی کتابخانهی JSON.NET
- استفاده از JSON.NET در ASP.NET MVC
- LINQ to JSON به کمک JSON.NET
- آشنایی با چالشهای امنیتی در توسعه برنامههای تحت وب، بخش اول
- نمایش بلادرنگ اعلامی به تمام کاربران در هنگام درج یک رکورد جدید
- پیاده سازی Template تو در تو در AngularJS و ASP.NET MVC
- یکپارچه سازی سیستم اعتبارسنجی ASP.NET MVC با Kendo UI validator
- ساخت یک Form Generator ساده در MVC
- آشنایی با WebDav و نحوه استفاده از آن
- قابلیت Templated Razor Delegate
- اعمال تزریق وابستگیها به مثال رسمی ASP.NET Identity
- ثبت جزئیات استثناهای Entity framework توسط ELMAH
- نمایش بلادرنگ اعلامی به تمام کاربران در هنگام درج یک رکورد جدید به صورت notification
- کار با وب سرویس جاوایی تشخیص ایمیلهای موقتی در دات نت
- فراخوانی متدهای Controllerها در Viewهای ASP.NET MVC
- لغو اجرای یک اکشن فیلتر برای یک اکشن خاص در MVC
- کار با اسکنر در برنامههای تحت وب (قسمت اول)
- کار با اسکنر در برنامههای تحت وب (قسمت دوم و آخر)
- تبدیل یک View به رشته و بازگشت آن به همراه نتایج JSON حاصل از یک عملیات Ajax ایی در ASP.NET MVC
- آشنایی با ساختار ViewBag
- مدیریت سشنها در برنامههای وب به کمک تزریق وابستگیها
- خلاصهای از روشهای ارسال دادههای سمت سرور به کدهای جاوا اسکریپتی در ASP.NET MVC
- یکدست کردن "ی" و "ک" در ASP.NET MVC با پیادهسازی یک Model Binder
- حذف پردازش درخواستهای فایلهای استاتیک در متد Application_AuthenticateRequest
- دریافت خطاهای موجود در Viewهای ASP.NET MVC در زمان کامپایل
- پیاده سازی یک متد الحاقی برای تبدیل آدرس فیزیکی به آدرس مجازی (آدرس سرور)
- استفاده از Razor در فایلهای JavaScript و CSS
- عمومی سازی الگوریتمها با استفاده از Reflection
نصب کتابخانهی FluentValidation در پروژه
فرض کنید پروژهی ما از سه پوشهی FluentValidationSample.Web، FluentValidationSample.Models و FluentValidationSample.Services تشکیل شدهاست که اولی یک پروژهی MVC است و دو مورد دیگر classlib هستند.
در پروژهی FluentValidationSample.Models، بستهی نیوگت کتابخانهی FluentValidation را به صورت زیر نصب میکنیم:
dotnet add package FluentValidation.AspNetCore
جایگزین کردن سیستم اعتبارسنجی مبتنی بر DataAnnotations با FluentValidation
اکنون فرض کنید در پروژهی Models، مدل ثبتنام زیر را اضافه کردهایم که از همان data annotations توکار و استاندارد ASP.NET Core برای اعتبارسنجی اطلاعات استفاده میکند:
using System.ComponentModel.DataAnnotations; namespace FluentValidationSample.Models { public class RegisterModel { [Required] [Display(Name = "User name")] public string UserName { get; set; } [Required] [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] [DataType(DataType.Password)] [Display(Name = "Password")] public string Password { get; set; } [DataType(DataType.Password)] [Display(Name = "Confirm password")] [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] public string ConfirmPassword { get; set; } [DataType(DataType.EmailAddress)] [Display(Name = "Email")] [EmailAddress] public string Email { get; set; } [Range(18, 60)] [Display(Name = "Age")] public int Age { get; set; } } }
using FluentValidation; namespace FluentValidationSample.Models { public class RegisterModelValidator : AbstractValidator<RegisterModel> { public RegisterModelValidator() { RuleFor(x => x.UserName).NotNull(); RuleFor(x => x.Password).NotNull().Length(6, 100); RuleFor(x => x.ConfirmPassword).Equal(x => x.Password); RuleFor(x => x.Email).EmailAddress(); RuleFor(x => x.Age).InclusiveBetween(18, 60); } } }
در اینجا در ابتدا به ازای هر خاصیت کلاس مدل مدنظر، یک RuleFor تعریف میشود که با استفاده از static reflection، امکان تعریف strongly typed آنها وجود دارد. سپس ویژگی Required به متد NotNull تبدیل میشود و ویژگی StringLength توسط متد Length قابل تعریف خواهد بود و یا ویژگی Compare توسط متد Equal به صورت strongly typed به خاصیت دیگری متصل میشود.
پس از این تعاریف، میتوان ویژگیهای اعتبارسنجی اطلاعات را از مدل ثبت نام حذف کرد و تنها ویژگیهای خاص Viewهای MVC را در صورت نیاز باقی گذاشت:
using System.ComponentModel.DataAnnotations; namespace FluentValidationSample.Models { public class RegisterModel { [Display(Name = "User name")] public string UserName { get; set; } [DataType(DataType.Password)] [Display(Name = "Password")] public string Password { get; set; } [DataType(DataType.Password)] [Display(Name = "Confirm password")] public string ConfirmPassword { get; set; } [DataType(DataType.EmailAddress)] [Display(Name = "Email")] public string Email { get; set; } [Display(Name = "Age")] public int Age { get; set; } } }
تعریف پیامهای سفارشی اعتبارسنجی
روش تعریف پیامهای سفارشی شکست اعتبارسنجی اطلاعات را توسط متد WithMessage در ادامه مشاهده میکنید:
using FluentValidation; namespace FluentValidationSample.Models { public class RegisterModelValidator : AbstractValidator<RegisterModel> { public RegisterModelValidator() { RuleFor(x => x.UserName) .NotNull() .WithMessage("Your first name is required.") .MaximumLength(20) .WithMessage("Your first name is too long!") .MinimumLength(3) .WithMessage(registerModel => $"Your first name `{registerModel.UserName}` is too short!"); RuleFor(x => x.Password) .NotNull() .WithMessage("Your password is required.") .Length(6, 100); RuleFor(x => x.ConfirmPassword) .NotNull() .WithMessage("Your confirmation password is required.") .Equal(x => x.Password) .WithMessage("The password and confirmation password do not match."); RuleFor(x => x.Email).EmailAddress(); RuleFor(x => x.Age).InclusiveBetween(18, 60); } } }
روش تعریف اعتبارسنجیهای سفارشی خواص مدل
فرض کنید میخواهیم یک کلمهی عبور وارد شدهی معتبر، حتما از جمع حروف کوچک، بزرگ، اعداد و symbols تشکیل شده باشد. برای این منظور میتوان از متد Must استفاده کرد:
using System.Text.RegularExpressions; using FluentValidation; namespace FluentValidationSample.Models { public class RegisterModelValidator : AbstractValidator<RegisterModel> { public RegisterModelValidator() { RuleFor(x => x.Password) .NotNull() .WithMessage("Your password is required.") .Length(6, 100) .Must(password => hasValidPassword(password)); //... } private static bool hasValidPassword(string password) { var lowercase = new Regex("[a-z]+"); var uppercase = new Regex("[A-Z]+"); var digit = new Regex("(\\d)+"); var symbol = new Regex("(\\W)+"); return lowercase.IsMatch(password) && uppercase.IsMatch(password) && digit.IsMatch(password) && symbol.IsMatch(password); } } }
البته lambda expression نوشته شده را میتوان توسط method groups، به صورت زیر نیز خلاصه نوشت:
RuleFor(x => x.Password) .NotNull() .WithMessage("Your password is required.") .Length(6, 100) .Must(hasValidPassword);
اگر نیاز به استفادهی از متد hasValidPassword در کلاسهای دیگری نیز وجود دارد، میتوان اینگونه اعتبارسنجیهای سفارشی را به کلاسهای مجزایی نیز تبدیل کرد. برای مثال فرض کنید که میخواهیم ایمیل دریافت شده، فقط از یک دومین خاص قابل قبول باشد.
using System; using FluentValidation; using FluentValidation.Validators; namespace FluentValidationSample.Models { public class EmailFromDomainValidator : PropertyValidator { private readonly string _domain; public EmailFromDomainValidator(string domain) : base("Email address {PropertyValue} is not from domain {domain}") { _domain = domain; } protected override bool IsValid(PropertyValidatorContext context) { if (context.PropertyValue == null) return false; var split = context.PropertyValue.ToString().Split('@'); return split.Length == 2 && split[1].Equals(_domain, StringComparison.OrdinalIgnoreCase); } } }
PropertyValidatorContext امکان دسترسی به نام و مقدار خاصیت در حال اعتبارسنجی را میسر میکند. همچنین مقدار کل model جاری را نیز به صورت یک object در اختیار ما قرار میدهد.
اکنون برای استفادهی از آن میتوان از متد SetValidator استفاده کرد:
RuleFor(x => x.Email) .SetValidator(new EmailFromDomainValidator("gmail.com"));
public static class CustomValidatorExtensions { public static IRuleBuilderOptions<T, string> EmailAddressFromDomain<T>( this IRuleBuilder<T, string> ruleBuilder, string domain) { return ruleBuilder.SetValidator(new EmailFromDomainValidator(domain)); } }
RuleFor(x => x.Email).EmailAddressFromDomain("gmail.com");
فرض کنید به RegisterModel این قسمت، دو خاصیت آدرس و شماره تلفنها نیز اضافه شدهاست که یکی به شیء آدرس و دیگری به مجموعهای از آدرسها اشاره میکند:
public class RegisterModel { // ... public Address Address { get; set; } public ICollection<Phone> Phones { get; set; } } public class Phone { public string Number { get; set; } public string Description { get; set; } } public class Address { public string Location { get; set; } public string PostalCode { get; set; } }
public class PhoneValidator : AbstractValidator<Phone> { public PhoneValidator() { RuleFor(x => x.Number).NotNull(); } } public class AddressValidator : AbstractValidator<Address> { public AddressValidator() { RuleFor(x => x.PostalCode).NotNull(); RuleFor(x => x.Location).NotNull(); } }
public class RegisterModelValidator : AbstractValidator<RegisterModel> { public RegisterModelValidator() { // ... RuleFor(x => x.Address).SetValidator(new AddressValidator()); RuleForEach(x => x.Phones).SetValidator(new PhoneValidator()); }
در قسمت بعد، روشهای مختلف استفادهی از قواعد اعتبارسنجی تعریف شده را در یک برنامهی ASP.NET Core بررسی میکنیم.
برای مطالعهی بیشتر
- «FluentValidation #1»
« ... حالا بعد از اعمال روش ارائه شده در این مطلب (ذخیرهسازی token و refresh token در دیتابیس) چطور میتوانیم کاربرانی که از توکن قبلی استفاده میکنند را مجبور به Sign out کنیم؟ ...»همان قسمت «تهیه یک اعتبارسنج توکن سفارشی» مطلب جاری هست که از نتیجهی «پیاده سازی Logout» استفاده میکند. یا حتی میتوانید در قسمت logout یک SerialNumber را هم تغییر دهید که به صورت یک Claim سفارشی در توکن قبلی وجود داشته باشد. عدم انطباق این مقادیر را در این اعتبارسنج سفارشی بررسی کنید.
JSON.NET یک کتابخانهی سورس باز کار با اشیاء JSON در دات نت است. تاریخچهی آن به 8 سال قبل بر میگردد و توسط یک برنامه نویس نیوزیلندی به نام James Newton King تهیه شدهاست. اولین نگارش آن در سال 2006 ارائه شد؛ مقارن با زمانی که اولین استاندارد JSON نیز ارائه گردید.
این کتابخانه از آن زمان تا کنون، 6 میلیون بار دانلود شدهاست و به علت کیفیت بالای آن، این روزها پایه اصلی بسیاری از کتابخانهها و فریم ورکهای دات نتی میباشد؛ مانند RavenDB تا ASP.NET Web API و SignalR مایکروسافت و همچنین گوگل نیز از آن جهت تدارک کلاینتهای کار با API خود استفاده میکنند.
هرچند دات نت برای نمونه در نگارش سوم آن جهت مصارف WCF کلاسی را به نام DataContractJsonSerializer ارائه کرد، اما کار کردن با آن محدود است به فرمت خاص WCF به همراه عدم انعطاف پذیری و سادگی کار با آن. به علاوه باید درنظر داشت که JSON.NET از دات نت 2 به بعد تا مونو، Win8 و ویندوز فون را نیز پشتیبانی میکند.
برای نصب آن نیز کافی است دستور ذیل را در کنسول پاورشل نیوگت اجرا کنید:
PM> install-package Newtonsoft.Json
معماری JSON.NET
کتابخانهی JSON.NET از سه قسمت عمده تشکیل شدهاست:
الف) JsonSerializer
ب) LINQ to JSON
ج) JSON Schema
الف) JsonSerializer
کار JsonSerializer تبدیل اشیاء دات نتی به JSON و برعکس است. مزیت مهم آن امکانات قابل توجه تنظیم عملکرد و خروجی آن میباشد که این تنظیمات را به شکل ویژگیهای خواص نیز میتوان اعمال نمود. به علاوه امکان سفارشی سازی هر کدام نیز توسط کلاسی به نام JsonConverter، پیش بینی شدهاست.
یک مثال:
var roles = new List<string> { "Admin", "User" }; string json = JsonConvert.SerializeObject(roles, Formatting.Indented);
و یا در مثال ذیل استفاده از یک anonymous object را مشاهده میکنید:
var jsonString = JsonConvert.SerializeObject(new { Id =1, Name = "Test" }, Formatting.Indented);
تنظیمات پیشرفتهتر JSON.NET
مزیت مهم JSON.NET بر سایر کتابخانههای موجود مشابه، قابلیتهای سفارشی سازی قابل توجه آن است. در مثال ذیل نحوهی معرفی JsonSerializerSettings را مشاهده مینمائید:
var jsonData = JsonConvert.SerializeObject(new { Id = 1, Name = "Test", DateTime = DateTime.Now }, new JsonSerializerSettings { Formatting = Formatting.Indented, Converters = { new JavaScriptDateTimeConverter() } });
{ "Id": 1, "Name": "Test", "DateTime": new Date(1409821985245) }
نوشتن خروجی JSON در یک استریم
خروجی متد JsonConvert.SerializeObject یک رشتهاست که در صورت نیاز به سادگی توسط متد File.WriteAllText در یک فایل قابل ذخیره میباشد. اما برای رسیدن به حداکثر کارآیی و سرعت میتوان از استریمها نیز استفاده کرد:
using (var stream = File.CreateText(@"c:\output.json")) { var jsonSerializer = new JsonSerializer { Formatting = Formatting.Indented }; jsonSerializer.Serialize(stream, new { Id = 1, Name = "Test", DateTime = DateTime.Now }); }
تبدیل JSON رشتهای به اشیاء دات نت
اگر رشتهی jsonData ایی را که پیشتر تولید کردیم، بخواهیم تبدیل به نمونهای از شیء User ذیل کنیم:
public class User { public int Id { set; get; } public string Name { set; get; } public DateTime DateTime { set; get; } }
var user = JsonConvert.DeserializeObject<User>(jsonData);
البته در اینجا با توجه به استفاده از JavaScriptDateTimeConverter برای تولید jsonData، نیاز است چنین تنظیمی را نیز در حالت DeserializeObject مشخص کنیم:
var user = JsonConvert.DeserializeObject<User>(jsonData, new JsonSerializerSettings { Converters = { new JavaScriptDateTimeConverter() } });
مقدار دهی یک نمونه یا وهلهی از پیش موجود
متد JsonConvert.DeserializeObject یک شیء جدید را ایجاد میکند. اگر قصد دارید صرفا تعدادی از خواص یک وهلهی موجود، توسط JSON.NET مقدار دهی شوند از متد PopulateObject استفاده کنید:
JsonConvert.PopulateObject(jsonData, user);
کاهش حجم JSON تولیدی
زمانیکه از متد JsonConvert.SerializeObject استفاده میکنیم، تمام خواص عمومی تبدیل به معادل JSON آنها خواهند شد؛ حتی خواصی که مقدار ندارند. این خواص در خروجی JSON، با مقدار null مشخص میشوند. برای حذف این خواص از خروجی JSON نهایی تنها کافی است در تنظیمات JsonSerializerSettings، مقدار NullValueHandling = NullValueHandling.Ignore مشخص گردد.
var jsonData = JsonConvert.SerializeObject(object, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.Indented });
به علاوه حذف Formatting = Formatting.Indented نیز توصیه میگردد. در این حالت فشردهترین خروجی ممکن حاصل خواهد شد.
مدیریت ارث بری توسط JSON.NET
در مثال ذیل کلاس کارمند و کلاس مدیر را که خود نیز در اصل یک کارمند میباشد، ملاحظه میکنید:
public class Employee { public string Name { set; get; } } public class Manager : Employee { public IList<Employee> Reports { set; get; } }
var employee = new Employee { Name = "User1" }; var manager1 = new Manager { Name = "User2" }; var manager2 = new Manager { Name = "User3" }; manager1.Reports = new[] { employee, manager2 }; manager2.Reports = new[] { employee };
var list = JsonConvert.SerializeObject(manager1, Formatting.Indented);
{ "Reports": [ { "Name": "User1" }, { "Reports": [ { "Name": "User1" } ], "Name": "User3" } ], "Name": "User2" }
- در اینجا مشخص نیست که این اشیاء، کارمند هستند یا مدیر. برای مثال مشخص نیست User2 چه نوعی دارد و باید به کدام شیء نگاشت شود.
- مشکل دوم در مورد کاربر User1 است که در دو قسمت تکرار شدهاست. این شیء JSON اگر به نمونهی معادل دات نتی خود نگاشت شود، به دو وهله از User1 خواهیم رسید و نه یک وهلهی اصلی که سبب تولید این خروجی JSON شدهاست.
برای حل این دو مشکل، تغییرات ذیل را میتوان به JSON.NET اعمال کرد:
var list = JsonConvert.SerializeObject(manager1, new JsonSerializerSettings { Formatting = Formatting.Indented, TypeNameHandling = TypeNameHandling.Objects, PreserveReferencesHandling = PreserveReferencesHandling.Objects });
{ "$id": "1", "$type": "JsonNetTests.Manager, JsonNetTests", "Reports": [ { "$id": "2", "$type": "JsonNetTests.Employee, JsonNetTests", "Name": "User1" }, { "$id": "3", "$type": "JsonNetTests.Manager, JsonNetTests", "Reports": [ { "$ref": "2" } ], "Name": "User3" } ], "Name": "User2" }
- با تنظیم PreserveReferencesHandling = PreserveReferencesHandling.Objects شماره Id خودکاری نیز به خروجی JSON اضافه میگردد. اینبار اگر به گزارش دهندهها با دقت نگاه کنیم، مقدار $ref=2 را خواهیم دید. این مورد سبب میشود تا در حین نگاشت نهایی، دو وهله متفاوت از شیء با Id=2 تولید نشود.
باید دقت داشت که در حین استفاده از JsonConvert.DeserializeObject نیز باید JsonSerializerSettings یاد شده، تنظیم شوند.
ویژگیهای قابل تنظیم در JSON.NET
علاوه بر JsonSerializerSettings که از آن صحبت شد، در JSON.NET امکان تنظیم یک سری از ویژگیها به ازای خواص مختلف نیز وجود دارند.
- برای نمونه ویژگی JsonIgnore معروفترین آنها است:
public class User { public int Id { set; get; } [JsonIgnore] public string Name { set; get; } public DateTime DateTime { set; get; } }
- با استفاده از ویژگی JsonProperty اغلب مواردی را که پیشتر بحث کردیم مانند NullValueHandling، TypeNameHandling و غیره، میتوان تنظیم نمود. همچنین گاهی از اوقات کتابخانههای جاوا اسکریپتی سمت کاربر، از اسامی خاصی که از روشهای نامگذاری دات نتی پیروی نمیکنند، در طراحی خود استفاده میکنند. در اینجا میتوان نام خاصیت نهایی را که قرار است رندر شود نیز صریحا مشخص کرد. برای مثال:
[JsonProperty(PropertyName = "m_name", NullValueHandling = NullValueHandling.Ignore)] public string Name { set; get; }
- استفاده از ویژگی JsonObject به همراه مقدار OptIn آن به این معنا است که از کلیه خواصی که دارای ویژگی JsonProperty نیستند، صرفنظر شود. حالت پیش فرض آن OptOut است؛ یعنی تمام خواص عمومی در خروجی JSON حضور خواهند داشت منهای مواردی که با JsonIgnore مزین شوند.
[JsonObject(MemberSerialization.OptIn)] public class User { public int Id { set; get; } [JsonProperty] public string Name { set; get; } public DateTime DateTime { set; get; } }
- با استفاده از ویژگی JsonConverter میتوان نحوهی رندر شدن مقدار خاصیت را سفارشی سازی کرد. برای مثال:
[JsonConverter(typeof(JavaScriptDateTimeConverter))] public DateTime DateTime { set; get; }
تهیه یک JsonConverter سفارشی
با استفاده از JsonConverterها میتوان کنترل کاملی را بر روی اعمال serialization و deserialization مقادیر خواص اعمال کرد. مثال زیر را در نظر بگیرید:
public class HtmlColor { public int Red { set; get; } public int Green { set; get; } public int Blue { set; get; } } var colorJson = JsonConvert.SerializeObject(new HtmlColor { Red = 255, Green = 0, Blue = 0 }, Formatting.Indented);
public class HtmlColorConverter : JsonConverter { public override bool CanConvert(Type objectType) { return objectType == typeof(HtmlColor); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { throw new NotSupportedException(); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { var color = value as HtmlColor; if (color == null) return; writer.WriteValue("#" + color.Red.ToString("X2") + color.Green.ToString("X2") + color.Blue.ToString("X2")); } }
از آنجائیکه این تبدیلگر صرفا قرار است برای حالت serialization استفاده شود، قسمت ReadJson آن پیاده سازی نشدهاست.
در آخر برای استفاده از آن خواهیم داشت:
var colorJson = JsonConvert.SerializeObject(new HtmlColor { Red = 255, Green = 0, Blue = 0 }, new JsonSerializerSettings { Formatting = Formatting.Indented, Converters = { new HtmlColorConverter() } });
تولید کد اتوماتیک MVVM با Roslyn