مطالب
غیر فعال کردن یک دکمه در حین انجام پردازش های سمت سرور
بعضی مواقع بهتر است یک دکمه در حال انجام پردازش‌های سمت سرور غیر فعال شود و وقتی عملیات سمت سرور به پایان رسید این دکمه دوباره فعال شود. غیر فعال کردن یک دکمه به این دلیل انجام می‌شود که از postback‌های مجدد در حین postback شدن صفحه جلوگیری شود.
 فرض کنید در رویداد کلیک یک دکمه کدی نوشته اید که اطلاعات یک دانشجو را ذخیره کند. کاربر نرم افزار بعد از یک بار کلیک روی دکمه، درخواستی به سرور می‌فرستد و این باعث می‌شود کدهای درون رویداد کلیک دکمه اجرا شوند، به دلیل این که کاملا این کدها اجرا نشده اند، صفحه هم postback نشده است. کاربر به هر دلیل صبر نمی‌کند تا این پردازش تمام شود (شاید او نمی‌داند عملیاتی در سمت سرور در حال اجرا شدن هست چون پیغامی به او نشان داده نشده است)، در نتیجه باز هم روی همین دکمه کلیک می‌کند و باعث می‌شود در حین پردازش کدهای درون دکمه توسط سرور، دوباره درخواستی به سمت سرور فرستاده شود و باز هم کدهای درون همین دکمه به اجرا در آیند. به عبارت بهتر در حین postback شدن صفحه دوباره درخواست postback کردن صفحه را می‌دهد و سرور هم در حین انجام کدهای درون دکمه با درخواست قبلی، دوباره کدهای درون رویداد کلیک را اجرا می‌کند. در این مثال این کار باعث می‌شود کدهای رویداد کلیک دکمه، به تعداد کلیک‌های انجام شده اجرا شوند. در نتیجه به همین تعداد می‌تواند یک دانشجوی مستقل در دیتابیس ذخیره شود. این می‌تواند مشکلات بسیاری را همراه داشته باشد.

به همین دلیل بهتر است با کلیک روی این دکمه این کارها اتفاق بیفتند:
الف) غیرفعال کردن دکمه در حین انجام پردازش‌های سمت سرور
ب) نشان دادن یک پیغام به کاربر در حین انجام پردازش‌های سمت سرور
ج) فعال کردن دکمه بعد از انجام پردازش‌های سمت سرور

برای غیرفعال کردن دکمه در حین انجام پردازش‌های سمت سرور نمی‌توان از کدهای سمت سرور استفاده کرد. چون تا کاملا صفحه postback نشود نمی‌توان این کدها را به صفحه اعمال کرد. پس این گزینه کنار می‌رود.
راه حل بسیار خوب استفاده از جاوا اسکریپت است. مثال زیر را ببینید:
<asp:Button runat="server" 
            ID="btnProcess" 
            Text="پردازش" 
            onclick="btnProcess_Click"
            OnClientClick="this.disabled = true; this.value = 'در حال پردازش اطلاعات ...';" 
            UseSubmitBehavior="false"
             />
<asp:Label runat="server" ID="lblMessage" Text=""></asp:Label>
در رویداد OnClientClick کارهای (الف) و (ب) انجام می‌شوند و با false کردن مقدار رویداد UseSubmitBehavior کار (ج) انجام می‌شود.

و در رویداد کلیک دکمه کد زیر را بنویسید:
protected void btnProcess_Click(object sender, EventArgs e)
{
    // insert student in database
    System.Threading.Thread.Sleep(2000);
    lblMessage.Text = "پردازش اطلاعات به پایان رسید";
}
در این رویداد باید یک دانشجو اضافه شود. برای ایجاد یک پردازش سمت سروری دو ثانیه ای از متد Sleep استفاده شده است.

کد برگرفته شده از : dotnetforum.lk


 
مطالب
تعیین اعتبار یک checkBoxList با کمک jQuery

