0

پشت صحنه فایلهای ASPX چه رخ میدهد؟

 
amirpetrucci0261
amirpetrucci0261
کاربر طلایی1
تاریخ عضویت : تیر 1388 
تعداد پست ها : 27726
محل سکونت : http://zoomstar.ir/

پشت صحنه فایلهای ASPX چه رخ میدهد؟

صفحات asp.net معمولا از دو فایل تشکیل شده اند: یک فایل aspx که حاوی ظاهر و اینترفیس صفحه است و یک فایل cs یا vb که به صورت یک فایل dll کامپایل شده و حاوی کدهایی است که رخداد های صفحه را کنترل میکنند . به این كدها اصطلاحا کدهای پشت صحنه یا code behind گفته میشود. این مقاله قصد دارد تا به بررسی دقیق تر فایلهای Aspx بپردازد. زیرا همانگونه که گفته شد فایلهای حاوی کد كامپايل میشوند و به فایلdll تبدیل میگردند.
حقیقت این است که asp.net هرکدام از فایلهای aspx را به اسمبلی تبدیل میکند. اولین باری که قرار است برنامه شما اجرا شود 3 مرحله زیر اتفاق می افتند:

1- ایجاد یک فایل cs یا vb که حاوی کدی میباشد که با اعلانهای فایل aspx همخوانی داشته باشد
2- استفاده از کامپایلر سی شارپ یا وی بی برای کامپایل کردن فایل cs یا vb به فایل DLL مورد نظر
3- اجرای فایل DLL کامپایل شده

این دنباله تنها یکبار رخ میدهد و نتیجه آن یک فایل DLL است که برای همه درخواستهایی (request) که از سرور میشود پاسخگوست مگر آنکه بخواهیم در صفحه تغییری دهیم و این تغییر منجر به این شود که بخواهیم این دنباله را از سر بگیریم.


اگر شما از این موضوع که چرا بار اولی که یک برنامه کاربردی asp.net را اجرا میکنید زمان زیادی گرفته میشود متعجب هستید، احتمالا اکنون تعجب شما برطرف شده است!


برای آنکه بهترمتوجه شوید این دنباله چگونه انجام میشود، بهتر است نگاهی به مثال ساده زیر بیندازید. در این مثال یک صفحه ساده aspx که حاوی یک پانل، textbox و اسکریپت سمت سرور است ایجاد کرده ایم. در زیر میتوانید کد صفحه aspx را مشاهده کنید:

<%@ Import Namespace="System.Web" %>
<%@ Page language="c#" Codebehind="WebForm13.aspx.cs"
AutoEventWireup="false" Inherits="WebApplication22.WebForm13" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>WebForm13</title>
<meta content="Microsoft Visual Studio 7.0" name="GENERATOR">
<meta content="C#" name="CODE_LANGUAGE">
<meta content="JavaScript" name="vs_defaultClientScript">
<meta content="http://schemas.microsoft.com/intellisense/ie5"
name="vs_targetSchema">
</HEAD>
<body MS_POSITIONING="GridLayout">
<script language="C#" runat="server">
private void myfunc(object sender, System.EventArgs e)
{
HttpContext.Current.Response.Write("Text Init");
}
</script>
<form id="WebForm13" method="post" runat="server">
<asp:TextBox id="TextBox1" OnLoad="myfunc"
style="Z-INDEX: 101; LEFT: 101px; POSITION: absolute; TOP: 114px"
runat="server" Width="170px" Height="48px"></asp:TextBox>
<asp:Panel id="LblNav"
style="Z-INDEX: 102; LEFT: 22px; POSITION: absolute; TOP: 63px"
runat="server" Width="269px">Panel</asp:Panel>
</form>
</body>
</HTML>

همه فایلهایی که توسط asp.net ایجاد شده اند در این پوشه قرار خواهند گرفت:

C:\$WINDOWSDir$\Microsoft.NET\Framework\vxx\Temporary ASP.NET Files\$YourWebAppName$\42343\654564

منظور از xx نسخه فریم ورک است که شما از آن استفاده میکنید.

نام دو پوشه آخر از اعداد تصادفی که توسط Asp.net تولید میشوند گرفته شده است.نکته جالب همان پوشه آخر است! چرا که آن پوشه همه فایلهای تولید شده برای فایلهای ASPX ،ACAX و ASAX را نگهداری میکند.آخرین پوشه همچنین حاوی پوشه ای است که اسمبلی نام دارد و پوشه دیگری را نگهداری میکند به نام dl2 که این پوشه حاوی زیر پوشه هایی است که نام آنها اعداد تصادفی برای همه اسمبلی های مورد ارجاع قرار گرفته از پروژه وب مورد نظر هستند و همچنین حاوی فایل DLL نیز میباشند.


