اشتراکها
نظرات مطالب
ASP.NET MVC #7
مباحث اعتبارسنجی در MVC را مطالعه کنید. پایه آن همین مطالب است. پس از اعتبارسنجی کاربر، در یک View میشود ساده if و else نوشت. مثلا:
در این حالت اگر کاربر به سیستم لاگین کرده باشد و همچنین نقش Administrator نیز به او پیشتر انتساب داده شده باشد، اطلاعات خاصی را مشاهده خواهد کرد.
@if (User.Identity.IsAuthenticated && User.IsInRole("Administrator")) { <div id="sidebar"> data </div> }
با تشکر
اگر دیتابیس تغییر کند باید PartialClass تغییر را دستی تغییر بدهیم؟ اگر پاسخ بله میباشد راهی وجود دارد برای اعمال تغییر ات به صورت خودکار؟
ایا توصیه میشود از view model به جای PartialClass برای اعتبارسنجی استفاده شود؟
اگر دیتابیس تغییر کند باید PartialClass تغییر را دستی تغییر بدهیم؟ اگر پاسخ بله میباشد راهی وجود دارد برای اعمال تغییر ات به صورت خودکار؟
ایا توصیه میشود از view model به جای PartialClass برای اعتبارسنجی استفاده شود؟
در قسمت قبل، مروری داشتیم بر تفاوتهای دو نوع مختلف فناوریهای ایجاد و مدیریت فرمها در Angular و هچنین ساختار ابتدایی برنامهی این سری را ایجاد کردیم. در ادامه، اولین فرم مبتنی بر قالبها را ایجاد خواهیم کرد.
ایجاد اولین فرم مبتنی بر قالبها
پس از ایجاد کامپوننت employee-register، فایل قالب آن یا src\app\employee\employee-register\employee-register.component.html را گشوده و به نحو ذیل تکمیل میکنیم:
زمانیکه المان فرم به صفحه اضافه میشود، Angular به صورت خودکار دایرکتیو مرتبطی را به فرم اضافه میکند. برای دسترسی به این دایرکتیو نیاز است یک template reference variable را تعریف کرد. برای مثال "form="ngForm# به معنای تعریف متغیر form است که به دایرکتیو توکار ngForm متصل شدهاست و اکنون حاوی وهلهای از این دایرکتیو میباشد. به همین جهت است که امکان دسترسی به اطلاعات این وهله توسط درج form.pristine در همان قالب وجود دارد.
خاصیت pristine مشخص میکند که آیا فرم توسط کاربر تغییر یافتهاست یا خیر؟
مقدار خاصیت pristine در ابتدای کار true است؛ به این معنا که هنوز تغییری در آن اعمال نشدهاست.
یک نکته: ممکن است در حین توسعهی برنامه، خطای ذیل را در کنسول developer tools مرورگرها مشاهده کنید:
این دایرکتیو تنها زمانی قابل دسترسی است که در قسمت imports ماژول جاری که با آن کار میکنید، تعریف FormsModule را به همان نحوی که در انتهای قسمت قبل بررسی کردیم (قسمت «افزودن ماژول فرمها به برنامه»)، افزوده باشید.
در ادامه، در همین فرمی که تعاریف آنرا در بالا مشاهده میکنید، اطلاعاتی را وارد نمائید. هنوز هم مقدار خاصیت pristine مساوی true است. علت اینجا است که هنوز به Angular اعلام نکردهایم که کدام فیلد یا فیلدهای فرم را باید تحت نظر قرار دهد. برای این منظور ابتدا به المان تعریف شده نامی را انتساب داده و سپس دایرکتیو ngModel را نیز به انتهای تعاریف آن اضافه میکنیم:
اکنون اگر مقدار فرم را تغییر دهیم، مشاهده خواهیم کرد که مقدار خاصیتpristine به false تغییر میکند:
یک نکته: زمانیکه دایرکتیو ngModel ذکر میشود، تعریف name المان متناظر با آن، الزامی است؛ در غیراینصورت خطای ذیل را در کنسول developer tools مرورگرها مشاهده خواهید کرد:
خاموش کردن اعتبارسنجی توکار مرورگرها
یکی از کارهایی را که نیاز است در حین کار با فرمها انجام داد، خاموش کردن اعتبارسنجی توکار مرورگرها است. فرض کنید ویژگی معتبر و استاندارد required را به یکی از المانهای ورودی اضافه کردهاید:
در این حالت اگر برنامه را اجرا کنید و بدون تکمیل این فیلد بر روی دکمهی ارسال فرم کلیک نمائید، به ازای مرورگرهای مختلف، پیام انگلیسی «لطفا این فیلد را تکمیل کنید» ظاهر خواهد شد و هر کدام شکل متفاوتی را دارند که جزئیات آنها را نمیتوان تغییر داد و یا سفارشی سازی کرد. به این مورد، browser validation میگویند. به همین جهت برای خاموش کردن این اعتبارسنجی توکار مرورگرها و ارائهی تجربهی کاربری یکنواخت و یکدستی در تمام مرورگرها، نیاز است ویژگی novalidate را به تگ فرم اضافه کرد:
هر دوی ویژگیهای novalidate و یاrequired ، جزو استاندارد HTML هستند و ارتباطی به Angular ندارند.
بهبود ظاهر فرم توسط اعمال شیوهنامههای بوت استرپ
در قسمت قبل، در ابتدای کار تدارک ساختار مثال این سری، بوت استرپ را نیز نصب و تنظیم کردیم. در ادامه میخواهیم اندکی ظاهر این فرم را بر اساس شیوهنامههای بوت استرپ بهبود ببخشیم:
- برای افزودن بوت استرپ نیازی نیست تا شیوهنامهی آنرا به صورت دستی به Index.html برنامه اضافه کرد. همینقدر که ارجاعی از آن در فایل angular-cli.json. در قسمت شیوهنامههای آن وجود داشته باشد، به صورت خودکار در bundle نهایی تولید شدهی توسط سیستم ساخت برنامهی Angular CLI ظاهر خواهد شد.
- در اینجا ابتدا فرم خود را در داخل یک container قرار دادهایم. این مورد سبب میشود تا محتوای آن به میانهی صفحه منتقل شود.
- سپس شیوهنامهی btn به دکمهی ارسال فرم اضافه شدهاست تا شکل دکمههای بوت استرپ را پیدا کند.
- سپس هر فیلد ورودی داخل یک div با کلاس form-group محصور میشود و هر کنترل، کلاس form-control را خواهد یافت.
افزودن سایر المانهای ورودی به فرم
تا اینجا دو text box را به فرم اضافه کردهایم. در ادامه میخواهیم المانهای دیگری را نیز تعریف کنیم:
افزودن Check boxes
چون با بوت استرپ کار میکنیم، نیاز است المان ورودی از نوع checkbox را داخل یک div با کلاس checkbox محصور کنیم. سپس یک label را تعریف کرده و Input را داخل آن قرار دهیم. در اینجا نیز همانند سایر المانها نیاز است نامی را به آن انتساب داده و سپس دایرکتیو ngModel را قید نمود تا Angular این کنترل را تحت نظر قرار دهد.
افزودن Radio buttons
Radio buttons نیز شبیه به Check boxها تعریف میشوند. در اینجا نیز یک div با کلاس radio و سپس label ایی که المان ورودی از نوع radio داخل آن قرار میگیرد، افزوده خواهد شد. فقط در اینجا باید دقت داشت که گروه بندی این المانها بر اساس نام آنها انجام میشود. به همین جهت است که نام این دو المان یکی وارد شدهاست. همچنین باید value آنرا نیز تنظیم کرد. این مقداری است که در نهایت به سرور ارسال خواهد شد.
افزودن Drop downs
در اینجا از المان select برای تشکیل یک drop down استفاده میکنیم و نحوهی تعریف آن بسیار شبیه است به تعریف text boxهایی که داخل form-group محصور شده و همچنین کلاس form-control را پیدا میکنند.
اما قسمت مهم آن، اطلاعاتی است که قرار است در این drop down نمایش داده شوند. این اطلاعات را میتوان از آرایهی languages گرفت و سپس توسط یک ngFor به المان select اضافه کرد. بنابراین باید به فایل employee-register.component.ts مراجعه کرده و آرایهی languages را به آن افزود:
کاری که در اینجا انجام میشود، تکرار المان option توسط ngFor است. برای مثال در اینجا 4 بار المان option توسط عناصر آرایهی زبانها در داخل المان select تکرار خواهد شد. به عبارتی select نهایی رندر شدهی در صفحه، چنین شکلی را پیدا میکند:
تا اینجا فرم تشکیل شدهی ما چنین نمایی را پیدا میکند:
در قسمت بعد این فرم را توسط مباحث data binding و بررسی نحوهی دسترسی به اطلاعات آن در کامپوننت مرتبط، تکمیل خواهیم کرد.
کدهای کامل این قسمت را از اینجا میتوانید دریافت کنید: angular-template-driven-forms-lab-02.zip
برای اجرای آن فرض بر این است که پیشتر Angular CLI را نصب کردهاید. سپس از طریق خط فرمان به ریشهی پروژه وارد شده و دستور npm install را صادر کنید تا وابستگیهای آن دریافت و نصب شوند. در آخر با اجرای دستور ng serve -o برنامه ساخته شده و در مرورگر پیش فرض سیستم نمایش داده خواهد شد.
ایجاد اولین فرم مبتنی بر قالبها
پس از ایجاد کامپوننت employee-register، فایل قالب آن یا src\app\employee\employee-register\employee-register.component.html را گشوده و به نحو ذیل تکمیل میکنیم:
<h3>Angular Forms</h3> <form #form="ngForm"> <input type="text" placeholder="Name"> <button type="submit">Ok</button> </form> form.pristine: {{ form.pristine }}
خاصیت pristine مشخص میکند که آیا فرم توسط کاربر تغییر یافتهاست یا خیر؟
مقدار خاصیت pristine در ابتدای کار true است؛ به این معنا که هنوز تغییری در آن اعمال نشدهاست.
یک نکته: ممکن است در حین توسعهی برنامه، خطای ذیل را در کنسول developer tools مرورگرها مشاهده کنید:
There is no directive with "exportAs" set to "ngForm"
در ادامه، در همین فرمی که تعاریف آنرا در بالا مشاهده میکنید، اطلاعاتی را وارد نمائید. هنوز هم مقدار خاصیت pristine مساوی true است. علت اینجا است که هنوز به Angular اعلام نکردهایم که کدام فیلد یا فیلدهای فرم را باید تحت نظر قرار دهد. برای این منظور ابتدا به المان تعریف شده نامی را انتساب داده و سپس دایرکتیو ngModel را نیز به انتهای تعاریف آن اضافه میکنیم:
<h3>Angular Forms</h3> <form #form="ngForm"> <input type="text" placeholder="Name" name="name" ngModel> <button type="submit">Ok</button> </form> form.pristine: {{ form.pristine }}
اکنون اگر مقدار فرم را تغییر دهیم، مشاهده خواهیم کرد که مقدار خاصیتpristine به false تغییر میکند:
یک نکته: زمانیکه دایرکتیو ngModel ذکر میشود، تعریف name المان متناظر با آن، الزامی است؛ در غیراینصورت خطای ذیل را در کنسول developer tools مرورگرها مشاهده خواهید کرد:
Error: If ngModel is used within a form tag, either the name attribute must be set or the form control must be defined as 'standalone' in ngModelOptions.
خاموش کردن اعتبارسنجی توکار مرورگرها
یکی از کارهایی را که نیاز است در حین کار با فرمها انجام داد، خاموش کردن اعتبارسنجی توکار مرورگرها است. فرض کنید ویژگی معتبر و استاندارد required را به یکی از المانهای ورودی اضافه کردهاید:
<input type="text" required placeholder="Name" name="name" ngModel>
<form #form="ngForm" novalidate>
بهبود ظاهر فرم توسط اعمال شیوهنامههای بوت استرپ
در قسمت قبل، در ابتدای کار تدارک ساختار مثال این سری، بوت استرپ را نیز نصب و تنظیم کردیم. در ادامه میخواهیم اندکی ظاهر این فرم را بر اساس شیوهنامههای بوت استرپ بهبود ببخشیم:
<div class="container"> <h3>Angular Forms</h3> <form #form="ngForm" novalidate> <div class="form-group"> <label>First Name</label> <input type="text" class="form-control" required name="firstName" ngModel> </div> <div class="form-group"> <label>Last Name</label> <input type="text" class="form-control" required name="lastName" ngModel> </div> <button class="btn btn-primary" type="submit">Ok</button> </form> </div> form.pristine: {{ form.pristine }}
- برای افزودن بوت استرپ نیازی نیست تا شیوهنامهی آنرا به صورت دستی به Index.html برنامه اضافه کرد. همینقدر که ارجاعی از آن در فایل angular-cli.json. در قسمت شیوهنامههای آن وجود داشته باشد، به صورت خودکار در bundle نهایی تولید شدهی توسط سیستم ساخت برنامهی Angular CLI ظاهر خواهد شد.
- در اینجا ابتدا فرم خود را در داخل یک container قرار دادهایم. این مورد سبب میشود تا محتوای آن به میانهی صفحه منتقل شود.
- سپس شیوهنامهی btn به دکمهی ارسال فرم اضافه شدهاست تا شکل دکمههای بوت استرپ را پیدا کند.
- سپس هر فیلد ورودی داخل یک div با کلاس form-group محصور میشود و هر کنترل، کلاس form-control را خواهد یافت.
افزودن سایر المانهای ورودی به فرم
تا اینجا دو text box را به فرم اضافه کردهایم. در ادامه میخواهیم المانهای دیگری را نیز تعریف کنیم:
افزودن Check boxes
<div class="checkbox"> <label> <input type="checkbox" name="is-full-time" ngModel> Full Time Employee </label> </div>
افزودن Radio buttons
<label>Payment Type</label> <div class="radio"> <label> <input type="radio" name="pay-type" value="FullTime" checked> Full Time </label> </div> <div class="radio"> <label> <input type="radio" name="pay-type" value="PartTime"> Part Time </label> </div>
افزودن Drop downs
<div class="form-group"> <label>Primary Language</label> <select class="form-control"> <option *ngFor="let lang of languages"> {{ lang }} </option> </select> </div>
اما قسمت مهم آن، اطلاعاتی است که قرار است در این drop down نمایش داده شوند. این اطلاعات را میتوان از آرایهی languages گرفت و سپس توسط یک ngFor به المان select اضافه کرد. بنابراین باید به فایل employee-register.component.ts مراجعه کرده و آرایهی languages را به آن افزود:
export class EmployeeRegisterComponent implements OnInit { languages = ["Persian", "English", "Spanish", "Other"];
<select class="form-control"> <option>Persian</option> <option>English</option> <option>Spanish</option> <option>Other</option> </select>
تا اینجا فرم تشکیل شدهی ما چنین نمایی را پیدا میکند:
در قسمت بعد این فرم را توسط مباحث data binding و بررسی نحوهی دسترسی به اطلاعات آن در کامپوننت مرتبط، تکمیل خواهیم کرد.
کدهای کامل این قسمت را از اینجا میتوانید دریافت کنید: angular-template-driven-forms-lab-02.zip
برای اجرای آن فرض بر این است که پیشتر Angular CLI را نصب کردهاید. سپس از طریق خط فرمان به ریشهی پروژه وارد شده و دستور npm install را صادر کنید تا وابستگیهای آن دریافت و نصب شوند. در آخر با اجرای دستور ng serve -o برنامه ساخته شده و در مرورگر پیش فرض سیستم نمایش داده خواهد شد.
اشتراکها
کتابخانه jcarousellite
jCarousel Lite is a jQuery plugin that carries you on a carousel
ride filled with images and HTML content. Put simply, you can navigate
images and/or HTML in a carousel-style widget. Demo
مسیرراهها
Blazor 5x
مبانی Blazor
- قسمت 4 : بخش 1 - Data Binding
- قسمت 5 : بخش 2 - کامپوننتها
- قسمت 6 : بخش 3 - چرخههای حیات کامپوننتها
- قسمت 7 : بخش 4 - انتقال اطلاعات از کامپوننتهای فرزند به کامپوننت والد
- قسمت 8 : بخش 5 - تامین محتوای نمایشی کامپوننتهای فرزند توسط کامپوننت والد
- قسمت 9 : بخش 6 - ساده سازی تعاریف ویژگیهای المانها و انتقال پارامترها به چندین زیر سطح
- قسمت 10 : بخش 7 - مسیریابی
- قسمت 11 : بخش 8 - کار با جاوا اسکریپت
- قسمت 12 : بخش 9 - یک تمرین
کار با فرمها
- قسمت 13 : بخش 1 - کار با EF Core در برنامههای Blazor Server
- قسمت 14 : بخش 2 - تعریف فرمها و اعتبارسنجی آنها
- قسمت 15 : بخش 3 - ویرایش اطلاعات
- قسمت 16 : بخش 4 - تهیه سرویسهای آپلود تصاویر
- قسمت 17 : بخش 5 - آپلود تصاویر
- قسمت 18 : بخش 6 - حذف اطلاعات
- قسمت 19 : بخش 7 - نکات ویژهی کار با EF-Core در برنامههای Blazor Server
- قسمت 20 : بخش 8 - استفاده از یک کامپوننت ثالث HTML Editor
احراز هویت و اعتبارسنجی کاربران Blazor Server
- قسمت 21 : بخش 1 - افزودن قالب ابتدایی Identity
- قسمت 22 : بخش 2 - ورود به سیستم و خروج از آن
- قسمت 23 : بخش 3 - کار با نقشهای کاربران
تهیه API مخصوص Blazor WASM
Blazor WASM
- قسمت 26 : ایجاد و تنظیمات اولیه
- قسمت 27 : کار با سرویسهای Web API
- قسمت 28 : نمایش لیست اطلاعات دریافتی از Web API
- قسمت 29 : یک تمرین: رزرو کردن یک اتاق انتخابی
- قسمت 30 : افزودن پرداخت آنلاین توسط درگاه مجازی پرباد
احراز هویت و اعتبارسنجی کاربران Blazor WASM
- قسمت 31 : بخش 1 - انجام تنظیمات اولیه
- قسمت 32 : بخش 2 - ثبت نام، ورود به سیستم و خروج از آن
- قسمت 33 : بخش 3 - بهبود تجربهی کاربری عدم دسترسیها
- پیاده سازی سیاستهای دسترسی پویای سمت سرور و کلاینت در برنامههای Blazor WASM
توزیع برنامه
مدیریت استثناءها
بررسی تغییرات Blazor 8x
- قسمت اول : معرفی SSR
- قسمت دوم : بررسی حالت رندر سمت سرور
- قسمت سوم : روش ارتقاء برنامههای Blazor Server قدیمی به دات نت 8
- قسمت چهارم : معرفی فرمهای جدید تعاملی
- قسمت پنجم : امکان تعریف جزیرههای تعاملی Blazor Server
- قسمت ششم : نکات تکمیلی ویژگی راهبری بهبود یافتهی صفحات SSR
- قسمت هفتم : امکان تعریف جزیرههای تعاملی Blazor WASM
- قسمت هشتم : مدیریت انتقال اطلاعات Pre-Rendering سمت سرور، به جزایر تعاملی
- قسمت نهم : معرفی حالت رندر تعاملی خودکار
- قسمت دهم : مدیریت حالت کاربران در روشهای مختلف رندر
- قسمت یازدهم : قالب جدید پیاده سازی اعتبارسنجی و احراز هویت - بخش اول
- قسمت دوازدهم : قالب جدید پیاده سازی اعتبارسنجی و احراز هویت - بخش دوم
- قسمت سیزدهم : امکان تعریف Sections
- قسمت چهاردهم : امکان استفاده از کامپوننتهای Blazor در برنامههای ASP.NET Core 8x
مطالب تکمیلی
- Best practiceهای یک پروژه Blazor
- کامپوننتهای جنریک در Blazor
- مدیریت حالت در برنامههای Blazor توسط الگوی Observer - قسمت اول
- مدیریت حالت در برنامههای Blazor توسط الگوی Observer - قسمت دوم
- روش آپلود فایلها به همراه اطلاعات یک مدل در برنامههای Blazor WASM 5x
- دریافت و نمایش فایلهای PDF در برنامههای Blazor WASM
- ارسال خطاهای رخدادهی در برنامههای سمت کلاینت Blazor WASM، به تلگرام
- بهبود کارآیی نمایش لیستها در Blazor با استفاده از دایرکتیو key@
- معرفی Blazor Hybrid
- امکان استفاده از کتابخانههای native در Blazor WASM 6x
- امکان ساخت برنامههای دسکتاپ چندسکویی Blazor در دات نت 6
- حل مشکل بارگذاری اولیه دستورات جاوا اسکریپتی در پروژههای Blazor
- پیاده سازی Remote Validation در Blazor
- روش ایجاد پروژههای کتابخانهای کامپوننتهای Blazor
- استفاده از date picker شمسی جاوا اسکریپتی در Blazor با قابلیت ورود تاریخ به صورت دستی
- ارائهی قالبی عمومی برای استفاده از تقویمهای جاوااسکریپتی در Blazor
- بهبود صفحهی بارگذاری اولیه در Blazor WASM
- استفاده از چند دکمه با عملکردهای مختلف برای ارسال یک EditForm در Blazor
- دستیابی به HttpContext در Blazor Server
- جلوگیری از دوباره اجرا شدن ناخواستهی متدهای نامتقارن در Blazor
- نکات ویژه کار با عملیات نامتقارن در Blazor Server
- استفاده از لنگر (anchor) برای اسکرول به قسمت خاصی از صفحه در Blazor Server
در این قسمت قصد داریم ساختار مقدماتی مثال این سری را که لیستی از تصاویر آپلود شدهی توسط کاربران مختلف را نمایش میدهد، بدون افزودن مباحث امنیتی و سطوح دسترسی کاربران وارد شدهی به سیستم، تشکیل دهیم. در قسمتهای بعدی، به تدریج آنرا با قابلیتهای مختلف IdentityServer 4x یکپارچه خواهیم کرد. در اینجا فرض بر این است که حداقل SDK نگارش 2.1.401 را پیشتر نصب کردهاید.
بررسی ساختار WebAPI مقدماتی مثال این سری
این پروژهی مقدماتی که هنوز قسمتهای اعتبارسنجی به آن اضافه نشدهاند، از دو قسمت WebApi و MvcClient تشکیل میشود.
کار قسمت WebApi، ارائهی یک Restful-API برای کار با گالری تصاویر است. برای اجرای آن وارد پوشهی src\WebApi\ImageGallery.WebApi.WebApp شده و ابتدا فایل restore.bat و سپس dotnet_run.bat را اجرا کنید.
در این حالت برنامه بر روی پورت 7001 در دسترس خواهد بود:
این پورت نیز در فایل Properties\launchSettings.json تنظیم شدهاست تا با پورت کلاینت MVC تهیه شده، تداخل نکند.
کار این سرویس، ارائهی ImagesController است که توسط آن میتوان لیستی از تصاویر موجود، اطلاعات یک تصویر و همچنین کار ثبت، ویرایش و حذف تصاویر را انجام داد.
در این Solution، رکوردهای تصاویری که در بانک اطلاعاتی ذخیره میشوند، یک چنین ساختاری را دارند:
همانطور که ملاحظه میکنید در اینجا OwnerId نیز در نظر گرفته شدهاست تا بتوان پس از اعمال مباحث اعتبارسنجی، تصاویر را از کاربری خاص دریافت و همچنین صرفا تصاویر متعلق به او را به آن کاربر خاص نمایش داد.
در این قسمت توسط کلاس ImageConfiguration کار مقدار دهی اولیهی بانک اطلاعاتی به کمک متد HasData مربوط به EF Core 2.1 صورت گرفتهاست و به این ترتیب میتوان برنامه را برای نمایش مقدماتی جاری، بدون داشتن سیستم اعتبارسنجی و مفاهیم کاربران، نمایش داد.
این قسمت از Solution، به نحو زیر تشکیل شدهاست:
- ImageGallery.WebApi.DataLayer
در اینجا کار تشکیل DbContext برنامه و همچنین مقدار دهی اولیهی بانک اطلاعاتی و تنظیمات Migrations قرار گرفتهاند.
- ImageGallery.WebApi.DomainClasses
در این پروژه کلاسهای موجودیتهای متناظر با جداول بانک اطلاعاتی قرار میگیرند.
- ImageGallery.WebApi.Mappings
این پروژه کار تهیه نگاشتهای AutoMapper برنامه را انجام میدهد؛ نگاشتهایی بین Models و DomainClasses که در ImagesController از آنها استفاده میشود.
- ImageGallery.WebApi.Models
در این پروژه همان DTO's پروژه قرار گرفتهاند. جهت رعایت مسایل امنیتی نباید کلاس موجودیت Image فوق را مستقیما در معرض دید API عمومی قرار داد. به همین جهت تعدادی Model در اینجا تعریف شدهاند که هم برای ثبت، ویرایش و حذف اطلاعات بکار میروند و هم جهت گزارشگیری از رکوردهای موجود جدول تصاویر.
- ImageGallery.WebApi.Services
در این پروژه کار با DbContext انجام شده و توسط آن اطلاعات تصاویر به بانک اطلاعاتی اضافه شده و یا واکشی میشوند.
- ImageGallery.WebApi.WebApp
این پروژه، همان پروژهی اصلی است که سایر قسمتهای یاد شده را در کنار هم قرار داده و به صورت یک Restful-API ارائه میدهد.
بررسی ساختار MvcClient مقدماتی مثال این سری
پس از اجرای WebAPI و آماده بودن آن جهت استفاده، اکنون یک کلاینت ASP.NET Core MVC را جهت کار با امکانات ImagesController آن، تدارک دیدهایم.
برای اجرای آن وارد پوشهی src\MvcClient\ImageGallery.MvcClient.WebApp شده و ابتدا فایل restore.bat و سپس dotnet_run.bat را اجرا کنید.
در این حالت برنامه بر روی پورت 5001 در دسترس خواهد بود:
این پورت نیز در فایل Properties\launchSettings.json تنظیم شدهاست.
در اینجا نمایی از اجرای این برنامه را مشاهده میکنید که لیستی از تصاویر را توسط GalleryController، از سرویس ImagesController مربوط به WebAPI، دریافت کرده و سپس نمایش میدهد. در این لیست تصاویر تمام کاربران با هم نمایش داده شدهاند و هنوز امکان فیلتر کردن آنها بر اساس کاربران وارد شدهی به سیستم را نداریم که در قسمتهای بعدی آنها را تکمیل خواهیم کرد.
این قسمت از Solution به نحو زیر تشکیل شدهاست:
- ImageGallery.MvcClient.Services
در اینجا یک Typed HTTP Client مخصوص NET Core 2.1. را تهیه کردهایم. این سرویس جهت دسترسی به آدرس https://localhost:7001 که WebAPI برنامه در آن قرار دارد، تشکیل شدهاست. روش ثبت مخصوص آنرا نیز در فایل آغازین پروژهی MvcClient.WebApp توسط متد services.AddHttpClient ملاحظه میکنید.
- ImageGallery.MvcClient.ViewModels
مدلهای متناظر با ساختار Viewهای Razor برنامهی وب، در اینجا قرار میگیرند.
- ImageGallery.MvcClient.WebApp
این پروژه، همان پروژهی اصلی است که سایر قسمتهای یاد شده را در کنار هم قرار داده و به صورت یک برنامهی MVC قابل مرور در مرورگر، ارائه میدهد.
کدهای کامل این قسمت را از اینجا میتوانید دریافت کنید.
برای اجرای آن ابتدا باید پروژهی WebApi.WebApp را اجرا کنید و سپس پروژهی MvcClient.WebApp.
بررسی ساختار WebAPI مقدماتی مثال این سری
این پروژهی مقدماتی که هنوز قسمتهای اعتبارسنجی به آن اضافه نشدهاند، از دو قسمت WebApi و MvcClient تشکیل میشود.
کار قسمت WebApi، ارائهی یک Restful-API برای کار با گالری تصاویر است. برای اجرای آن وارد پوشهی src\WebApi\ImageGallery.WebApi.WebApp شده و ابتدا فایل restore.bat و سپس dotnet_run.bat را اجرا کنید.
در این حالت برنامه بر روی پورت 7001 در دسترس خواهد بود:
این پورت نیز در فایل Properties\launchSettings.json تنظیم شدهاست تا با پورت کلاینت MVC تهیه شده، تداخل نکند.
کار این سرویس، ارائهی ImagesController است که توسط آن میتوان لیستی از تصاویر موجود، اطلاعات یک تصویر و همچنین کار ثبت، ویرایش و حذف تصاویر را انجام داد.
در این Solution، رکوردهای تصاویری که در بانک اطلاعاتی ذخیره میشوند، یک چنین ساختاری را دارند:
using System; using System.ComponentModel.DataAnnotations; namespace ImageGallery.WebApi.DomainClasses { public class Image { [Key] public Guid Id { get; set; } [Required] [MaxLength(150)] public string Title { get; set; } [Required] [MaxLength(200)] public string FileName { get; set; } [Required] [MaxLength(50)] public string OwnerId { get; set; } } }
در این قسمت توسط کلاس ImageConfiguration کار مقدار دهی اولیهی بانک اطلاعاتی به کمک متد HasData مربوط به EF Core 2.1 صورت گرفتهاست و به این ترتیب میتوان برنامه را برای نمایش مقدماتی جاری، بدون داشتن سیستم اعتبارسنجی و مفاهیم کاربران، نمایش داد.
این قسمت از Solution، به نحو زیر تشکیل شدهاست:
- ImageGallery.WebApi.DataLayer
در اینجا کار تشکیل DbContext برنامه و همچنین مقدار دهی اولیهی بانک اطلاعاتی و تنظیمات Migrations قرار گرفتهاند.
- ImageGallery.WebApi.DomainClasses
در این پروژه کلاسهای موجودیتهای متناظر با جداول بانک اطلاعاتی قرار میگیرند.
- ImageGallery.WebApi.Mappings
این پروژه کار تهیه نگاشتهای AutoMapper برنامه را انجام میدهد؛ نگاشتهایی بین Models و DomainClasses که در ImagesController از آنها استفاده میشود.
- ImageGallery.WebApi.Models
در این پروژه همان DTO's پروژه قرار گرفتهاند. جهت رعایت مسایل امنیتی نباید کلاس موجودیت Image فوق را مستقیما در معرض دید API عمومی قرار داد. به همین جهت تعدادی Model در اینجا تعریف شدهاند که هم برای ثبت، ویرایش و حذف اطلاعات بکار میروند و هم جهت گزارشگیری از رکوردهای موجود جدول تصاویر.
- ImageGallery.WebApi.Services
در این پروژه کار با DbContext انجام شده و توسط آن اطلاعات تصاویر به بانک اطلاعاتی اضافه شده و یا واکشی میشوند.
- ImageGallery.WebApi.WebApp
این پروژه، همان پروژهی اصلی است که سایر قسمتهای یاد شده را در کنار هم قرار داده و به صورت یک Restful-API ارائه میدهد.
بررسی ساختار MvcClient مقدماتی مثال این سری
پس از اجرای WebAPI و آماده بودن آن جهت استفاده، اکنون یک کلاینت ASP.NET Core MVC را جهت کار با امکانات ImagesController آن، تدارک دیدهایم.
برای اجرای آن وارد پوشهی src\MvcClient\ImageGallery.MvcClient.WebApp شده و ابتدا فایل restore.bat و سپس dotnet_run.bat را اجرا کنید.
در این حالت برنامه بر روی پورت 5001 در دسترس خواهد بود:
این پورت نیز در فایل Properties\launchSettings.json تنظیم شدهاست.
در اینجا نمایی از اجرای این برنامه را مشاهده میکنید که لیستی از تصاویر را توسط GalleryController، از سرویس ImagesController مربوط به WebAPI، دریافت کرده و سپس نمایش میدهد. در این لیست تصاویر تمام کاربران با هم نمایش داده شدهاند و هنوز امکان فیلتر کردن آنها بر اساس کاربران وارد شدهی به سیستم را نداریم که در قسمتهای بعدی آنها را تکمیل خواهیم کرد.
این قسمت از Solution به نحو زیر تشکیل شدهاست:
- ImageGallery.MvcClient.Services
در اینجا یک Typed HTTP Client مخصوص NET Core 2.1. را تهیه کردهایم. این سرویس جهت دسترسی به آدرس https://localhost:7001 که WebAPI برنامه در آن قرار دارد، تشکیل شدهاست. روش ثبت مخصوص آنرا نیز در فایل آغازین پروژهی MvcClient.WebApp توسط متد services.AddHttpClient ملاحظه میکنید.
- ImageGallery.MvcClient.ViewModels
مدلهای متناظر با ساختار Viewهای Razor برنامهی وب، در اینجا قرار میگیرند.
- ImageGallery.MvcClient.WebApp
این پروژه، همان پروژهی اصلی است که سایر قسمتهای یاد شده را در کنار هم قرار داده و به صورت یک برنامهی MVC قابل مرور در مرورگر، ارائه میدهد.
کدهای کامل این قسمت را از اینجا میتوانید دریافت کنید.
برای اجرای آن ابتدا باید پروژهی WebApi.WebApp را اجرا کنید و سپس پروژهی MvcClient.WebApp.
- مباحث اعتبارسنجی سمت کلاینت در اینجا بحث شدند.
+ بجای مقدار رشتهای "Null" (که یک مقدار واقعی و غیرنال هست)، از "" استفاده کنید (مقدار خالی). اگر مقدار انتخاب شدهی یک drop down خالی باشد، نال ترجمه میشود. بعد هم از NotEmpty برای بررسی آن استفاده کنید:
RuleFor(x => x.StringField).NotNull().NotEmpty().WithMessage("...");
جهت مباحث تکمیلی اعتبارسنجی کاربران به این مطالب مراجعه کنید:
- اعتبار سنجی کاربران در ASP.NET MVC
- مدیریت سفارشی سطوح دسترسی کاربران در MVC
- Iris Membership برای احراز هویت کاربران در ASP.NET MVC به صورت پویا
- ASP.NET Identity
- اعتبار سنجی کاربران در ASP.NET MVC
- مدیریت سفارشی سطوح دسترسی کاربران در MVC
- Iris Membership برای احراز هویت کاربران در ASP.NET MVC به صورت پویا
- ASP.NET Identity
نظرات مطالب
مقابله با XSS ؛ یکبار برای همیشه!
سلام. مدل برنامه من به شرح زیر است:
و برای فیلد Content یک TextArea قرار دادم که به Froala متصل شده و برای ذخیره اکشن زیر رو نوشتم
مشکل اینجاست که وقتی از Froala استفاده میکنم تابع ToSafeHtml از کتابخانه AntiXss مایکروسافت و ToSafeHtml مطرح شده در این بحث هیچ تاثیری روی فیلد Content نداره اما وقتی Froala را با TextArea جایگزین میکنم همه چی درست میشه. میخواستم ببینم چطور میشه این مشکل رو برطرف کرد؟
public class Post { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int PostId { get; set; } [Required(ErrorMessage = "فیلد عنوان الزامی است")] [Display(Name = "عنوان پست")] public string PostTitle { get; set; } [Display(Name = "محتوا")] [AllowHtml] public string Content { get; set; } [DataType(DataType.Date)] [Display(Name = "تاریخ نشر")] public DateTime PublishDate { get; set; } }
[HttpPost] public ActionResult CreateNewPost(Post post) { if (ModelState.IsValid) { post.Content = post.Content.ToSafeHtml(); PostData.AddNewPost(post); return RedirectToAction("Index", "Home", new { area = "" }); } return View(post); }