checkBoxList جزو کنترل‌هایی در ASP.Net است که نمی‌توان RequiredFieldValidator استاندارد را بر آن اعمال کرد. به عبارتی اگر نیاز بود حداقل یک آیتم چک باکس لیست حتما توسط کاربر انتخاب شود، راه حل آماده‌ای برای آن وجود ندارد. پیاده سازی این‌کار با استفاده از jQuery به سادگی میسر است که در ادامه آن‌را مرور خواهیم کرد.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="CheckBoxListValidator._Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[
function CheckItems(sender, args) {
//Get the total nuumber of selected CheckBoxes
var num = jQuery("table#<%=CheckBoxList1.ClientID%> input:checked").length;
args.IsValid = num > 0;
}
//]]>
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:CheckBoxList ID="CheckBoxList1" runat="server">
<asp:ListItem>item1</asp:ListItem>
<asp:ListItem>item2</asp:ListItem>
</asp:CheckBoxList>
<asp:CustomValidator ClientValidationFunction="CheckItems" ID="ValidateIt"
runat="server" ErrorMessage="(*)"> </asp:CustomValidator>
<asp:Button ID="Button1" runat="server" />
</div>
</form>
</body>
</html>

توضیحات:
یک CustomValidator استاندارد را به فرم اضافه کرده‌ایم تا توسط تابعی که به ClientValidationFunction آن معرفی می‌شود، کار اعتبار سنجی سمت کاربر را انجام دهد. این تابع یا همان CheckItems مثال فوق، امضای استاندارد و آشنایی دارد. اگر تعیین اعتبار صورت گرفته باشد، باید args.IsValid در آن به true تنظیم شود یا بر عکس.
اصل قضیه هم، همین یک سطر کد زیر است:

var num = jQuery("table#<%=CheckBoxList1.ClientID%> input:checked").length;
کار این سطر که از جی‌کوئری استفاده می‌کند، پیدا کردن جدولی است که ID آن مساوی آی دی سمت کلاینت چک باکس لیست ما است (ASP.Net یک چک باکس لیست را به صورت یک جدول حاوی چک باکس‌ها رندر می‌کند). سپس در همان ناحیه مشغول به جستجوی چک باکس‌هایی می‌شود که تیک خورده‌اند. نهایتا تعداد آن‌ها را بر می‌گرداند.

مطالب
فایل‌های chm و مشکل فارسی - قسمت دوم

بر اساس جستجوهایی که انجام داده‌ام، CHM پشتیبانی کاملی را از یونیکد انجام نمی‌دهد (مشکل جستجو و همچنین ایندکس کردن).
اما با ترفندی می‌توان این مساله را حل کرد و آن هم تبدیل encoding فایل‌ها به عربی است (windows-1256). در این حالت هم جستجو کار می‌کند و هم عنوان صفحات هنگام جستجو در لیست موارد یاد شده درست نمایش داده می‌شود و صفحه add to favorites نیز مشکلی در نمایش عنوان‌های صفحه‌ها نخواهد داشت. روش کار به شرح زیر است:

الف) encoding تمام فایل‌های html خود را به صورت زیر تغییر دهید (از utf-8 به windows-1256):

<meta content="text/html; charset=Windows-1256" http-equiv="Content-Type">

ب) محتوای تمام فایل‌های html خود را یکبار با فرمت ویندوز 1256 ذخیره کنید. برای این منظور در دات نت به سادگی زیر می‌توان عمل کرد:
using System.IO;
using System.Text;

public static void SaveAs1256(string fileName)
{
string content = File.ReadAllText(fileName);
File.WriteAllText(fileName, content, Encoding.GetEncoding("windows-1256"));
}

شاید بعضی از ویرایشگرهای متنی هم این مورد را پشتیبانی کنند.(مانند ویرایشگر ویژوال استودیو)

ج) اصلاح فایل hhp پروژه خود
فایل hhp مربوط به html help work shop را باز کنید. (همان فایل پروژه ساخت راهنما)
اگر مثال قبل را دنبال کرده باشید، محتوای فایل آن چیزی شبیه به خطوط زیر خواهد بود:

[OPTIONS]
Compatibility=1.1 or later
Compiled file=test.chm
Contents file=Table of Contents.hhc
Default Window=win1
Default topic=page1.html
Display compile progress=No
Full-text search=Yes
Index file=Index.hhk
Language=0x429 Farsi
Title=راهنمای یک

