if (ModelState.IsValid) { // find user by username var user = await _signInManager.UserManager.FindByNameAsync(Input.Username); // validate username/password using ASP.NET Identity if (user != null && (await _signInManager.CheckPasswordSignInAsync(user, Input.Password, true)) == SignInResult.Success) { await _events.RaiseAsync(new UserLoginSuccessEvent(user.UserName, user.Id, user.UserName, clientId: context?.Client.ClientId)); // only set explicit expiration here if user chooses "remember me". // otherwise we rely upon expiration configured in cookie middleware. AuthenticationProperties props = null; if (LoginOptions.AllowRememberLogin && Input.RememberLogin) { props = new AuthenticationProperties { IsPersistent = true, ExpiresUtc = DateTimeOffset.UtcNow.Add(LoginOptions.RememberMeLoginDuration) }; }; // issue authentication cookie with subject ID and username var isuser = new IdentityServerUser(user.Id) { DisplayName = user.UserName }; await HttpContext.SignInAsync(isuser, props); if (context != null) { if (context.IsNativeClient()) { // The client is native, so this change in how to // return the response is for better UX for the end user. return this.LoadingPage(Input.ReturnUrl); } // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null return Redirect(Input.ReturnUrl); } // request for a local page if (Url.IsLocalUrl(Input.ReturnUrl)) { return Redirect(Input.ReturnUrl); } else if (string.IsNullOrEmpty(Input.ReturnUrl)) { return Redirect("~/"); } else { // user might have clicked on a malicious link - should be logged throw new Exception("invalid return URL"); } } await _events.RaiseAsync(new UserLoginFailureEvent(Input.Username, "invalid credentials", clientId: context?.Client.ClientId)); ModelState.AddModelError(string.Empty, LoginOptions.InvalidCredentialsErrorMessage); }
نوع شمارشی، یک نوع صحیح است و شامل لیستی از ثوابت میباشد که توسط برنامه نویس مشخص میگردد . انواع شمارشی برای تولید کد خودمستند به کار میروند یعنی کدی که به راحتی قابل درک باشد و نیاز به توضیحات اضافه نداشته باشد. زیرا به راحتی توسط نام ، نوع کاربرد و محدوده مقادیرشان قابل درک میباشند . مقادیر نوع شمارشی منحصربه فرد میباشند (unique) و شامل مقادیر تکراری نمیباشند در غیر این صورت کامپایلر خطای مربوطه را هشدار میدهد . نحوه تعریف نوع شمارشی :
enum typename{enumerator-list}
enum Day{SAT,SUN,MON,TUE,WED,THU,FRI}
Day day1,day2; day1 = SAT; day2 = SUN;
enum Day{SAT=1,SUN=2,MON=4,TUE=8,WED=16,THU=32,FRI=64}
enum Day{SAT=1,SUN,MON,TUE,WED,THU,FRI}
میتوان به شمارشگرها مقادیر یکسانی نسبت داد
enum Answer{NO=0,FALSE=0,YES=1,TRUE=1,OK=1}
enum Answer{NO=0,FALSE=0,YES=1,YES=2,OK=1}
1- enum سبب میشود که شما مقادیر مجاز و قابل انتظار را به متغیرهایتان نسبت دهید .
2- enum اجازه میدهد با استفاده از نام به مقدار دستیابی پیدا کنید پس کدهایتان خواناتر میشود .
3- با استفاده از enum تایپ کدهایتان سریع میشود زیرا IntelliSense در مورد انتخاب گزینه مناسب شما را یاری میدهد .
چند تعریف از enum :
enum Color{RED,GREEN,BLUE,BLACK,ORANGE} enum Time{SECOND,MINUTE,HOUR} enum Date{DAY,MONTH,YEAR} enum Language{C,DELPHI,JAVA,PERL} enum Gender{MALE,FEMALE}
اما تغییراتی که در c++11 اعمال شده : Type-Safe Enumerations
فرض کنید دو enum تعریف کرده اید و به شکل زیر میباشد
enum Suit {Clubs, Diamonds, Hearts, Spades}; enum Jewels {Diamonds, Emeralds, Opals, Rubies, Sapphires};
برای تعریف جدیدی که در c++11 داده شده کلمه کلیدی class بعد از کلمه enum مورد استفاده قرار میگیرد . به طور مثال تعریف دو enum پیشین که با خطا مواجه میشد بصورت زیر تعریف میشود و از کامپایلر خطایی دریافت نمیکنیم .
enum class Suit {Clubs, Diamonds, Hearts, Spades}; enum class Jewels {Diamonds, Emeralds, Opals, Rubies, Sapphires};
enum Suit {Clubs, Diamonds, Hearts, Spades}; Suit var1 = Clubs; int var2= Clubs;
enum class Jewels {Diamonds, Emeralds, Opals, Rubies, Sapphires}; Jewels typeJewel = Jewels::Emeralds; int suitValue = static_cast<int>(typeJewel);
یک مثال کلی و جامعتر :
// Demonstrating type-safe and non-type-safe enumerations #include <iostream> using std::cout; using std::endl; // You can define enumerations at global scope //enum Jewels {Diamonds, Emeralds, Rubies}; // Uncomment this for an error enum Suit : long {Clubs, Diamonds, Hearts, Spades}; int main() { // Using the old enumeration type... Suit suit = Clubs; // You can use enumerator names directly Suit another = Suit::Diamonds; // or you can qualify them // Automatic conversion from enumeration type to integer cout << "suit value: " << suit << endl; cout << "Add 10 to another: " << another + 10 << endl; // Using type-safe enumerations... enum class Color : char {Red, Orange, Yellow, Green, Blue, Indigo, Violet}; Color skyColor(Color::Blue); // You must qualify enumerator names // Color grassColor(Green); // Uncomment for an error // No auto conversion to numeric type cout << endl << "Sky color value: "<< static_cast<long>(skyColor) << endl; //cout << skyColor + 10L << endl; // Uncomment for an error cout << "Incremented sky color: " << static_cast<long>(skyColor) + 10L // OK with explicit cast << endl; return 0; }
اولین نکتهای که باید بدانید این است که هر نوع دادهای که شما در دات نت دارید و تعریف میکنید، از والدی به نام System.Object مشتق میشود. برای مثال وقتی شما کلاسی را تعریف میکنید، چه ضمنی و چه صریح، کلاس شما از System.Object ارث بری خواهد کرد.
class DotnetTips { .... }
class DotnetTips:System.Object { ... }
Equals | اگر هر دو شیء مقادیر یکسانی داشته باشند، True باز میگرداند. در فصل پنجم با این مورد بیشتر آشنا میشویم. |
GetHashCode | بر اساس مقادیر این شیء، یک کد هش شده میسازد. اگر شیء قرار است مقدار هش آن در جداول هش، مثل Dictionary یا HashSet به عنوان کلید به کار رود بهتر است این متد رونویسی شود. متاسفانه این متد در شیء Object تعریف شده است و از آنجا که بیشتر نوعها هیچ وقت به عنوان یک کلید استفاده نمیشوند؛ بهتر بود در این رابطه به یک اینترفیس منتقل میشد. در فصل 5 بیشتر در این مورد بحث خواهد شد (مطالب مرتبط در اینباره + + + ). |
ToString | پیاده سازی پیشفرض آن اینست که این متد با اجرای کدthis.GetType().FullName
نام نوع را برمیگرداند. ولی برای بعضی نوعها چون Boolean,int32 این متد، رونویسی شده و مقدار مربوطه را به طور رشتهای باز میگرداند. در بعضی موارد هم این متد برای استفادههایی چون دیباگ برنامه هم رونویسی میشود. توجه داشته باشید که که نسبت به CultureInfo ترد مربوطه، واکنش نشان میدهد که در فصل 14 آن را بررسی میکنیم. |
GetType | یک نمونه از شیء مورد نظر را برمیگرداند که با استفاده از ریفلکشن میتوان به اطلاعات متادیتای آن شیء دسترسی پیدا کرد. در مورد ریفلکشن در فصل 23 صحبت خواهد شد. |
Protected Methods
MemberwiseClone | این متد از شیء جاری یک Shallow copy (+ )گرفته و فیلدهای غیر ایستای آن را همانند شیء جاری پر میکند. اگر فیلدهای غیر ایستا از نوع Value باشند که کپی بیت به بیت صورت خواهد گرفت. ولی اگر فیلدی از نوع Reference باشد، از همان نوع Ref میباشند؛ ولی خود شیء اصلی، یک شیء جدید به حساب میآید و به شیء سازندهاش ارتباطی ندارد. |
Finalize | یک متد Virtual است و زمانی صدا زده میشود که GC قصد نابودسازی آن شیء را داشته باشد. این متد برای زمانی نیاز است که شما قصد دارید قبل از نابودسازی، کاری را انجام دهید. در فصل 21 در این مورد بیشتر صحبت میکنیم. |
همانطور که میدانید، همهی اشیا نیاز دارند تا با استفاده از کلمهی new، در حافظه تعریف شوند:
DotnetTips dotnettips=new DotnetTips("i am constructor");
اتفاقاتی که با استفاده از عملگر new رخ میدهد به شرح زیر است:
- اولین کاری که CLR انجام میدهد، محاسبهی مقدار حافظه یا تعداد بایتهای فیلدهای شیء مربوطه است و همچنین اشیایی که از آنها مشتق شده است؛ مثل System.Object که همیشه وجود دارد. هر شیءایی که بر روی حافظهی Heap قرار میگیرد، به یک سری اعضای اضافه هم نیاز دارد که Type Object Pointer و Sync Block Index نامیده میشوند و CLR از آنها برای مدیریت حافظه استفاده میکند. تعداد بایتهای این اعضای اضافه هم با تعداد بایتهای شیء مدنظر جمع میشوند.
- طبق تعداد بایتهای به دست آمده، یک مقدار از حافظهی Heap دریافت میشود.
- دو عضو اضافه که در بند شماره یک به آن اشاره کردیم، آماده سازی میشوند.
- سازندهی شیء صدا زده میشود. سازنده بر اساس نوع ورودی شما انتخاب میشود و در صورت ارجاع به سازندههای والد، ابتدا سازندههای والد صدا زده میشوند و بعد از اینکه همهی سازندهها صدا زده شدند، سازندهی System.Object صدا زده میشود که هیچ کدی ندارد؛ ولی به هر حال عمل Return آن انجام میشود.
بعد از انجام همهی موارد بالا، یک اشاره گر به متغیر شما (در اینجا dotnettips) برگشت داده میشود.
با توجه به اینکه React یک سیستم متشکل از کامپوننتهای کوچک و بزرگ است و از JSX جهت کدنویسی استفاده میکند و یک قالب HTML، متشکل از تمام عناصر به صورت درهم ریخته میباشد و بخشهای مختلفی دارد، امکان استفادهی مستقیم از قالب HTML در آن وجود ندارد و باید با فرمت React همخوانی داشته باشد. من در اینجا از قالب رایگان و راستچین شده AdminLTE که بر پایه بوت استرپ 4 میباشد استفاده کردهام.
همانطور که میدانید React پوشهای را به نام public، مهیا کردهاست که برای استفادهی عمومی از فایلهای استاتیک ایجاد شدهاست. پس ابتدا فایلهای js,css، تصاویر و دیگر فایلهای استاتیک را به پوشهی public منتقل میکنیم. سپس فایل index قالب را باز کرده و به تگ header فایل مراجعه کنید. تگهای لینکهای معرفی فایلهای css و script ای را که در آن تعریف شدهاند، کپی کرده به هدر فایل index.html که در پوشهی public قرار دارد، منتقل کنید. همچنین از فایلهای اسکرپیت دیگر که در پایین تگ Body قرار گرفتهاند، غافل نگردید.
در اینجا باید بخشهای اساسی قالب، همانند navbar و sidebar را به صورت کامپوننت ایجاد کنیم.
پس ابتدا یک کامپوننت NavBar.jsx را ایجاد کرده و کدهای همین قسمت را در متد render قرار میدهیم:
import React, { Component } from "react";
class NavBar extends Component {
state = {};
render() {
return (
<React.Fragment>
<nav>
<!-- Left navbar links -->
<ul>
<li>
<a data-widget="pushmenu" href="#"><i></i></a>
</li>
<li>
<a href="index3.html">خانه</a>
</li>
<li>
<a href="#">تماس</a>
</li>
</ul>
<!-- SEARCH FORM -->
<form>
<div>
<input type="search" placeholder="جستجو" aria-label="Search">
<div>
<button type="submit">
<i></i>
</button>
</div>
</div>
</form>
...
</nav>
</React.Fragment>
);
}
}
export default NavBar;
- تمامی کامنتهای موجود در فایل را حذف کنید.
- تمام تگها که شامل خصوصیت class هستند را با استفاده از ابزار جستجو، یافته و با عبارت className جایگزین کنید.
- در صورتیکه روی تگها از خصوصیت style استفاده کردهاید، به شکل زیر ویرایش کرده و قالب jsx را روی آن پیاده کنید.
style="opacity:0.8;"
style={{ opacity: "0.8" }}
- در صورتیکه از تگهای img و یا input استفاده میکنید، حتما باید انتها تگها به شکل زیر بسته شده باشند:
<input type="search" placeholder="جستجو" aria-label="Search">
<input className="form-control form-control-navbar" type="search" placeholder="جستجو" aria-label="Search" />
import React, { Component } from "react"; class NavBar extends Component { state = {}; render() { return ( <React.Fragment> <nav className="main-header navbar navbar-expand bg-white navbar-light border-bottom"> <ul className="navbar-nav"> <li className="nav-item"> <a className="nav-link" data-widget="pushmenu" href="#"> <i className="fa fa-bars"></i> </a> </li> <li className="nav-item d-none d-sm-inline-block"> <a href="index3.html" className="nav-link"> خانه </a> </li> <li className="nav-item d-none d-sm-inline-block"> <a href="#" className="nav-link"> تماس </a> </li> </ul> <form className="form-inline ml-3"> <div className="input-group input-group-sm"> <input className="form-control form-control-navbar" type="search" placeholder="جستجو" aria-label="Search" /> <div className="input-group-append"> <button className="btn btn-navbar" type="submit"> <i className="fa fa-search"></i> </button> </div> </div> </form> ... </nav> </React.Fragment> ); } } export default NavBar;
return ( <React.Fragment> <NavBar /> <SideBar /> <div className="content-wrapper" style={{ marginTop: "20px" }}> <DomainList /> </div> <Footer /> </React.Fragment> )
یک CSS Framework مبتنی بر Flexbox
- جمع و جور بدون نیاز به هیچ فایل جاوا اسکریپت
- سهولت استفاده از گرید سیستم و ستون بندی .
- کامپوننتهای مدرن و متنوع مثل Card
- ماژولار ، به عنوان نمونه میتوان تنها از ماژول ستونها استفاده کرد.
- اقبال خوب جامعهی استفاده کنندگان (بیش از 34 هزار ستارهی گیتهاب تا این لحظه)
راه اندازی StimulSoft Report در ASP.NET MVC
ممنون میشم اگه راهنمایی کنید.
تعریف رنگ در iTextSharp
شما میتوانید فایل XML ذخیره شده را بعدا استفاده کنید و یا میتوانید آن را به برنامه نویسان دیگر هم بدهید.
اجازه دهید نگاهی داشته باشیم بر محتویات داخل فایل XML . فایل XML کلکسیونی از تگ BreakPoints داخل BreakpointCollection است.هر تگ Breakpoint حاوی اطلاعاتی در مورد یک Breakpoint خاص است.
اگر شما هر زمانی همه Breakpointها را از کدتان حذف کردید به راحتی میتوانید آن را تنها با کلیک بر روی Import وارد کدتان بکنید و تمام Breakpointهای ذخیره شده را بازآوری کنید.
نکته: Import کردن Breakpoint براساس شماره خط کد شما میباشد یعنی همان خطی که شما Breakpoint را گذاشته اید پس اگر شماره خط کد شما تغییر کند Breakpoint بروی خط قبلی گذاشته میشود.
روی tblNews کلیک کرده آنرا بکشید و روی فرم رها کنید. آنگاه ظاهر فرم و چیدمان کنترلها را تنظیم کنید و دو دکمه ذخیره و لغو برابر با شکل در فرم ایجاد کنید:
کد رویداد دو دکمه را اینگونه بنویسید:
private void btnCancel_Click(object sender, EventArgs e) { this.Close(); } private void btnSave_Click(object sender, EventArgs e) { this.DialogResult = System.Windows.Forms.DialogResult.OK; }
در پایین فرم روی tblNewsBindingSource کلیک کنید و از قسمت Properties ویژگی Modifiers آنرا برابر با Public کنید.
روی Combobox کلیک کنید، سپس ویژگی DataBinding -> Text آنرا خالی کنید. سپس روی فلش بالای Combobox دسته خبر کلیک کنید و تنظیمات آنرا مانند شکل زیر انجام دهید.
برای پرشدن آن کد زیر را در رویداد Load فرم اینگونه بنویسید:
private void frmAddEditNews_Load(object sender, EventArgs e) { MyNewsService.MyNewsServiceClient MyNews = new MyNewsService.MyNewsServiceClient(); tblCategoryIdComboBox.DataSource = MyNews.GetAllCategory(); }
به فرم اصلی بازگردید و برای رویداد دکمهی ویرایش چنین بنویسید:
private void btnEdit_Click(object sender, EventArgs e) { if (tblNewsDataGridView.CurrentRow == null) { MessageBox.Show("سطری برای ویرایش انتخاب کنید"); } else { //tblNews news = tblNewsDataGridView.CurrentRow.DataBoundItem as tblNews; tblNews news = MyNews.GetNews(Convert.ToInt32(tblNewsDataGridView.CurrentRow.Cells["tblNewsId"].Value)); frmAddEditNews frmAdd = new frmAddEditNews(); frmAdd.tblNewsBindingSource.DataSource = news; if (frmAdd.ShowDialog() == DialogResult.OK) { MyNews.EditNews(news); tblNewsBindingSource.DataSource = MyNews.GetAllNews().Select(p => new { p.tblNewsId, p.tblCategory.CatName, p.Title, p.Description, RegDate = MiladiToShamsi(p.RegDate) }); } } }
در صورتی که متد GetAllNews را به صورت ساده به ویژگی DataSource دیتاگرید نسبت داده بودیم میتوانستید از کد زیر برای مقداردهی به متغیر news بهره ببریم. ولی در حال حاضر این خط کد پیغام خطا میدهد. البته راههای دیگری برای حل این مشکل وجود دارد که در این درس قصد پرداختن به آنرا ندارم.
tblNews news = tblNewsDataGridView.CurrentRow.DataBoundItem as tblNews;
کد مربوط به رویداد دکمهی افزودن و حذف را نیز به صورت زیر بنویسید:
private void btnAdd_Click(object sender, EventArgs e) { tblNews news = new tblNews(); frmAddEditNews frmAdd = new frmAddEditNews(); frmAdd.tblNewsBindingSource.DataSource = news; if (frmAdd.ShowDialog() == DialogResult.OK) { MyNews.AddNews(news); tblNewsBindingSource.DataSource = MyNews.GetAllNews().Select(p => new { p.tblNewsId, p.tblCategory.CatName, p.Title, p.Description, RegDate = MiladiToShamsi(p.RegDate) }); } } private void btnRemove_Click(object sender, EventArgs e) { if (MessageBox.Show("آیا با حذف این سطر اطمینان دارید؟","هشدار",MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes) { MyNews.DeleteNews(Convert.ToInt32(tblNewsDataGridView.CurrentRow.Cells["tblNewsId"].Value)); tblNewsBindingSource.DataSource = MyNews.GetAllNews().Select(p => new { p.tblNewsId, p.tblCategory.CatName, p.Title, p.Description, RegDate = MiladiToShamsi(p.RegDate) }); } }
برنامه را اجرا کنید. کار ما کم و بیش به پایان رسیده است. شما یک پروژهی ویندوز ساده با استفاده از WCF ای که از Entity Framework برای اتصال به پایگاه داده بهره میبرد؛ ایجاد کردید. WCF بسیار گستردهتر از این است و در اینجا تنها به بخشی از آن پرداختیم. احتمالاً در صورت استقبال خوانندگان در آینده دربارهی تنظیمات ریز WCF برای امنیت، سرعت، محدودیت و استفاده در محیطهای مختلف خواهم نوشت.
شاد و پیروز باشید.