اشتراک‌ها
نکاتی برای ساده کردن استفاده از یک رابط کاربری

چند مثال:
- پیشتر در این سایت از کلمه‌ی نامفهوم و غریبی به نام «برچسب» استفاده شده بود. عین عنوان را در قسمت برچسب مطلب کپی می‌کردند (حین ارسال لینک). از زمانیکه به «گروه» تغییر نام یافت، مشکل حل شد.
- پیام می‌دن، جستجوی سایت صفحه بندی نداره. عنوان می‌کنم اون مستطیل آبی برجسته مثل تمام قسمت‌های دیگر سایت یک دکمه است. قابل کلیک است. در کنارش علامت مراجعه به صفحه‌ی 2 هم قرار داده شد. (تصور کاربری رابط‌های تخت و مترو اینجا کلا زیر سؤال هست)
و ... 

نکاتی برای ساده کردن استفاده از یک رابط کاربری
نظرات مطالب
ارتقاء به ASP.NET Core 1.0 - قسمت 19 - بومی سازی
هم پیش و هم پس از سه خط زیر در متد Configure تست گرفتم
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);
ولی باز هم با مشکل مواجه است اطلاعات User بعد از لاگین به صورت شکل زیر است در صورتی که اگر از متد UseRequestLocalization در کانفیگ استفاده نشود و موارد مربوط به Localization فعال نباشد کاربر به درستی لاگین می‌کند و اطلاعات Claim‌ها و بقیه موارد از بانک اطلاعاتی پر می‌شود.
اشتراک‌ها
تحلیل سرعت بارگذاری یک سایت از نقاط مختلف جهان به صورت گرافیکی و برروی نقشه جهان.

ابتدا مکان سرور مربوط به وب سایت را روی نقشه مشخص کرده و سپس به صورت گرافیکی سرعت بارگذاری سایت را از مکان‌های مختلف دنیا روی نقشه به شما نشان می‌دهد. تحلیلی مناسب برای سایت‌های چند ملیتی.

تحلیل سرعت بارگذاری یک سایت از نقاط مختلف جهان به صورت گرافیکی و برروی نقشه جهان.
اشتراک‌ها
جشنواره وب ایران

این جشنواره هر ساله از میان سایت‌های فعال در تمامی حوزه‌های وب و در گروه‌های مختلف یک سایت را به عنوان سایت برتر سال معرفی میکند.

جشنواره وب ایران
اشتراک‌ها
ساخت tour برای وب سایت
با کمک این سایت می‌توانید به راحتی برای وب سایت خودتون tour  بسازید.
مانند کاری که فارس نیوز برای تغییرات جدیدش انجام داده.
ساخت tour برای وب سایت
نظرات اشتراک‌ها
HTML Helper برای jqGrid
اگر این کتابخانه‌ها نبودند و امروزه تا این حد تکامل پیدا نکرده بودند، هیچ وقت سیلورلایت و فلش از صحنه روزگار محو نمی‌شدند. در بسیاری از اوقات هدف ساخت یک برنامه غنی وب است. برنامه‌ای که تجربه کاربری آن همانند برنامه‌های دسکتاپ باشد. مثلا صفحه مدام چشمک نمی‌زند و کاربر احساس نمی‌کند که مدام رفت و برگشت به سرور وجود دارد، کنترل‌های auto-complete مانند برنامه‌های دسکتاپ و یا حتی شکیل‌تر و غنی‌تر از آن‌ها در وب وجود دارند، برنامه‌های تک صفحه‌ای وب، اعتبار سنجی‌های سمت کاربر، بدون هدایت او به سرور و دریافت پاسخ آنی و بسیاری از مثال‌های دیگری که در جهت بهبود کاربری در وب مطرح هستند. در اینجا HTML خالص بدون جاوا اسکریپت حرفی برای گفتن ندارد. HTML خالص صرفا جهت ارائه محتوا اختراع شده است نه طراحی برنامه‌های غنی وب و کار ما هم با ASP.NET و یا فناوری‌های مشابه، تولید برنامه‌های وب است و نه صرفا ارائه محتوا. اگر قرار است مثلا چند صفحه توضیح مشخصات شرکتی را در اینترنت قرار دهید، این تنها به معنای ارائه‌ی محتوا است. نیازی به برنامه خاصی ندارد. چند صفحه HTML به همراه مقداری هم CSS برای اینکار کافی است. اما اگر همینجا قرار شد از کاربر اطلاعات دریافت کنید، نیاز است تجربه کاربری او را غنی کنید.
مطالب
نحوه ایجاد یک تصویر امنیتی (Captcha) با حروف فارسی در ASP.Net MVC
در این مطلب، سعی خواهیم کرد تا همانند تصویر امنیتی این سایت که موقع ورود نمایش داده می‌شود، یک نمونه مشابه به آنرا در ASP.Net MVC ایجاد کنیم. ذکر این نکته ضروری است که قبلا آقای پایروند در یک مطلب دو قسمتی کاری مشابه را انجام داده بودند، اما در مطلبی که در اینجا ارائه شده سعی کرده ایم تا تفاوتهایی را با مطلب ایشان داشته باشد.