[WINDOWS]
win1=,"Table of Contents.hhc","Index.hhk","page1.html","page1.html",,,,,0x3420,,0x304e,,,,,,2,,0


[FILES]
page1.html
page2.html

[INFOTYPES]

نیاز است تا آن‌را به صورت زیر ویرایش کرد تا فرمت 1256 به آن اعمال شود:
به قسمت options چند سطر زیر را اضافه کنید: (زبان فارسی و فونت تاهومای عربی)

Default Font=Tahoma,8,178
Language=0x429 Farsi

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

محض نمونه، کل وبلاگ جاری را به یک فایل chm تبدیل کرده‌ام که ‌آن‌را از آدرس زیر می‌توانید دریافت نمائید:
دریافت فایل

برای آزمایش، یک عبارت فارسی را در آن جستجو نمائید.


پ.ن.
این راه حلی است که به نظر من رسیده و جواب داده. اگر شما با encoding های دیگر هم جواب گرفته‌اید (مشکل جستجوی فارسی حل شده) لطفا پیغام بگذارید. با تشکر.

مطالب
نمایش خودکار آیکون لینک‌های سایت‌های خارجی با استفاده از jQuery

اگر دقت کرده باشید در کنار هر لینک خارجی (هر لینک ختم شده به خارج از سایت) در این وبلاگ، آیکون آن سایت هم به صورت خودکار نمایش داده می‌شود. از نظر من جالب بوده (خصوصا جهت مشخص کردن وجود یک لینک در میان انبوهی متن، یا برای نمایش لیستی از لینک‌ها)، نظر شما رو نمی‌دونم!
این‌کار در ادامه‌ی مطلبی است که در مورد نوشتن اسکریپت‌های گریس مانکی چندی قبل منتشر کردم. البته بهبود یافته‌ی آن است. برای ایجاد یک چنین قابلیتی در سایت فقط کافی است چند سطر اسکریپت زیر را به هدر سایت خود اضافه کنید.

<script src='http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js' type='text/javascript' />
<script type="text/javascript">
$(document).ready(function(){
$("a").each(function(){
var $a = $(this);
var href = $a.attr("href");
// see if the link is external
if (href && href.match(/^http/))
if (!href.match(document.domain)) {
var domain = href.replace(/<\S[^><]*>/g, "").split('/')[2];
var image = '<img src="http://' + domain +
'/favicon.ico" width="0" ' +
' onload="this.width=16;this.height=16;this.style.paddingLeft=\'3px\';this.style.paddingRight=\'1px\';" ' +
' style="border:0" ' +
' onerror="this.src=\'http://vahid.nasiri.googlepages.com/weblink.gif\';" />';
$(this).prepend(image);
}
});
});
</script>

توضیحاتی در مورد جزئیات برنامه نویسی آن:
با استفاده از jQuery ، زمانیکه document ما ready شد ( document.ready )، تمام لینک‌های موجود در صفحه را پیدا می‌کنیم (یک به یک). سپس مقدار href آن‌ها را می‌خوانیم (ببینید با jQuery انجام این نوع کارها چقدر ساده شده است). اکنون روی لینک دریافت شده باید پردازش صورت گیرد و نام دومین آن جدا شود (اگر ختم به خارج از سایت بود). سپس بر اساس این دومین ، یک تگ img منتهی به آیکون آن سایت طراحی و نمایش داده خواهد شد (به قبل از لینک اضافه می‌شود).
عموما هر پروژه‌ای هر چند کوچک و به ظاهر کم اهمیت، نکات خاصی را به همراه دارد.
برای مثال، در ابتدای کار width=0 در نظر گرفته نشد. مشکلی را که ایجاد کرد این بود که یک سایت ممکن است اصلا favicon.ico نداشته باشد. فایرفاکس محترم اصلا به روی مبارک هم نخواهد آورد و شما متوجه نخواهید شد که در صفحه کمبود تصویری وجود دارد. اما در IE حتما جای خالی آیکون و تصویر به نحوه واضحی گوشزد می‌شود. بنابراین در ابتدای کار قرار نیست چیزی را نمایش دهیم (width=0). سپس در رخ‌داد onload تگ img، اگر تصویر واقعا وجود داشت و بارگذاری شد، طول و عرض آن‌را 16 در 16 قرار خواهیم داد (این مورد هم لازم است. چون بعضی از سایت‌ها اندازه‌های بسیار بزرگی را برای آیکون خود در نظر می‌گیرند که اصلا مقصود ما را برآورده نخواهند کرد).
این مورد (عدم نمایش تصاویری که وجود ندارند) مشکلی را که در ادامه ایجاد خواهد کرد، عدم یکنواختی در سایت است. یک سری از لینک‌های خارجی آیکون دارند و یک سری خیر. نکته جالبی که در مورد تگ img وجود دارد رخ‌داد onerror آن است. اگر مرورگر نتواند تصویر مورد نظر را پیدا یا بارگذاری کند، این روال رخ‌داد‌ گردان فراخوانی می‌شود. همینجا از موقعیت استفاده شده و src تصویر جاری به یک آیکون مشخص و از قبل تعیین شده تنظیم می‌شود.

