using System; using System.Collections.Generic; using System.Data.SqlClient; using System.Linq; using System.Web; public class GallerySite { int iD; public int ID { get { return iD; } set { iD = value; } } string imagePath; public string ImagePath { get { return imagePath; } set { imagePath = value; } } string imageText; public string ImageText { get { return imageText; } set { imageText = value; } } public List<GallerySite> GetImage() { List<GallerySite> _Gallery = new List<GallerySite>() { }; SqlConnection cnn = new SqlConnection("Data Source=.;Initial Catalog=RoshanZamirDataBase;Integrated Security=True"); cnn.Open(); SqlCommand cmd = new SqlCommand("Select * From Gallery", cnn); SqlDataReader datareadfewr = cmd.ExecuteReader(); if (datareadfewr.HasRows) { while (datareadfewr.Read()) { _Gallery.Add(new GallerySite() { ID = Convert.ToInt32(datareadfewr["ID"]), ImagePath = (string)datareadfewr["ImagePath"], ImageText=(string)datareadfewr["ImageText"] }); } } return _Gallery; } } ................................................................................................................................. <link href="orbit-1.2.3.css" rel="stylesheet" /> <script src="jquery-1.8.3.min.js"></script> <script src="jquery.orbit-1.2.3.min.js"></script> <script type="text/javascript"> $(function () { $.ajax({ url: "Handler.ashx", contentType: "application/json; charset=utf-8", success: function (data) { $.each(data, function (i, b) { var str = '<img src="' + b.ImagePath + '" alt="' + b.ImageText + '"/>'; $("#featured").append(str); }); $('#featured').orbit(); }, dataType: "json" }); }); </script> ........................................................................................................................... Handler : public class Handler : IHttpHandler { public void ProcessRequest (HttpContext context) { var _Gallery = new GallerySite(); var List = _Gallery.GetImage(); string str = JsonConvert.SerializeObject(List); context.Response.Write(str); } public bool IsReusable { get { return false; } } }
- کش کرنل به صورت پیش فرض بر روی صفحات ایستا فعال شده است؛ نه برای صفحاتی با محتوای پویا که البته این مورد قابل تغییر است که نحوه این تغییر را پایینتر توضیح خواهیم داد.
- اگر آدرس درخواستی شامل کوئری باشد صفحه کش نخواهد شد: http://www.site.info/postarchive.htm?id=25
- برای پاسخ ازمکانیزمهای فشرده سازی پویا استفاده شده باشد مثل gzip کش نخواهد شد
- صفحه درخواست شده صفحه اصلی سایت باشد کش نخواهد شد : http://www.dotnettip.info ولی اگر درخواست بدین صورت باشه http://www.domain.com/default.htm کش خواهد کرد.
- درخواست به صورت ناشناس anonymous نباشد و نیاز به authentication داشته باشد کش نخواهد شد (یعنی در هدر شامل گزینه authorization میباشد).
- درخواست باید از نوع نسخه http1 به بعد باشد.
- اگر درخواست شامل Entity-body باشد کش نخواهد کرد.
- درخواست شامل If-Range/Range header باشد کش نمیشود.
- کل حجم response بییشتر از اندازه تعیین شده باشد کش نخواهد گردید، این اندازه در کلید ریجستری UriMaxUriBytes قرار دارد. اطلاعات بیشتر
- اندازه هدر بیشتر از اندازه تعیین شده باشد که عموما اندازه تعیین شده یک کیلو بایت است.
- کش پر باشد، کش انجام نخواهد گرفت.
برای تعیین مقدار سایز کش response که در بالا اشاره کردیم میتوانید در همان پنجره، گزینه edit feature settings را انتخاب کنید.
این قسمت از مطلب که به نقل از مقاله آقای Karol Jarkovsky در این آدرس است یک سری تست هایی با نرم افزار(Web Capacity Analysis Tool (WCAT گرفته است که به نتایج زیر دست پیدا کرده است:
نه من این رو تستی انجام دادم.
هدف اصلی من ارسال ایمیل انبوه بود به این صورت که تعداد زیادی ایمیل بر اساس صنفهای کاری در یک جدول ذخیره شدن. مثلاً صنف ساختمانی، ...
حالا من میخوام یک صفحه داشته باشم
ادمین بیاد از دراپ دان گروه رو انتخاب کنه و بر حسب صنف حالا مثلاً 100 تا ایمیل بهش نشون داده میشه.
بعد به فرض یه متن رو در یک تکست باکس وارد کنه و این متن به این افراد ایمیل بشه.
در این لینک توضیحات کاملتری رو داده بودم ولی هنوز جوابی نگرفتم.
http://forums.asp.net/t/1998923.aspx?send+mass+email+using+quartz+net
از ویندوز سرویس هم نمیتونم استفاده کنم چون هاستها اشتراکی هستند و ادمین هاست اجازه نصب نمیده.
- جاوا اسکریپت توانایی خواندن، نوشتن، کپی و اجرای فایلها را بر روی هارد دیسک ندارد و همچنین دسترسی مستقیمی به سیستم عامل ندارد.
- مرورگرهای مدرن اجازه کار با فایلها را به جاوا اسکریپت میدهند؛ بشرطی که آن فایل از طریق input درون صفحه وب و با اجازه کاربر انتخاب شود و فقط محدود به دسترسی به همان فایل است.
- وقتی یک تَب جدید را در مرورگر باز میکنید، جاوااسکریپتِ این دو تَب (دو صفحهی جداگانه) هیچ دسترسی و اطلاعاتی بهم ندارند.
- جاوااسکریپت به کوکیها دسترسی دارد (کوکی، فایلهای متنی کوچکی برای ذخیره اطلاعات کاربر از یک سایت است؛ مانند نام کاربری و کلمه عبور). از کوکیها برای ذخیرهی توکن نشستها استفاده میشود. لذا اگه هکر بتواند کوکی نشست یک کاربر را بدست بیاورد، میتواند از هویت او استفاده کند و خود را بجای کاربر مورد نظر قرار دهد.
- جاوااسکریپت امکان تغییرات در DOM مرورگر را دارد (داخل صفحهای که جاوااسکریپت در آن اجرا شده است).
- جاوا اسکریپت با استفاده از شیء XMLHttpRequest میتواند درخواستهای HTTP را با محتوای دلخواه، به مقصد مورد نظر ارسال نماید.
- در مرورگرهای مدرن امروزی امکان دسترسی به دوربین، میکروفن، GPS وفایلهای خاصی از طریق APIهای HTML5 امکانپذیر هست.
انواع روشهای XSS
- روش بازتابی Reflected XSS Attack
- روش ذخیره شده Stored XSS Attack
- روش مبتنی بر DOM-based XSS
روش بازتابی Reflected XSS Attack
ASP.NET MVC #19
میشه لطفا راهنمایی کنید ؟
<script src="//code.jquery.com/jquery-1.11.3.min.js"></script> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script> <link href="~/content/css/bootstrap-switch.min.css" rel=stylesheet"></link> <script src="~/Scripts/bootstrap-switch.min.js"></script>
نکته مهم: فایل css شامل دو نسخه هست که یکی از آن برای Bootstrap2 و دیگری برای نسخه 3 آن است که نسبت به آن نسخه، استایل مناسب را انتخاب کنید.
var model=BootstrapSwitchModel(); //وضعیت فعال بودن و غیرفعال بودن سوئیچ model.Checked=true; //اندازه آن model.Size=BootstrapSize..normal; //یک انیمیشن ساده موقع سوئیچ کردن دارد model.Animate=true; //به چک باکس عادی تبدیل میشود model.Disabled=true; //غیرفعال شده و به صورت فقط خواندنی قابل دسترس است model.Readonly=true; //رنگ قعال بودن model.OnColor=BootstrapColor.Success; //رنگ غیرفعال بودن model.OffColor=BootstrapColor.Danger; //متن نمایشی در هنگام فعال بودن model.OnText="On"; //متن نمایشی در حالت عدم انتخاب model.OffText="Off"; //بین دو حالت روشن و خاموش نمایش داده میشود model.label="Public Display"; //تعیین میزان اندازه برچسب بالا model.LabelWidth=100; //سوئیچ به صورت آینه ای معکوس میشود model.Inverse=false; //کلاسی جهت تغییر استایل سوئیچ model.BaseClass="myclass"; //تعیین کلاس برای تگ اصلی پدر model.WrapperClass="wclass"; //فقط یکی از چند سوئیچ میتواند فعال باشد model.RadioAllOff=false; //یک سوئیچ در حالت عادی فقط یکی از //وضعیتها را نمایش میده ولی در این حالت //سوئیچ در ابتدا بین این دو وضعیت گیر کرده است model.Indeterminate=true; //اندازه سمت چپ و راست سوئیچ model.HandleWidth=25;
@{ var model=BootstrapSwitchModel(); ....} @HTML.BootstrapSwitch("id",model);
CACHE MANIFEST #Cache Section CACHE: /Content/Images/icons-18-white.png /Content/Images/icons-36-white.png /Content/Images/ajax-loader.png /Content/css /Scripts/js
NETWORK webService.Js
CACHE MANIFEST # 2010-06-18:v2 # Explicitly cached 'master entries'. CACHE: /favicon.ico index.html css images/ stylesheet .logo.png scripts/main.js # Resources that require the user to be online. NETWORK: login.php /myapi http://api.twitter.com
AddType text/cache-manifest .appcache
using System.Web; namespace JavaScriptReference { public class Manifest : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/cache-manifest"; context.Response.WriteFile(context.Server.MapPath("Manifest.txt")); } public bool IsReusable { get { return false; } } } }
CACHE MANIFEST # Version Jesus 3! CACHE: index.html js/Custom.js js/Utility.js styles/index.css styles/kendo.common.min.css styles/BlueOpal/loading.gif styles/BlueOpal/slider-h.gif styles/BlueOpal/slider-v.gif NETWORK: * <%@ Page Language="VB" ContentType="text/cache-manifest" ResponseEncoding="utf-8" AutoEventWireup="true" CodeFile="manifest.aspx.vb" Inherits="Configuration_manifest" %>
<!DOCTYPE html> <html manifest="/manifest.aspx">
ASP.NET MVC #19
جلوگیری از ارسال Spam در ASP.NET MVC
اول اینکه سیستم کش طوری طراحی شده که وقتی به یک حد معینی از منابع استفاده کرد خالی میشه.
دوم اینکه اگر بر فرض مثال متوسط زمان فیلترگذاری ما 5 ثانیه باشه کش ما هر 5 ثانیه اون مورد رو حذف میکنه.
یک حساب سرانگشتی ساده:
سایز رشته تولید شده در MD5 همیشه ثابت و 16 بایت است.
اگر خیلی به شما ارفاق کنم و سایتی که میگین پر بازدید هست در عرض 5 ثانیه 10،000،000 درخواست داشته باشه! تنها 150 مگابایت از حافظه صرف اینکار میشه.
- برای یک وب سایت پربازدید 150 مگابایت اصلا چیزی نیست.
- اگر با یک شبکه اجتماعی سر و کار داشته باشیم هم اینکه سیستم پایگاههای داده غیررابطه ای جایگزین مناسبی هست هم اینکه اصلا میتونیم یک حافظه کاملا اختصاصی برای اون داشته باشیم (واقعا میصرفه 16 گیگ! رم بخریم برای اینکار چون شبکه اجتماعی درآمد زیادی داره)
به این نکته هم توجه داشه باشیم اگر پارامتر سوم رو حذف کنیم به ازای هر IP در هر 5 ثانیه فقط یک درخواست میتونیم داشته باشیم و این یعنی باید از 10 میلیون مکان مختلف درخواست حمله صورت بگیره.
به نظر من استفاده از کش گزینه خیلی خوبی هست ولی میشه با ترکیب سایر روشها به این حساسیت پاسخ داد.
کار کردن با مسیریابی برای یک پروژه ساده ، نیاز به طراحی پیچیده ندارد. مسیریابی پیش فرض موجود در فایل RoutConfig.cs برای کارهای ابتدایی کافیست. اما اگر کمی کار پیچیده شود و صفحات مختلفی با منطقهای متفاوتی ایجاد کنیم، ممکن است با مشکل روبرو شویم. در MVC5 به کمک دخالت ویژگیها در مسیریابی، کار ساده شده است اما در MVC4 و قبل از آن چه باید کرد؟ پیش از بسط مساله، ابتدا این سوال را پاسخ میدهیم که چگونه صفحهی start پروژه انتخاب میشود؟
مسیریابی پیش فرض یک پروژه MVC به شکل زیر است :
routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } );
وقتی یک پروژه MVC را بررسی کنید، مشاهده میکنید که در شاخهی اصلی آن، فایل index یا default وجود ندارد و اصولا منطق کار با اکشنها و صدا زدن آنها و دیدن پاسخها توسط View، این اتفاق را توجیه میکند. پس وقتی درخواستی به سمت شاخهی اصلی ما فرستاده میشود، مسیریابی وارد عمل میشود. وقتی پروژه را اجرا میکنید، متد RegisterRoutes از شیءایی که از کلاس RoutingConfig.cs ساخته شده (به فایل global.asax نگاه کنید) فراخوانی میشود و شیء Routes از " قالب آدرس " هایی که ما تعیین کرده ایم پُر میشود. بخشی از فایل RoutConfig.cs را در تصویر زیر میبینیم.
به Url کد فوق نگاه کنید که در حقیقت آدرسی نسبی است. آدرس ما به طور کامل به شکل زیر قابل تعریف است:
http://mydomain.com/{controller}/{action}/{id}
واضح است که درخواست اولیه به سایت ما دارای بخشهای controller و action و بخش اختیاری id نیست. پس به شکل پیشفرض بر اساس آنچه در جلوی خصوصیت defaults نوشته شده است، فراخوانی خواهد شد. یعنی اکشن Index از داخل کنترلر Home صدا زده میشود و چون id نداریم، هیچ نوع id به متد (اکشن) index ارسال نخواهد شد.
یک روتینگ دیگر به شکل زیر در بالای کد فوق اضافه کنید :
routes.MapRoute( name: "Default1", url: "{controller}/{action}/{id}", defaults: new { controller = "News", action = "Index", id = UrlParameter.Optional } );
حتما متوجه شدید که اینبار با اجرای پروژه، متد(اکشن) Index از کنترلر News فراخوانی خواهد شد. در حقیقت اولین روتینگ ساخته شده همان چیزیست که Asp.NET MVC پس از دریافت ریکوئست به آن رجوع میکند. دقت کنید که مقدار name در دو MapRouting فوق متفاوت است.
اما این اسمها(name ها) به چه دردی میخورند؟
قبل از توضیح در این مورد، default1 را از پروژه حذف میکنیم و با همان MapRouting پیش فرض به کار خود ادامه میدهیم. ابتدا مروری بر عملکرد MapRouting انجام میدهیم.
همانطور که میدانید برای ایجاد یک لینک از طریق ویوی Razor از چیزی شبیه دستور زیر میتوانیم استفاده کنیم:
<a href="@Url.Action("post", "News", new { id = @item.PostName }, null)"> @item.PostTitle </a>
فرض کنید یک سایت خبری داریم و گروههای مختلف آن شامل مطالب متفاوتی هستند. کنترلری به نام News ایجاد کردهایم، که دارای یک اکشن به نام post است که نام مطلب را دریافت کرده و یک View به ما برمیگرداند. بخش هایی از صفحه اول را در تصاویر زیر میبینید. تصویر آخر، بخش پایین صفحه اخبار است، که بوسیله لینک (لینک های) موجود صفحات جابجا میشوند.
وقتی کد فوق در یک صفحه فراخوانی میشود، کالکشن Routes بررسی میشود و لینک مورد نظر، با توجه به ورودیهای Url.Action ساخته میشود. ما یک MapRouting به نام Default در کالکشن Routes داریم، پس Url.Action لینک زیر را میسازد:
http://mydomain.com/news/post/نام-مقاله
استفاده از MapRouting مثل یک جعبه است که ورودی آن مقادیر موجود در Url.Action میباشد و آنچه به ما بر میگرداند یک آدرس برای فراخوانی اکشن مورد نیاز است. (آخرین پارامتر، null قرار داده شده که برای تعیین نوع پروتکل استفاده میشود که http یا https میتواند باشد.)
برای فراخوانی صفحهی اخبار (لیست اخبار) میتوانید دستور زیر را بنویسید :
@Html.ActionLink("اخبار", "Index", "News", null, new { @class="btn btn-success"})
این دستور تگ anchor را نیز میسازد و به کمک MapRouting آدرسی شبیه آدرس زیر را به ما بر میگرداند. (به تفاوت دو دستور دقت کنید):
<a href="/News">اخبار</a>
واضح است که چون MapRouting یک حالت پیش فرض درونی دارد که دارای اکشن دیفالت index است، پس ActionLink اگر ببیند لینکش در صفحه قرار است به شکل /news/index تعریف شود خود بخود بخش index را حذف میکند.
فرض کنید بعد از کلیک روی لینک فوق، اکشن index ، یک آبجکتِ لیستی با 10 خبر آخر، ایجاد میکند. پس ما میخواهیم قابلیت صفحه بندی را برای لیست اخبار فعال کنیم و در هر صفحه 10 مطلب را نمایش دهیم. مشکل از همینجا آغاز میشود. MapRouting فعلی جوابگوی ما نخواهد بود و آدرس را به شکل زیر نمایش میدهد.
<a href="/News/index?pid=2">صفحه بعد</a>
و آنچه ما در View نوشتهایم چیزی شبیه کد زیر است :
@Html.ActionLink("صفحه بعد", "index", "News", new { pid = …. }, null)
مشکلی در ارجاع به صفحات وجود ندارد و با کلیک روی لینک "صفحه بعد" مقدار عدد 2 به اکشن index ارسال میشود و اگر کد نویسی را برای take و skip کردن لیست، درست انجام شده باشد، نتیجه مورد نظر نمایش داده خواهد شد. اما آدرس فوق آدرس زیبایی نیست. اولین فکری که به ذهن برنامه نویس میرسد، ایجاد یک مسیریابی دیگر است. فکر درستیست؛ اما اگر چند بار دیگر این اتفاق بیفتد و در بخش هایی از برنامه نیاز به روتینگ پیدا کنید و روتینگهای جدید ایجاد کنید متوجه خواهید شد که مدیریت این MapRouting ها کار خسته کننده و طاقت فرسایی خواهد شد، مخصوصا اگر بدانید که فقط مجاز به استفاده از یک پارامتر optional در هر MapRouting هستید! دست شما کاملا بسته است. لینکهای بالای سایت را اصلاح میکنید ولی لینکهای پایین سایت خراب میشوند و بالعکس.
به هر حال MapRouting زیر را به RoutConfig.cs اضافه میکنیم :
اینکار بستگی به پروژهی شما دارد، مپ روتینگ فوق این مزیت را دارد که با مپ روتینگهای دیگر به سختی قاطی میشود! یعنی حتا اگر قبل از مپ روتینگ دیفالت نوشته شود برنامه با مشکل مواجه نخواهد شد، چون اصلا شکل درخواست اولیه به سایت، چیزی شبیه این آدرس نیست. اما خاص بودن آن و همچنین نوع بهره گیری از آن با کمک Action یا ActioLink شاید شما را سردرگم خواهد کند.- اسم این MapRouting ، دیگر Default نیست.routes.MapRoute("PostPaging", "{controller}/{action}/{id}/{pid}", defaults: new { controller = "News", action = "Index", id = "all", pid = UrlParameter.Optional } );
- یک پارامتر pid اضافهتر از MapRouting اولی دارد.
- pid به عنوان یک پارامتر اختیاری تعریف شده است، پس "قالب آدرس" بسیار شبیه مپ روتینگ قبلی است.
- مقدار id اختیاری نیست، چون قرار است در آینده بتوانیم گروههای مختلف موجود در بخش اخبار را صفحه بندی کنیم و قرار نیست پشت سر هم MapRouting ایجاد کنیم و کافیست به جای id اسم گروه را بنویسیم. در حالتیکه اسمی از گروه درلینکهایمان نبرده باشیم به شکل پیشفرض all قرار داده میشود که یعنی کل اخبار مد نظر است. (در اکشن مربوطه باید این تصمیمات را لحاظ کنیم)
- حتما این MapRouting را بعد از MapRouting اولیه بنویسید، کمی پیشتر، علت این امر توضیح داده شد و گفته شد اولین چیزی که MVC پس از درخواست ما میبیند به عنوان Routing بررسی میکند (درخواست اولیه) و چون ساختار MapRouting فوق تا اندازه ای شبیه ساختار Default MapRouting است ممکن است با فراخوانی سایت مشکل ایجاد شود.
- میتوانید MapRouting را کمی خاصتر هم بنویسیم :
routes.MapRoute("NewsPaging", "News/index/{id}/{pid}", defaults: new { controller = "News", action = "Index", id = "all", pid = UrlParameter.Optional } );
اما مشکل این MapRouting ها چیست؟
درخواست به سایت آمده و قرار است سایت بارگذاری شود؛ ترتیب زیر در شیء routes ثبت شده است :
در صفحه اول ما لینکی به شکل زیر گذاشته ایم :
@Html.ActionLink("اخبار", "Index", "News", null, new { @class="btn btn-success"})
در صفحه اخبار، لینک "صفحه بعد" وجود دارد ، آیا این لینک به شکل صحیح نمایش داده میشود؟ خیر! نتیجه کار را ببینید :
<a href="/News/index?pid=2">صفحه بعد</a>
به نظر میرسد یک طرح دقیق برای آدرس دهی شاید این مسائل را حل کند ولی نه وقت داریم و نه اعصاب.
1. ساخته شدن لینکها توسط هلپرها (که از مپ روتینگهای ثبت شده ما پیروی میکند)
2. واکنش پروژه به درخواستهای دریافتی و هدایت آن به اکشنهای مورد نظر که کاملا به ترتیب ثبت مپ روتینگها در کالکشن Routes بستگی دارد .
@Html.RouteLink("صفحه بعد", "PostPaging", new { action = "cat", controller = "News", id =. .., pid = ...})
نتیجه برای لینک موجود در صفحه اخبار چیزی شبیه شکل زیر خواهد شد :
<a href="/News/cat/all/2">صفحه بعد</a>
@Html.RouteLink("اخبار", "Default", new { controller = "news" }) @Html.RouteLink("درباره ما", "pages", new RouteValueDictionary(new { controller="Page", action="Index", pagename="درباره-ما"}), new Dictionary<string, Object> { { "data-toggle", "popover" }, { "data-placement", "top" } })
همانطور که میبینید در RoutLink
اولی، اخبار را به کمک MapRouting
با نام default
بازنویسی میکنیم و نتیجه چیزی شبیه کد زیر خواهد شد :
<a href="/News">اخبار</a>
در RoutLink دومی اولا از یک RoutValueDictionary به جای یک آبجکت ساده استفاده کرده ایم و مقادیر را به شکل فوق به کنترلر و اکشن و ...نسبت داده ایم ثانیا برای بخش HTML نیز پراپرتیها را به کمک یک دیکشنری ارسال میکنیم، به خاطر وجود "-" در یکی از خواص، راه دیگری غیر از اینکار نداریم.
اما دقت کنید که از یک MapRouting جدید استفاده کردیم که نامش pages است،
این MapRoutnig را قبل از دیگر Routing ها مینویسیم؟ وسط دو MapRouting قبلی مینویسیم؟ آخر MapRouting ها مینویسیم؟ آیا فرقی میکند؟ اگر سریع بگوییم خــیر! اشتباه کرده ایم. واقعا فرق میکند.
دقت کنید موضوع MapRouting فقط ایجاد یک لینکتر و تمیز نیست؛ RoutLink یک لینک تمیز بر اساس مپ روتینگی که نامش برده شده ایجاد میکند
اما تضمین نمیکند که با کلیک بر روی لینک به هدف برسیم و به خطای 404 برخورد نکنیم! اگر روی لینک کلیک کنید آدرس شروع به تفسیر شدن
میکند و این تفسیر اصلا ربطی به نامی که به RoutLink داده ایم ندارد و ترتیب موجود در کالکشن ایجاد شده در RoutConfig تعیین کننده است.(آبجکت Routes ) اگر MapRouting فوق را در انتهای بقیه بگذاریم صفحه اول لود میشود ولی با کلیک
روی "درباره ما" صفحه پیغام خطا خواهد داد.
باید به یاد
داشته باشیم برای اجرای درخواست (کلیک روی لینک)، آنچه برای ASP.NET MVC اهمیت دارد، ترتیب قرار گیری MapRouting ها در RouteRegister است و
ما به کمک RoutLink تنها
مشکل ساخت لینکها بر اساس قالب MapRouting مورد
نظرمان را حل کردیم و این به ما تضمینی برای هدایت آن لینک به مکان درست را نخواهد
داد.
اگر ترتیب به شکل زیر باشد :
1باشد. درخواست اولیه برای بالا آمدن سایت به مشکل برخورد نمیکند چون همان مپ روتینگ 1 اجرا میشود. اما مشکل فوق به وجود خواهد آمد و خطای 404 با کلیک بر روی "درباره ما" نمایش داده خواهد شد چون با کلیک روی "درباره ما" مپ روتینگ شماره 1 وارد عمل میشود.
2
3
اگر ترتیب به شکل زیر باشد :
3آیا اصلا صفحه اول سالم لود خواهد شد؟ خیر! درخواست نسبی " / " (یا به طور کامل http://mydomain.com ) شماره 3 را به خیر پشت سر میگذارد، چون اصلا چیزی به نام page در آدرس وجود ندارد که از این MapRouting بخواهد پیروی کند. اما در شماره 2 گیر میافتد چون این فرمت را حفظ کرده است :
2
1
"{controller}/{action}/{id}/{pid}"
اگر ترتیب به شکل زیر باشد :
3این همان چیزیست که مد نظر ماست. اولا 1 قبل از 2 است و صفحه اول برای لود شدن به مشکل برخورد نمیکند.
1
2
ثانیا وقتی روی "درباره ما" کلیک میکنیم همان شماره 3 فراخوانی میشود و بقیه مپ روتینگها اعمال نمیشوند.