بررسی وجود پیاده سازی محتویات MasterPage

25 10 2009

شاید در استفاده از MasterPage ها زمانی پیش آمده باشد که لازم شده وجود پیاده سازی یک ContentPlaceHolder را در صفحه خاص رو بررسی کنید. مثلا زمانی رو در نظر بگیرید که در صفحه خاصی نباید بلوک خلاصه محتویات صفحه یا لینکها نمایش داده شود و این کادر نیز در MasterPage پیاده سازی شده است.

پس روشی باید به کار گیرید که آن کادر در آن صفحه به خصوص نمایش داده نشود. متاسفانه در دات نت روشی برای این کار در نظر گرفته نشده است؛ لااقل هیچ متد عمومی برای این کار وجود ندارد.

خوشبختانه ویژگی داخلی و مخفی در کلاس MasterPage وجود دارد به نام ContentTemplates که لیستی از ContentPlaceHolder هست که توسط صفحه جاری پیاده سازی شده است. کاری که لازم است استفاده از قدرت Reflection دات نت هست تا به آن ویژگی دسترسی پیدا کنیم.

همراه با این باید ContentPlaceHolder برای وجود کنترل در داخلی خودش هم بررسی بشه. تابع زیر برای همین کار هست:

public static bool HasNonEmptyControls(ContentPlaceHolder cph)
{
    if (cph.Controls.Count == 0)
    {
        return false;
    }
    else if (cph.Controls.Count == 1)
    {
        LiteralControl c = cph.Controls[0] as LiteralControl;

        if (string.IsNullOrEmpty(c.Text) || IsWhiteSpace(c.Text))
            return false;
    }

    return true;
}

static bool IsWhiteSpace(string s)
{
    for (int i = 0; i < s.Length; i++)
        if (!char.IsWhiteSpace(s[i]))
            return false;

    return true;
}

در ادامه تابع اصلی منظور ما که وجود پیاده سازی از یک ContentPlaceHolder به خصوص رو بررسی خواهد کرد:

static readonly Type _masterType = typeof(MasterPage);
static readonly PropertyInfo _contentTemplatesProp = _masterType.GetProperty("ContentTemplates", BindingFlags.GetProperty | BindingFlags.NonPublic | BindingFlags.Instance);

public static bool HasContentPageContent(ContentPlaceHolder cph)
{
    IDictionary templates = null;
    MasterPage master = cph.Page.Master;

    while (templates == null && master != null)
    {
        templates = (IDictionary)_contentTemplatesProp.GetValue(master, null);
        master = master.Master;
    }

    if (templates == null)
        return false;

    bool isSpecified = false;

    foreach (string key in templates.Keys)
    {
        if (key == cph.ID)
        {
            isSpecified = true;

            break;
        }
    }

    return isSpecified;
}

همانطور که از کد مشخصه با بدست آوردن ویژگی ContentTemplates که یک لسیت دیکشنری است وجود ContentPlaceHolder مورد نظر رو بررسی می کنیم.

و سر انجام ترکیبی از این دو تابع جهت بدست آوردن نتیجه مطلوب:

public static bool HasContentOrControls(ContentPlaceHolder cph)
{
    return HasNonEmptyControls(cph) || HasContentPageContent(cph);
}

و تمام. به راحتی می توانید از این تابع استفاده کنید. مانند نمونه زیر:

<%if (HasContentOrControls(plhOptions)){ %>
<div id="options">
 <div>
 <h2>
 <asp:ContentPlaceHolder ID="plhOptionsTitle" runat="server" />
 </h2>
 <asp:ContentPlaceHolder ID="plhOptions" runat="server" />
 </div>
</div>
<%}%>

همانطور که در این مثال مشاهده می کنید، فقط در صورتی که plhOptions در صفحه پیاده سازی شده باشد کادر مربوط به آن همراه با محتویات بخش plhOptionsTitle نمایش داده خواهند شد.

منبع

خوش باشید.

Advertisements




دو مقاله دو ابزار

11 03 2009