همان طور که ممکن است بدانید، اکشن متدها در کنترلرهای 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();
        }
    }
}
همان طور که مشاهده می‌کنید، کلاسی به اسم CaptchaImageResult تعریف شده که از کلاس ActionResult ارث بری کرده است. در این صورت باید متد ExecuteResult را override کنید. متد ExecuteResult به صورت خودکار هنگامی که از CaptchaImageResult به عنوان یک نوع برگشتی اکشن متد استفاده شود اجرا می‌شود. به همین خاطر باید تصویر امنیتی توسط این متد تولید شود و به صورت جریان (stream)  برگشت داده شود

کدهای اولیه برای ایجاد یک تصویر امنیتی به صورت خیلی ساده از کلاس‌های فراهم شده توسط +GDI ، که در دات نت فریمورک وجود دارند استفاده خواهند کرد. برای این کار ابتدا یک شیء از کلاس Bitmap با دستور زیر ایجاد خواهیم کرد:
// Create a new 32-bit bitmap image.
Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
پارامترهای اول و دوم به ترتبی عرض و ارتفاع تصویر امنیتی را مشخص خواهند کرد و پارامتر سوم نیز فرمت تصویر را بیان کرده است. Format32bppArgb یعنی یک تصویر که هر کدام از پیکسل‌های آن 32 بیت فضا اشغال خواهند کرد ، 8 بیت اول میزان آلفا، 8 بیت دوم میزان رنگ قرمز، 8 بیت سوم میزان رنگ سبز، و 8 تای آخر نیز میزان رنگ آبی را مشخص خواهند کرد 

سپس شیئی از نوع Graphics برای انجام عملیات ترسیم نوشته‌های فارسی روی شیء bitmap ساخته می‌شود:
// Create a graphics object for drawing.
Graphics gfxCaptchaImage = Graphics.FromImage(bitmap);
خصوصیات مورد نیاز ما از gfxCaptchaImage را به صورت زیر مقداردهی می‌کنیم:
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();
متد CreateSalt در کلاس CaptchaHelpers قرار گرفته است، و نحوه پیاده سازی آن بدین صورت است:
public int CreateSalt()
{
   Random random = new Random();
   return random.Next(1000, 9999);
}
سپس مقدار موجود در salt را برای مقایسه با مقداری که کاربر وارد کرده است در session قرار می‌دهیم:
HttpContext.Current.Session["captchastring"] = salt;
سپس عدد اتفاقی تولید شده باید تبدیل به حروف شود، مثلا اگر عدد 4524 توسط متد CreateSalt تولید شده باشد، رشته "چهار هزار و پانصد و بیست و چهار" معادل آن نیز باید تولید شود. برای تبدیل عدد به حروف، آقای نصیری کلاس خیلی خوبی نوشته اند که چنین کاری را انجام می‌دهد. ما نیز از همین کلاس استفاده خواهیم کرد:
string randomString = (salt).NumberToText(Language.Persian);
در دستور بالا، متد الحاقی NumberToText با پارامتر Language.Persian وظیفه تبدیل عدد salt را به حروف فارسی معادل خواهد داشت.