ما بر روی پوشه ای که حاوی همه فایلهای تولید شده برای فایلهای ASPX، ASCX و ASCX هستند تمرکز خواهیم داشت


اولین فایلی که مورد توجه ماست فایل XML ای است که نام صفحه را نگهداری میکند مثلا (WebForm13.aspx.4689d8a0.xml). این فایل حاوی اطلاعاتی است که نگاشتی بین نام صفحه و نام تصادفی که توسط asp.net برای تولید صفحات استفاده میشود برقرار میکند. این فایل حاوی داده هایی است که با فایلهلی آن صفحه مطابقت دارند و هر گونه تغییری در این فایل منجر به ایجاد مجدد صفحه ASPX و کامپایل مجدد خواهد شد.

<preserve assem="jibrfh34" type="ASP.WebForm13_aspx" hash="49b238a170c332">
<filedep name="c:\inetpub\wwwroot\WebApplication22\bin\WebApplication22.DLL" />
<filedep name="c:\inetpub\wwwroot\WebApplication22\WebForm13.aspx" />
</preserve>

پس از این که متوجه شدید که هر فایلی که با عبارت “jibrfh34” آغاز میگردد، فایلی است که برای یک صفحه بخصوص ساخته شده است، ما میبایست هدف از ایجاد هرفایل را امتحان کنیم. مهمترین فایل، فایل cs یا vb است که خطوط سی شارپ یا وی بی تولید شده را مطابق با تگهای ASPX و کد مورد نظر نگهداری میکند. فایل res نگهدارنده منابعی است که پس از آن کامپایلر از آنها استفاده میکند. فایل cmdline حاوی دستورات خط فرمانی است که توسط asp.net برای کامپایل فایل cs یا vb از آنها استفاده میشود. این فایل شامل یک ارجاع به دیگر اسمبلی ها و بهینه سازی ها نیز هست. فایل out نیز تشکیل شده است از خروجی های فرآیند کامپایل برنامه. فایلهای dll و pdb نیز بعنوان خروجی کامپایل شده برنامه مورد استفاده قرار میگیرند.


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