چند روز پیش کار بر روی دو تا مقاله  توصیفی برای ابزارهایی که قبلا نوشته بودم روبه پایان رسوندم که لینک آنها رو اینجا میذارم.

ابزار اولی مربوط به کنترل خطاها در Asp.Net و بعدی در مورد کار با thread ها در دلفی است.

در این مقاله به بررسی ابزار CustomErrorHandler می پردازیم که به ما این امکان را می دهد که شیوه نمایش خطاها را در ASP.NET تغییر دهیم. این خطاها از لحاظ ساختار بسیار استاندارد تر و برای گوگل قابل تشخیص تر هستند.

با استفاده ابزار ThreadWorker که برای دلفی نوشته شده است می توانید، وظایف و یا کارهای طولانی خود را بدون وقفه در کار برنامه انجام دهید.





ریستارت کردن سایت ASP.NET

13 02 2009

در وبسایت های پر بازدید پیش میاد که به دلایل مختلفی مانند توسعه و یا تست قسمتی از سایت، یا سنگین شدن سایت به علت استفاده نادرست از رم و یا حملات احتمالی که ممکن است باعث سنگین شدن سایت بشود، نیاز به راه اندازی وبسایت پیش بیاد.
البته در مورد حملات این کار می تواند موفقتا مشکل را حل کند تا فرصت کافی برای راه حل اساسی پیدا کنید.
راه اندازی مجدد یا Restart باعث خواهد شد که تمامی محتویات کش، محتویات session و حافظه پاک شده و وبسایت بسته شود تا در درخواست بعدی به طور خودکار مجددا اجرا شود.

در ASP.NET یک متد اصلی برای این کار طراحی شده است و یک متد دیگر هم وجود دارد که این کار را انجام میدهد.

متد اول:

HttpRuntime.UnloadAppDomain()

این متد باعث پایان یافتن سایت می شود و تا رسیدن درخواست بعدی سایت مجددا اجرا نخواهد شد. نکته مهمی که در استفاده از این تابع است، فراخوانی رویداد Application_End در Global.asax است که به شما اجازه میده کارهای نهایی برای آزاد سازی حافظه را انجام بدید. مزیت اصلی این تابع طی کامل مراحل و عملیات آزاد سازی حافظه و پایان کار سایت است.

متد دوم:

HttpRuntime.Close()

این متد نیز همانند متد قبلی باعث پایان کار سایت خواهد شد و سایت در درخواست بعدی مجددا اجرا خواهد شد. نکته مهم در استفاده این تابع عدم فراخوانی رویداد Application_End هست. در حقیقت این تابع سایت را به یکباره متوقف می کند که هیچیک از مراحل پایان کار سایت اجرا نخواهند شد و می تواند برای مواقع اضطراری مناسب باشد.

نکته ای که در مورد HttpRuntime.Close هست این است که در حقیقت این مدت برای پاک کردن کش سایت طراحی شده، ولی ظاهرا این کار را با بستن سایت انجام می دهد که البته نتایجی مانند Restart کردن دارد! همانطور که گفته شد تفاوت عمده این مدت در این است مراحل بسته سایت به ترتیب انجام نشده و سایت به یکباره متوقف خواهد شد تا در خواست بعدی مجددا اجرا شود.

سعی کنید در قسمت مدیریت سایت خود صفحه ای را برای فراخوانی این دو مدت طراحی کنید.





محاسبه تعداد کاربران آنلاین در ASP.NET

3 01 2009

محاسبه کاربران آنلاین در سایت یکی از مسائل مهم در آمار گیری آن هست که برای انجام آن راه های مختلفی وجود دارد. برخی سایت ها وجود دارند که چنین سرویس هایی را برای سایتها عرضه می کنند و برخی سیستم های آمار گیری وجود دارند که می توانید آن ها را خریداری کرده و یا به طور رایگان استفاده کنید.

در ASP.NET نیز چندین روش وجود دارد که یکی از آنها استفاده از رویدادهای Session است. در استفاده از شیئ Session در حالت عادی چندین مشکل مانند TimeOut وجود دارد که باعث عدم کارایی این روش می شود.

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

  • توضیحی مختصر درباره OnlineActiveUsers