به صورت پیش فرض نوشته‌های تصویر امنیتی به صورت چپ چین نوشته خواهند شد، و با توجه به این که نوشته ای که باید در تصویر امنیتی قرار بگیرد فارسی است، پس بهتر است آنرا به صورت راست به چپ در تصویر بنویسیم، بدین صورت:
// 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;
و همچنین نوع و اندازه فونت که در این مثال tahoma می‌باشد:
// Font of Captcha and its size
Font font = new Font("Tahoma", 10);
خوب نوشته فارسی اتفاقی تولید شده آماده ترسیم شدن است، اما اگر چنین تصویری تولید شود احتمال خوانده شدن آن توسط روبات‌های پردازش گر تصویر شاید زیاد سخت نباشد. به همین دلیل باید کاری کنیم تا خواندن این تصویر برای این روبات‌ها سخت‌تر شود، روش‌های مختلفی برای این کار وجود دارند: مثل ایجاد نویز در تصویر امنیتی یا استفاده از توابع ریاضی سینوسی و کسینوسی برای نوشتن نوشته‌ها به صورت موج. برای این کار اول یک مسیر گرافیکی در تصویر یا موج اتفاقی ساخته شود و به شیء gfxCaptchaImage نسبت داده شود. برای این کار اول نمونه ای از روی کلاس GraphicsPath ساخته می‌شود،
// Create a path for text 
GraphicsPath path = new GraphicsPath();
و با استفاده از متد AddString ، رشته اتفاقی تولید شده را با فونت مشخص شده، و تنظیمات اندازه دربرگیرنده رشته مورد نظرر، و تنظیمات فرمت بندی رشته را لحاظ خواهیم کرد.
path.AddString(randomString, 
                font.FontFamily, 
                (int)font.Style, 
                (gfxCaptchaImage.DpiY * font.SizeInPoints / 72), 
                new Rectangle(0, 0, width, height), format);
با خط کد زیر شیء path را با رنگ بنقش با استفاده از شیء gfxCaptchaImage روی تصویر bitmap ترسیم خواهیم کرد:
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();
تصویر امنیتی به صورت یک تصویر با فرمت jpg به صورت جریان (stream) به مرورگر باید فرستاده شوند:
HttpResponseBase response = context.HttpContext.Response;
response.ContentType = "image/jpeg";
bitmap.Save(response.OutputStream, ImageFormat.Jpeg);
و در نهایت حافظه‌های اشغال شده توسط اشیاء فونت و گرافیک و تصویر امنیتی آزاد خواهند شد:
// Clean up.
font.Dispose();
gfxCaptchaImage.Dispose();
bitmap.Dispose();
برای استفاده از این کدها، اکشن متدی نوشته می‌شود که نوع CaptchaImageResult را برگشت می‌دهد:
public CaptchaImageResult CaptchaImage()
{
     return new CaptchaImageResult();
}
اگر در یک View خصیصه src یک تصویر به آدرس این اکشن متد مقداردهی شود، آنگاه تصویر امنیتی تولید شده نمایش پیدا می‌کند:
<img src="@Url.Action("CaptchaImage")"/>
بعد از پست کردن فرم مقدار text box تصویر امنیتی خوانده شده و با مقدار موجود در session مقایسه می‌شود، در صورتی که یکسان باشند، کاربر می‌تواند وارد سایت شود (در صورتی که نام کاربری یا کلمه عبور خود را درست وارد کرده باشد) یا اگر از این captcha در صفحات دیگری استفاده شود عمل مورد نظر می‌تواند انجام شود. در مثال زیر به طور ساده اگر کاربر در کادر متن مربوط به تصویر امنیتی مقدار درستی را وارد کرده باشد یا نه، پیغامی به او نشان داده می‌شود.  
[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 است و با مقایسه‌ی مقدار آن با مقدار موجود در کوکی کاربر، مشخص می‌کند آیا اطلاعات کاربری در سمت سرور تغییر کرده‌است یا خیر؟ اگر بله، این کاربر مجبور به لاگین مجدد خواهد شد.
 OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, User>(
            validateInterval: TimeSpan.FromMinutes(0),
            regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
اینکه چه زمانی بررسی مجدد SecurityStamp موجود در کوکی کاربر صورت می‌گیرد، توسط پارامتر validateInterval مشخص می‌شود. در اینجا این پارامتر به صفر تنظیم شده‌است. یعنی اطلاعات کاربر در درخواست بعدی، مجددا تعیین اعتبار می‌شود.
تغییر اطلاعات فیلد SecurityStamp یا با فراخوانی مستقیم userService.UpdateSecurityStampAsync انجام می‌شود یا متدهای ذیل هم به صورت توکار شامل این فراخوانی در پشت صحنه هستند:
UserManager.CreateAsync
UserManager.RemovePasswordAsync
UserManager.UpdatePassword
UserManager.RemoveLoginAsync
UserManager.ChangePhoneNumberAsync/SetPhoneNumberAsync
UserManager.SetTwoFactorEnabledAsync
UserManager.SetEmailAsync
یعنی هر نوع تغییری در اطلاعات کاربر، سبب logout او خواهد شد.
پاسخ به بازخورد‌های پروژه‌ها
چند متد الحاقی SEO
سلام؛ در مورد seo سایت 
زمانی که سایتی داریم شبیه همین سایت هر مقاله ای که ثبت میشود اطلاعات از database شده و در view ای به نام post نمایش داده میشود . حالا تکلیف Title صفحه و metatag‌ها چی میشود .keyword-description