مطالب
یک نکته کوچک راجع به تعریف Mime Type ها روی سرور
همان طور که می‌دانید در css امکان استفاده از فونت‌های فارسی مهیاست. برای این کار کافیست با دستور زیر فونت را در فایل css خود تعریف کنیم و در صورتیکه فونت روی سیستم کاربر موجود نباشد ابتدا فونت روی سیستم دانلود شده و سپس نمایش داده می‌شود. استفاده از سه پسوند مختلف نیز برای مرورگرهای مختلف در نظر گرفته شده است تا خروجی در تمامی مرورگر‌ها به درستی نمایش داده شود.
@font-face {
  src: url('Font/BYekan.eot?#') format('eot'),  /* IE6–8 */
       url('Font/BYekan.woff') format('woff'),  /* FF3.6+, IE9, Chrome6+, Saf5.1+*/
       url('Font/BYekan.ttf') format('truetype');  /* Saf3—5, Chrome4+, FF3.5, Opera 10+ */
}
در یک پروژه با مشکل عجیبی روبرو شدم . پروژه روی لوکال به خوبی کار می‌کرد اما بعد از آپلود روی سرور فونت‌ها بسیار دیر لود می‌شد. یعنی ابتدا تمامی اجزای صفحه لود شده و با تاخیری چند ثانیه ای فونت نمایش داده می‌شد. مرورگری که در حال کار روی آن برای تست پروژه بودم باید از پسوند woff مربوط به آن فونت استفاده می‌کرد.
بعد از تست پروژه با فایرباگ متوجه شدم که متاسفانه اصلا فونت روی سیستم دانلود نشده و خروجی 404 که مربوط به File Not Found است برگشت داده می‌شود. سعی کردم با دادن آدرس فونت در برنامه download manager فونت را دانلود کنم. اما باز هم فونت دانلود نمی‌شد! (یعنی فایل روی سرور موجود بود ولی هیچ دسترسی به آن ممکن نبود) برای دو پسوند دیگر یعنی eot  و ttf هم این کار را تست کردم و متوجه شدم روی این دو پسوند مشکل خاصی وجود ندارد. با تماس با پشتیبانی هاست متوجه شدم اصلا این پسوند در Mime Type های سرور تعریف نشده است . بنابراین به صورت دستی Mime Type مورد نظر را روی سرور تعریف کردم و مشکل حل شد:

همچنین لیست کامل Mime Types‌ها در آدرس زیر موجود است:

لیست کامل Mime Types 

مطالب
لینک‌های هفته‌ی اول اسفند

وبلاگ‌ها ، سایت‌ها و مقالات ایرانی (داخل و خارج از ایران)

Visual Studio

ASP. Net

طراحی و توسعه وب

اس‌کیوال سرور

عمومی دات نت

ویندوز