using System;
using System.Collections;
using System.Collections.Specialized;
using System.Configuration;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Caching;
using System.Web.SessionState;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using ASP;
[System.Runtime.CompilerServices.CompilerGlobalScopeAttribute()]
public class WebForm13_aspx : WebApplication22.WebForm13,
System.Web.SessionState.IRequiresSessionState {

#line 19 "http://localhost/WebApplication22/WebForm13.aspx"
protected System.Web.UI.HtmlControls.HtmlForm WebForm13;
#line default
private static bool __intialized = false;
private static object __stringResource;
private static System.Collections.ArrayList __fileDependencies;
#line 13 "http://localhost/WebApplication22/WebForm13.aspx"
private void myfunc(object sender, System.EventArgs e)
{
HttpContext.Current.Response.Write("Text Init");
}
#line default
public WebForm13_aspx() {
System.Collections.ArrayList dependencies;
if ((ASP.WebForm13_aspx.__intialized == false)) {
ASP.WebForm13_aspx.__stringResource =
System.Web.UI.TemplateControl.ReadStringResource(typeof(ASP.WebForm13_aspx));
dependencies = new System.Collections.ArrayList();
dependencies.Add("c:\\inetpub\\wwwroot\\WebApplication22\\WebForm13.aspx");
ASP.WebForm13_aspx.__fileDependencies = dependencies;
ASP.WebForm13_aspx.__intialized = true;
}
this.Server.ScriptTimeout = 30000000;
}
protected override bool SupportAutoEvents {
get {
return false;
}
}
protected ASP.Global_asax ApplicationInstance {
get {
return ((ASP.Global_asax)(this.Context.ApplicationInstance));
}
}
public override string TemplateSourceDirectory {
get {
return "/WebApplication22";
}
}
private System.Web.UI.Control __BuildControlTextBox1() {
System.Web.UI.WebControls.TextBox __ctrl;
#line 20 "http://localhost/WebApplication22/WebForm13.aspx"
__ctrl = new System.Web.UI.WebControls.TextBox();
#line default
this.TextBox1 = __ctrl;
#line 20 "http://localhost/WebApplication22/WebForm13.aspx"
__ctrl.ID = "TextBox1";
#line default
#line 20 "http://localhost/WebApplication22/WebForm13.aspx"
((System.Web.UI.IAttributeAccessor)(__ctrl)).SetAttribute("style",
"Z-INDEX: 101; LEFT: 101px; POSITION: absolute; TOP: 114px");
#line default
#line 20 "http://localhost/WebApplication22/WebForm13.aspx"
__ctrl.Width = System.Web.UI.WebControls.Unit.Parse("170px",
System.Globalization.CultureInfo.InvariantCulture);
#line default
#line 20 "http://localhost/WebApplication22/WebForm13.aspx"
__ctrl.Height = System.Web.UI.WebControls.Unit.Parse("48px",
System.Globalization.CultureInfo.InvariantCulture);
#line default
#line 20 "http://localhost/WebApplication22/WebForm13.aspx"
__ctrl.Load -= new System.EventHandler(this.myfunc);
#line default
#line 20 "http://localhost/WebApplication22/WebForm13.aspx"
__ctrl.Load += new System.EventHandler(this.myfunc);
#line default
return __ctrl;
}
private System.Web.UI.Control __BuildControlLblNav() {
System.Web.UI.WebControls.Panel __ctrl;
#line 21 "http://localhost/WebApplication22/WebForm13.aspx"
__ctrl = new System.Web.UI.WebControls.Panel();
#line default
this.LblNav = __ctrl;
#line 21 "http://localhost/WebApplication22/WebForm13.aspx"
__ctrl.ID = "LblNav";
#line default
#line 21 "http://localhost/WebApplication22/WebForm13.aspx"
((System.Web.UI.IAttributeAccessor)(__ctrl)).SetAttribute("style",
"Z-INDEX: 102; LEFT: 22px; POSITION: absolute; TOP: 63px");
#line default
#line 21 "http://localhost/WebApplication22/WebForm13.aspx"
__ctrl.Width = System.Web.UI.WebControls.Unit.Parse("269px",
System.Globalization.CultureInfo.InvariantCulture);
#line default
System.Web.UI.IParserAccessor __parser =
((System.Web.UI.IParserAccessor)(__ctrl));
#line 21 "http://localhost/WebApplication22/WebForm13.aspx"
__parser.AddParsedSubObject(new System.Web.UI.LiteralControl("Panel"));
#line default
return __ctrl;
}
private System.Web.UI.Control __BuildControlWebForm13() {
System.Web.UI.HtmlControls.HtmlForm __ctrl;
#line 19 "http://localhost/WebApplication22/WebForm13.aspx"
__ctrl = new System.Web.UI.HtmlControls.HtmlForm();
#line default
this.WebForm13 = __ctrl;
#line 19 "http://localhost/WebApplication22/WebForm13.aspx"
__ctrl.ID = "WebForm13";
#line default
#line 19 "http://localhost/WebApplication22/WebForm13.aspx"
__ctrl.Method = "post";
#line default
System.Web.UI.IParserAccessor __parser =
((System.Web.UI.IParserAccessor)(__ctrl));
#line 19 "http://localhost/WebApplication22/WebForm13.aspx"
__parser.AddParsedSubObject(new
System.Web.UI.LiteralControl("\r\n\t\t\t"));
#line default
#line 19 "http://localhost/WebApplication22/WebForm13.aspx"
this.__BuildControlTextBox1();
#line default
#line 19 "http://localhost/WebApplication22/WebForm13.aspx"
__parser.AddParsedSubObject(this.TextBox1);
#line default
#line 19 "http://localhost/WebApplication22/WebForm13.aspx"
__parser.AddParsedSubObject(new
System.Web.UI.LiteralControl("\r\n\t\t\t"));
#line default
#line 19 "http://localhost/WebApplication22/WebForm13.aspx"
this.__BuildControlLblNav();
#line default
#line 19 "http://localhost/WebApplication22/WebForm13.aspx"
__parser.AddParsedSubObject(this.LblNav);
#line default
#line 19 "http://localhost/WebApplication22/WebForm13.aspx"
__parser.AddParsedSubObject(new
System.Web.UI.LiteralControl("\r\n\t\t"));
#line default
return __ctrl;
}
private void __BuildControlTree(System.Web.UI.Control __ctrl) {
System.Web.UI.IParserAccessor __parser =
((System.Web.UI.IParserAccessor)(__ctrl));
#line 1 "http://localhost/WebApplication22/WebForm13.aspx"
__parser.AddParsedSubObject(this.CreateResourceBasedLiteralControl(0, 397, true));
#line default
#line 1 "http://localhost/WebApplication22/WebForm13.aspx"
this.__BuildControlWebForm13();
#line default
#line 1 "http://localhost/WebApplication22/WebForm13.aspx"
__parser.AddParsedSubObject(this.WebForm13);
#line default
#line 1 "http://localhost/WebApplication22/WebForm13.aspx"
__parser.AddParsedSubObject(new
System.Web.UI.LiteralControl("\r\n\r\n\t</body>\r\n</HTML>\r\n"));
#line default
}
protected override void FrameworkInitialize() {
SetStringResourcePointer(ASP.WebForm13_aspx.__stringResource, 397);
this.__BuildControlTree(this);
this.FileDependencies = ASP.WebForm13_aspx.__fileDependencies;
this.EnableViewStateMac = true;
}
public override int GetTypeHashCode() {
return 423941586;
}
}
}

