چند مثال:
- پیشتر در این سایت از کلمهی نامفهوم و غریبی به نام «برچسب» استفاده شده بود. عین عنوان را در قسمت برچسب مطلب کپی میکردند (حین ارسال لینک). از زمانیکه به «گروه» تغییر نام یافت، مشکل حل شد.
- پیام میدن، جستجوی سایت صفحه بندی نداره. عنوان میکنم اون مستطیل آبی برجسته مثل تمام قسمتهای دیگر سایت یک دکمه است. قابل کلیک است. در کنارش علامت مراجعه به صفحهی 2 هم قرار داده شد. (تصور کاربری رابطهای تخت و مترو اینجا کلا زیر سؤال هست)
و ...
هم پیش و هم پس از سه خط زیر در متد Configure تست گرفتم
ولی باز هم با مشکل مواجه است اطلاعات User بعد از لاگین به صورت شکل زیر است در صورتی که اگر از متد UseRequestLocalization در کانفیگ استفاده نشود و موارد مربوط به Localization فعال نباشد کاربر به درستی لاگین میکند و اطلاعات Claimها و بقیه موارد از بانک اطلاعاتی پر میشود.
var options = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>(); LocalizationPipeline.ConfigureOptions(options.Value); app.UseRequestLocalization(options.Value);
متاسفانه بعد از اهراز هویت که توسط متد PasswordSignInAsync انجام میشود و با اینکه resultIdentity هم مقدار آن Successed میباشد.
var resultIdentity = await _signInManager.PasswordSignInAsync(username, password, rememberMe, lockoutOnFailure: true);
اشتراکها
مجموعه فونت های ورزشی برای وب
این مجموعه برای وب سایت هایی که در زمینه ورزشی فعالیت میکنند فونتهای مناسبی دارد که از طرف سایت Fontello.com منتشر شده است.
اشتراکها
جشنواره وب ایران
اشتراکها
ساخت tour برای وب سایت
نظرات اشتراکها
HTML Helper برای jqGrid
اگر این کتابخانهها نبودند و امروزه تا این حد تکامل پیدا نکرده بودند، هیچ وقت سیلورلایت و فلش از صحنه روزگار محو نمیشدند. در بسیاری از اوقات هدف ساخت یک برنامه غنی وب است. برنامهای که تجربه کاربری آن همانند برنامههای دسکتاپ باشد. مثلا صفحه مدام چشمک نمیزند و کاربر احساس نمیکند که مدام رفت و برگشت به سرور وجود دارد، کنترلهای auto-complete مانند برنامههای دسکتاپ و یا حتی شکیلتر و غنیتر از آنها در وب وجود دارند، برنامههای تک صفحهای وب، اعتبار سنجیهای سمت کاربر، بدون هدایت او به سرور و دریافت پاسخ آنی و بسیاری از مثالهای دیگری که در جهت بهبود کاربری در وب مطرح هستند. در اینجا HTML خالص بدون جاوا اسکریپت حرفی برای گفتن ندارد. HTML خالص صرفا جهت ارائه محتوا اختراع شده است نه طراحی برنامههای غنی وب و کار ما هم با ASP.NET و یا فناوریهای مشابه، تولید برنامههای وب است و نه صرفا ارائه محتوا. اگر قرار است مثلا چند صفحه توضیح مشخصات شرکتی را در اینترنت قرار دهید، این تنها به معنای ارائهی محتوا است. نیازی به برنامه خاصی ندارد. چند صفحه HTML به همراه مقداری هم CSS برای اینکار کافی است. اما اگر همینجا قرار شد از کاربر اطلاعات دریافت کنید، نیاز است تجربه کاربری او را غنی کنید.
در این مطلب، سعی خواهیم کرد تا همانند تصویر امنیتی این سایت که موقع ورود
نمایش داده میشود، یک نمونه مشابه به آنرا در ASP.Net MVC ایجاد کنیم.
ذکر این نکته ضروری است که قبلا آقای پایروند در یک مطلب دو قسمتی کاری مشابه را انجام داده بودند، اما در مطلبی که در اینجا ارائه شده سعی کرده ایم تا تفاوتهایی را با مطلب ایشان داشته باشد.
همان طور که ممکن است بدانید، اکشن متدها در کنترلرهای MVC میتوانند انواع مختلفی را برگشت دهند که شرح آن در مطالب این سایت به مفصل گذشته است. یکی از این انواع، نوع ActionResult میباشد. این یک کلاس پایه برای انواع برگشتی توسط اکشن متدها مثل JsonResult، FileResult میباشد. (اطلاعات بیشتر را اینجا بخوانید) اما ممکن است مواقعی پیش بیاید که بخواهید نوعی را توسط یک اکشن متد برگشت دهید که به صورت توکار تعریف نشده باشد. مثلا زمانی را در نظر بگیرید که بخواهید یک تصویر امنیتی را برگشت دهید. یکی از راه حلهای ممکن به این صورت است که کلاسی ایجاد شود که از کلاس پایه ActionResult ارث بری کرده باشد. بدین صورت:
همان طور که مشاهده میکنید، کلاسی به اسم CaptchaImageResult تعریف شده که از کلاس ActionResult ارث بری کرده است. در این صورت باید متد ExecuteResult را override کنید. متد ExecuteResult به صورت خودکار هنگامی که از CaptchaImageResult به عنوان یک نوع برگشتی اکشن متد استفاده شود اجرا میشود. به همین خاطر باید تصویر امنیتی توسط این متد تولید شود و به صورت جریان (stream) برگشت داده شود
کدهای اولیه برای ایجاد یک تصویر امنیتی به صورت خیلی ساده از کلاسهای فراهم شده توسط +GDI ، که در دات نت فریمورک وجود دارند استفاده خواهند کرد. برای این کار ابتدا یک شیء از کلاس Bitmap با دستور زیر ایجاد خواهیم کرد:
پارامترهای اول و دوم به ترتبی عرض و ارتفاع تصویر امنیتی را مشخص خواهند کرد و پارامتر سوم نیز فرمت تصویر را بیان کرده است. Format32bppArgb یعنی یک تصویر که هر کدام از پیکسلهای آن 32 بیت فضا اشغال خواهند کرد ، 8 بیت اول میزان آلفا، 8 بیت دوم میزان رنگ قرمز، 8 بیت سوم میزان رنگ سبز، و 8 تای آخر نیز میزان رنگ آبی را مشخص خواهند کرد
سپس شیئی از نوع Graphics برای انجام عملیات ترسیم نوشتههای فارسی روی شیء bitmap ساخته میشود:
خصوصیات مورد نیاز ما از gfxCaptchaImage را به صورت زیر مقداردهی میکنیم:
واحد اندازه گیری به پیکسل، کیفیت تصویر تولید شده توسط دو دستور اول، و در دستور سوم ناحیه ترسیم با یک رنگ سفید پاک میشود.
سپس یک عدد اتفاقی بین 1000 و 9999 با دستور زیر تولید میشود:
متد CreateSalt در کلاس CaptchaHelpers قرار گرفته است، و نحوه پیاده سازی آن بدین صورت است:
سپس مقدار موجود در salt را برای مقایسه با مقداری که کاربر وارد کرده است در session قرار میدهیم:
سپس عدد اتفاقی تولید شده باید تبدیل به حروف شود، مثلا اگر عدد 4524 توسط
متد CreateSalt تولید شده باشد، رشته "چهار هزار و پانصد و بیست و چهار"
معادل آن نیز باید تولید شود. برای تبدیل عدد به حروف، آقای نصیری کلاس خیلی خوبی نوشته اند که چنین کاری را انجام میدهد. ما نیز از همین کلاس استفاده خواهیم کرد:
در دستور بالا، متد الحاقی NumberToText با پارامتر Language.Persian وظیفه تبدیل عدد salt را به حروف فارسی معادل خواهد داشت.
به صورت پیش فرض نوشتههای تصویر امنیتی به صورت چپ چین نوشته خواهند شد، و با توجه به این که نوشته ای که باید در تصویر امنیتی قرار بگیرد فارسی است، پس بهتر است آنرا به صورت راست به چپ در تصویر بنویسیم، بدین صورت:
و همچنین نوع و اندازه فونت که در این مثال tahoma میباشد:
خوب نوشته فارسی اتفاقی تولید شده آماده ترسیم شدن است، اما اگر چنین
تصویری تولید شود احتمال خوانده شدن آن توسط روباتهای پردازش گر تصویر
شاید زیاد سخت نباشد. به همین دلیل باید کاری کنیم تا خواندن این تصویر
برای این روباتها سختتر شود، روشهای مختلفی برای این کار
وجود دارند: مثل ایجاد نویز در تصویر امنیتی یا استفاده از توابع ریاضی
سینوسی و کسینوسی برای نوشتن نوشتهها به صورت موج. برای این کار اول یک
مسیر گرافیکی در تصویر یا موج اتفاقی ساخته شود و به شیء gfxCaptchaImage نسبت
داده شود. برای این کار اول نمونه ای از روی کلاس GraphicsPath ساخته میشود،
و با استفاده از متد AddString ، رشته اتفاقی تولید شده را با فونت مشخص
شده، و تنظیمات اندازه دربرگیرنده رشته مورد نظرر، و تنظیمات فرمت بندی
رشته را لحاظ خواهیم کرد.
با خط کد زیر شیء path را با رنگ بنقش با استفاده از شیء gfxCaptchaImage روی تصویر bitmap ترسیم خواهیم کرد:
برای ایجاد یک منحنی و موج از کدهای زیر استفاده خواهیم کرد:
موقع ترسیم تصویر امنیتی است:
تصویر امنیتی به صورت یک تصویر با فرمت jpg به صورت جریان (stream) به مرورگر باید فرستاده شوند:
و در نهایت حافظههای اشغال شده توسط اشیاء فونت و گرافیک و تصویر امنیتی آزاد خواهند شد:
برای استفاده از این کدها، اکشن متدی نوشته میشود که نوع CaptchaImageResult را برگشت میدهد:
اگر در یک View خصیصه src یک تصویر به آدرس این اکشن متد مقداردهی شود، آنگاه تصویر امنیتی تولید شده نمایش پیدا میکند:
بعد از پست کردن فرم مقدار text box تصویر امنیتی خوانده شده و با مقدار موجود در session مقایسه میشود، در صورتی که یکسان باشند، کاربر میتواند وارد سایت شود (در صورتی که نام کاربری یا کلمه عبور خود را درست وارد کرده باشد) یا اگر از این captcha در صفحات دیگری استفاده شود عمل مورد نظر میتواند انجام شود. در مثال زیر به طور ساده اگر کاربر در کادر متن مربوط به تصویر امنیتی
مقدار درستی را وارد کرده باشد یا نه، پیغامی به او نشان داده میشود.
کدهای کامل مربوط به این مطلب را به همراه یک مثال از لینک زیر دریافت نمائید:
MVC-Persian-Captcha
همان طور که ممکن است بدانید، اکشن متدها در کنترلرهای MVC میتوانند انواع مختلفی را برگشت دهند که شرح آن در مطالب این سایت به مفصل گذشته است. یکی از این انواع، نوع ActionResult میباشد. این یک کلاس پایه برای انواع برگشتی توسط اکشن متدها مثل JsonResult، FileResult میباشد. (اطلاعات بیشتر را اینجا بخوانید) اما ممکن است مواقعی پیش بیاید که بخواهید نوعی را توسط یک اکشن متد برگشت دهید که به صورت توکار تعریف نشده باشد. مثلا زمانی را در نظر بگیرید که بخواهید یک تصویر امنیتی را برگشت دهید. یکی از راه حلهای ممکن به این صورت است که کلاسی ایجاد شود که از کلاس پایه ActionResult ارث بری کرده باشد. بدین صورت:
using System; using System.Web.Mvc; namespace MVCPersianCaptcha.Models { public class CaptchaImageResult : ActionResult { public override void ExecuteResult(ControllerContext context) { throw new NotImplementedException(); } } }
کدهای اولیه برای ایجاد یک تصویر امنیتی به صورت خیلی ساده از کلاسهای فراهم شده توسط +GDI ، که در دات نت فریمورک وجود دارند استفاده خواهند کرد. برای این کار ابتدا یک شیء از کلاس Bitmap با دستور زیر ایجاد خواهیم کرد:
// Create a new 32-bit bitmap image. Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
سپس شیئی از نوع Graphics برای انجام عملیات ترسیم نوشتههای فارسی روی شیء bitmap ساخته میشود:
// Create a graphics object for drawing. Graphics gfxCaptchaImage = Graphics.FromImage(bitmap);
gfxCaptchaImage.PageUnit = GraphicsUnit.Pixel; gfxCaptchaImage.SmoothingMode = SmoothingMode.HighQuality; gfxCaptchaImage.Clear(Color.White);
سپس یک عدد اتفاقی بین 1000 و 9999 با دستور زیر تولید میشود:
// Create a Random Number from 1000 to 9999 int salt = CaptchaHelpers.CreateSalt();
public int CreateSalt() { Random random = new Random(); return random.Next(1000, 9999); }
HttpContext.Current.Session["captchastring"] = salt;
string randomString = (salt).NumberToText(Language.Persian);
به صورت پیش فرض نوشتههای تصویر امنیتی به صورت چپ چین نوشته خواهند شد، و با توجه به این که نوشته ای که باید در تصویر امنیتی قرار بگیرد فارسی است، پس بهتر است آنرا به صورت راست به چپ در تصویر بنویسیم، بدین صورت:
// Set up the text format. var format = new StringFormat(); int faLCID = new System.Globalization.CultureInfo("fa-IR").LCID; format.SetDigitSubstitution(faLCID, StringDigitSubstitute.National); format.Alignment = StringAlignment.Near; format.LineAlignment = StringAlignment.Near; format.FormatFlags = StringFormatFlags.DirectionRightToLeft;
// Font of Captcha and its size Font font = new Font("Tahoma", 10);
// Create a path for text GraphicsPath path = new GraphicsPath();
path.AddString(randomString, font.FontFamily, (int)font.Style, (gfxCaptchaImage.DpiY * font.SizeInPoints / 72), new Rectangle(0, 0, width, height), format);
gfxCaptchaImage.DrawPath(Pens.Navy, path);
//-- using a sin ware distort the image int distortion = random.Next(-10, 10); using (Bitmap copy = (Bitmap)bitmap.Clone()) { for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int newX = (int)(x + (distortion * Math.Sin(Math.PI * y / 64.0))); int newY = (int)(y + (distortion * Math.Cos(Math.PI * x / 64.0))); if (newX < 0 || newX >= width) newX = 0; if (newY < 0 || newY >= height) newY = 0; bitmap.SetPixel(x, y, copy.GetPixel(newX, newY)); } } }
//-- Draw the graphic to the bitmap gfxCaptchaImage.DrawImage(bitmap, new Point(0, 0)); gfxCaptchaImage.Flush();
HttpResponseBase response = context.HttpContext.Response; response.ContentType = "image/jpeg"; bitmap.Save(response.OutputStream, ImageFormat.Jpeg);
// Clean up. font.Dispose(); gfxCaptchaImage.Dispose(); bitmap.Dispose();
public CaptchaImageResult CaptchaImage() { return new CaptchaImageResult(); }
<img src="@Url.Action("CaptchaImage")"/>
[HttpPost] public ActionResult Index(LogOnModel model) { if (!ModelState.IsValid) return View(model); if (model.CaptchaInputText == Session["captchastring"].ToString()) TempData["message"] = "تصویر امنتی را صحیح وارد کرده اید"; else TempData["message"] = "تصویر امنیتی را اشتباه وارد کرده اید"; return View(); }
کدهای کامل مربوط به این مطلب را به همراه یک مثال از لینک زیر دریافت نمائید:
MVC-Persian-Captcha
نظرات مطالب
بررسی فرمت کوکیهای ASP.NET Identity
سؤال: چرا به روز رسانی اطلاعات کاربر، سبب logout او میشود؟
در ASP.NET Identity، جدول کاربران دارای فیلد SecurityStamp است و با مقایسهی مقدار آن با مقدار موجود در کوکی کاربر، مشخص میکند آیا اطلاعات کاربری در سمت سرور تغییر کردهاست یا خیر؟ اگر بله، این کاربر مجبور به لاگین مجدد خواهد شد.
اینکه چه زمانی بررسی مجدد SecurityStamp موجود در کوکی کاربر صورت میگیرد، توسط پارامتر validateInterval مشخص میشود. در اینجا این پارامتر به صفر تنظیم شدهاست. یعنی اطلاعات کاربر در درخواست بعدی، مجددا تعیین اعتبار میشود.
تغییر اطلاعات فیلد SecurityStamp یا با فراخوانی مستقیم userService.UpdateSecurityStampAsync انجام میشود یا متدهای ذیل هم به صورت توکار شامل این فراخوانی در پشت صحنه هستند:
یعنی هر نوع تغییری در اطلاعات کاربر، سبب logout او خواهد شد.
در ASP.NET Identity، جدول کاربران دارای فیلد SecurityStamp است و با مقایسهی مقدار آن با مقدار موجود در کوکی کاربر، مشخص میکند آیا اطلاعات کاربری در سمت سرور تغییر کردهاست یا خیر؟ اگر بله، این کاربر مجبور به لاگین مجدد خواهد شد.
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, User>( validateInterval: TimeSpan.FromMinutes(0), regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
تغییر اطلاعات فیلد SecurityStamp یا با فراخوانی مستقیم userService.UpdateSecurityStampAsync انجام میشود یا متدهای ذیل هم به صورت توکار شامل این فراخوانی در پشت صحنه هستند:
UserManager.CreateAsync UserManager.RemovePasswordAsync UserManager.UpdatePassword UserManager.RemoveLoginAsync UserManager.ChangePhoneNumberAsync/SetPhoneNumberAsync UserManager.SetTwoFactorEnabledAsync UserManager.SetEmailAsync
پاسخ به بازخوردهای پروژهها
چند متد الحاقی SEO
سلام؛ در مورد seo سایت
زمانی که سایتی داریم شبیه همین سایت هر مقاله ای که ثبت میشود اطلاعات از database شده و در view ای به نام post نمایش داده میشود . حالا تکلیف Title صفحه و metatagها چی میشود .keyword-description