متفرقه
بازخوردهای دوره
استفاده از StructureMap به عنوان یک IoC Container
سلام من یه مشکل توی کدم دارم
من از structureMap استفاده میکنم
من یه WebViewPage ساختم و توش از یه Property استفاده کردم  از نوع IText و حالا می‌خوام این Property به وسیله DI یک وهله از اون ساخته بشه یه سری تنظیماتی رو هم انجام دادم ولی هرکاری کردم نشد کسی می‌تونه کمکم کنه
  public abstract class WebViewPage<TModel> : System.Web.Mvc.WebViewPage<TModel>
    {
        public IText _text { get; set; }
        public Localizer T
        {
            get
            {
                return _text.Get;
            }
        }


        public override void InitHelpers()
        {
            //_text = ProjectObjectFactory.Container.GetInstance<Text>();
            base.InitHelpers();
        }
    }

    public abstract class WebViewPage : WebViewPage<dynamic>
    {

    }
}
و این هم تنظیمات StructureMap
public class TestRegistry : Registry
    {
        public TestRegistry()
        {

           // Policies.FillAllPropertiesOfType<IText>().Use<Text>();
           
            For<IText>().Use<Text>();

            Policies.SetAllProperties(x =>
            {
                x.OfType<IText>();
            });


        }
    }
اشتراک‌ها
استفاده از MVVM در ASP.NET Core

Open source MVVM framework for ASP.NET Core and OWIN 

View

@viewModel DotvvmDemo.CalculatorViewModel, Dotvvm
    
<p>
    Enter the first number: 
    <dot:TextBox Text="{value: Number1}" />
</p>
<p>
    Enter the second number: 
    <dot:TextBox Text="{value: Number2}" />
</p>
<p>
    <dot:Button Text="Calculate" Click="{command: Calculate()}" />
</p>
<p>
    The result is: {{value: Result}}
</p>

ViewModel

using System;
    
namespace DotvvmDemo 
{
    public class CalculatorViewModel 
    {
            
        public int Number1 { get; set; }
            
        public int Number2 { get; set; }
            
        public int Result { get; set; }
            
        public void Calculate() 
        {
            Result = Number1 + Number2;
        }
    }
}


استفاده از MVVM در ASP.NET Core
نظرات مطالب
صفحه بندی، مرتب سازی و جستجوی پویای اطلاعات به کمک Kendo UI Grid
یک نکته درباره‌ی فیلترینگ اولیه (پیشفرض)
اگر خواستید که به صورت پیشفرض (قرار دادن یک یا چند فیلتر به صورت پیش فرض) گرید بر اساس یک Enum فیلتر شود مقدار Enum ارسالی از سمت سرور به رشته تبدیل شود و مقدار ایندکس آن ارسال نشود
این Enum
public enum RequestStatus : byte
{
    Checking,
    Accepted,
    Rejected
}

var query = _context.Products.Select(x => new { x.Status.ToString(), ... });
بعد در سمت کلاینت و filed ها
"Status": { type: "string" },
و فیلتر کردن اولیه
filter: [
    { field: "Status", operator: "eq", value: "Checking" },
],

و بعد قسمت Column ها
field: "Status",
    values: [
    { text: "در حال بررسی", value: "Checking" },
    { text: "تایید شده", value: "Accepted" },
    { text: "رد شده", value: "Rejected" },
],
title: 'وضعیت'

نظرات مطالب
کمی درباره httpmodule
از رویداد AcquireRequestState  استفاده کنید ، همانطور که گفتیم این رویداد برای مدیریت stateهاست ، عموما در رویدادهای ابتدایی session‌ها هنوز ایجاد نشدند
کد زیر نمونه ای از دسترسی به session هاست :
public void Init(HttpApplication app)
        {
            app.AcquireRequestState+=new EventHandler(_AUTH);
        }

    private void _AUTH(object sender, EventArgs e)
        {
            HttpApplication app = (HttpApplication) sender;
            HttpContext context = app.Context;
            HttpSessionState session = context.Session;

                if(session!=null)
            {
                string text = "session is not exist";
                if (session["userid"] != null)
                {
                    text = "session is exist";
                }
                    context.Response.Write(text);
               
            } 

        }
توجه داشته باشید که خط (if(session!=null بسیار مهم هست و در صورت نبودن خط شرطی بعدی دچار خطایی که شما گرفتید می‌شود