میتوانید توجه کنید که این فایل شامل یادداشتهایی است که کد را به خطوط HTML در متن فایل ASPX نگاشت میکنند. شما متیوانید از آن یادداشتها برای این که متوجه شوید چگونه asp.net خطوط HTML را تبدیل و تفسیر میکند استفاده کنید


هر فایل cs یا vb تولید شده یک تعریف از کلاسی است که از کلاس کد پشت صفحه (code behind ) مشتق شده و اینترفیس مورد نظر را پیاده سازی میکند.

public class WebForm13_aspx : WebApplication22.WebForm13
System.Web.SessionState.IRequiresSessionState

این کلاس (WebForm13_aspx) قبل از کلاس کد پشت صفحه (WebApplication22.WebForm13) فراخوانی خواهد شد. یعنی متد سازنده کلاس WebForm13_aspx در ابتدا فراخوانی میشود.این متد فایلهای مورد نیاز کلاس را مقداردهی اولیه میکند . اولین تابعی که باید فراخوانی گردد FrameworkInitialize. FrameworkInitialize است که متدی است محافظت شده و در کلاس TemplateControl تعریف گردیده و تنها در کلاس فایلهای ASPX پیاده سازی شده است.


FrameworkInitialize سپس متد __BuildControlTree را فراخوانی میکند که مسوول ایجاد همه کنترلهای صفحه است. __BuildControlTree نیز متد دیگری را فراخوانی میکند که __ BuildControlWebForm13 نام دارد و فرم اصلی صفحه را ایحاد کرده و سپس __BuildControlXXX را برای هر کنترل روی فرم فراخوانی میکند. اگر کنترل مربوطه حاوی کنترلهای فرزند باشد، __BuildControlXXX برای هریک از آن کنترلها نیز فرخوانی خواهد شد.


هر تابع __BuildControlXXX یک شیء توسط اعلان ASPX کنترل مورد نظر ایجاد میکند و سپس ویژگیها و رخدادهای آن شیء را انتساب میدهد. سپس هر تایعی که در صفحه ASPX داخل بلوک SCRIPT نوشته شده باشد و خصوصیت runat آن برابر با server باشد بعنوان متدهای کلاس به delegate مورد نظر مرتبط خواهند شد.


همانگونه که قبلا گفته شد، فایل cs یا vb در اولین مرتبه ای که asp.net یک صفحه را فراخوانی کند به صورت یک اسمبلی کامپایل میشود. ما به این نتیجه رسیده ایم که تعییراتی که در فایل Aspx رخ میدهد در HTML ای که به سمت کلاینت فرستاده میشود بازتاب نخواهد داشت.از سوی دیگر این نکته ناگفته نماند که مقداردهی اولیه رخدادهای کنترلها در C# در کدپشت صفحه رخ نخواهند داد و کاملا در کد ASPX اتفاق می افتند


اکنون که متوجه شدیم در فایلهای ASPX چه رخ میدهد، بهتر است به چرخه حیات صفحه برگردیم و آن را به روز سازیم.در آن فرآیند دو کلاس وجود دارد:

1- کلاس کد پشت صفحه - WebForm1
2- کلاس تولید شده برای فایل ASPX - adbdef

:

ترتیب فراخوانی ها از این قرار هستند

1- ایجاد adbdef
2- ایجاد WebForm1
3- فراخوانی متد FrameworkInitialize از کلاس adbdef
4- فراخوانی __ BuildTree و دیگر متدهای ساخت
5- فراخوانی صفحه و رخدادهای کنترلهای آن به ترتیب. اگر رخدادها هم در فایل aspx و هم در کد پشت صفحه اعلان شده باشند، رخدادهای اعلان شده در فایل aspx زودتر فراخوانی میگردند

چهارشنبه 10 آذر 1389  5:35 AM
تشکرات از این پست
دسترسی سریع به انجمن ها