این ابزار از رویدادهای شیئ Session به نحوی متفاوت استفاده می کند، به گونه ای که مشکلات استفاده از آن مرتفع شده و روشی مطمئن برخوردار خواهید بود.

در صورتی که نیاز دارید تفکیکی بر کاربران عضو در سایت و کاربران میهمان داشته باشید، این ابزار این کار را برای شما می تواند انجام دهد و تنها کافی است تا فراخوانی های مورد نیاز انجام شود.

این ابزار را کاملا تست شده نوشته ام و هم اکنون بر روی سایت خودم نصب هست.

اگر نظرات و پیشنهادی در مورد توسعه این ابزار دارید خوشحال می شوم

* مطالب مرتبط

بررسی فعال بودن Javascript در ASP.NET

راهنمای کامل توابع JQuery و MooTools به صورت CHM





بررسی فعال بودن Javascript در ASP.NET

28 12 2008

برای اینکه به فعال بودن جاوا اسکریپت در مرورگر کاربر مطمئن بشین چند روش می تونید استفاده کنید که با توجه به نیازتون یکی از اونا رو انتخاب کنید و یا ترکیبی از آنها استفاده کنید.

  • استفاده از تگ noscript

البته این روش ربطی به ASP.NET نداره ولی با این حال مفید هست. با استفاده از کد زیر می تونید کاربر رو زمانی که جاوا اسکریپت در صفحه فعال نیست به صفحه خاصی هدایت کنید.

<meta http-equiv="refresh" content="0;url=EnableScripts.htm">

همانطور که از کد مشخصه این کار باعث میشه تا کاربر به صفحه EnableScripts.htm هدایت بشه. معمولا این روش زیاد کاربر پسند نیست ولی برای صفحاتی که بدون وجود جاوا اسکریپت به هم خواهند خورد و فعال بودن آن حیاطی هست می تونید از این روش استفاده کنید. دقت کنید که کد بالا باید در بخش Head سایت قرار بگیره، مانند زیر:<head>
<title>Welcome</title>
<noscript>
<meta http-equiv="refresh" content="0;url=http://www.google.com">
</noscript>
</head>

همچنین به جای کد بالا می تونید پیغامی رو در صفحه نمایش بدید:

<noscript>
کاربر گرامی، برای مشاهده این صفحه باید جاوا اسکریپت را در مرورگر خود فعال نمایید.
</noscript>

که این کد رو می تونید در هرجای صفحه قرار بدین.

  • استفاده از فیلد مخفی یا Hidden در ASP.NET

گاهی اوقات لازم است تا در صفحه هایی مانند فرم های ویزارد که چندین مرحله دارند، از فعال بودن جاوا اسکریپت اطمینان حاصل کنید. بدین منظور می توانید از دو روش متفاوت استفاده کنید که من در اینجا یکیش رو توضیح می دم.

برای بررسی فعال بودن جاوا اسکریپت در رویداد های PostBack ابتدا باید یک فیلد hidden رو در فرم قرار بدین و مقدار این فیلد رو برابر 0 قرار بدین. چیزی شبیه این:
<asp:HiddenField ID="txtCheckJS" runat="server" Value="0" />

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

<script type="text/javascript">
document.getElementById('<%=txtCheckJS.ClientID %>').value='1';
</script>

کاری که این کد جاوا اسکریپت انجام میده تغییر مقدار فیلد به 1 هست، که یعنی جاوا اسکریپت فعال است. تنها کاری که باقی مونده بررسی این فیلد در رویداد کلیک هست. کافی هست که کدی مانند زیر رو استفاده کنید:
if (Page.IsPostBack)
{
if (Convert.ToInt32(txtCheckJS.Value) == 1)
{
// Javascript is enabled
}
else
{
// Oh No!
// Javascript is not enabled
}
}

روش دیگری از بررسی که با استفاده از Validator ها پیاده سازی شده رو می تونید تو این پست از وبلاگ وحید نصیری مطالعه کنید.