مخفی کردن کوئری استرینگ‌ها در ASP.NET MVC توسط امکانات Routing
اندازه‌ی قلم متن
تخمین مدت زمان مطالعه‌ی مطلب: سه دقیقه

ابتدا مدل و منبع داده نمونه زیر را در نظر بگیرید:
using System.Collections.Generic;

namespace TestRouting.Models
{
    public class Issue
    {
        public int IssueId { set; get; }
        public int ProjectId { set; get; }
        public string Title { set; get; }
        public string Body { set; get; }
    }

    public static class IssuesDataSource
    {
        public static IList<Issue> CreateDataSource()
        {
            var results = new List<Issue>();
            for (int i = 0; i < 100; i++)
            {
                results.Add(new Issue { IssueId = i, ProjectId = i, Body = "Test...", Title = "Title " + i });
            }
            return results;
        }
    }
}
به همراه کنترلر زیر برای نمایش لیست اطلاعات و همچنین نمایش جزئیات یک issue انتخابی:
using System.Linq;
using System.Web.Mvc;
using TestRouting.Models;

namespace TestRouting.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            var issuesList = IssuesDataSource.CreateDataSource();
            return View(issuesList); //show the list
        }

        public ActionResult Details(int issueId, int projectId)
        {
            var issue = IssuesDataSource.CreateDataSource()
                                        .Where(x => x.IssueId == issueId && x.ProjectId == projectId)
                                        .FirstOrDefault();
            return View(issue);
        }
    }
}
و View زیر کار نمایش لیست بازخوردهای یک پروژه را انجام می‌دهد:
@model IEnumerable<TestRouting.Models.Issue>
@{
    ViewBag.Title = "Index";
}
<h2>
    Issues</h2>
<ul>
    @foreach (var item in Model)
    {
   
        <li>
            @Html.ActionLink(linkText: item.Title,
                     actionName: "Details",
                     controllerName: "Home",
                     routeValues: new { issueId = item.IssueId, projectId = item.ProjectId },
                     htmlAttributes: null)
        </li>
    }
</ul>
در این حالت اگر پروژه را اجرا کنیم، هر لینک نمایش داده شده، چنین فرمی را خواهد داشت:
 http://localhost:1036/Home/Details?issueId=0&projectId=0
سؤال: آیا می‌شود این لینک‌ها را کمی زیباتر و SEO Friendly‌تر کرد؟
برای مثال آن‌را به نحو زیر نمایش داد:
 http://localhost:1036/Home/Details/0/0
پاسخ: بلی. برای اینکار تنها کافی است از امکانات مسیریابی استفاده کنیم:
using System.Web.Mvc;
using System.Web.Routing;

namespace TestRouting
{
    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                name: "IssueDetails",
                url: "Details/{issueId}/{projectId}", //تطابق با یک چنین مسیرهایی
                defaults: new 
                          { 
                                controller = "Home", //کنترلری که این نوع مسیرها را پردازش خواهد کرد
                                action = "Details", // اکشن متدی که نهایتا پارامترها را دریافت می‌کند
                                issueId = UrlParameter.Optional, //این خواص نیاز است هم نام پارامترهای اکشن متد تعریف شوند
                                projectId = UrlParameter.Optional
                          }
            );

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
        }
    }
}
در اینجا یک route جدید به نام دلخواه IssueDetails پیش از route پیش فرض، تعریف شده است.
این route جدید با مسیرهایی مطابق پارامتر url آن تطابق خواهد یافت. پس از آن کوئری استرینگ متناظر با issueId را به پارامتر issueId اکشن متدی به نام Details و کنترلر Home ارسال خواهد کرد؛ به همین ترتیب در مورد projectId عمل خواهد شد.
ضمنا در url نهایی نمایش داده شده، دیگر اثری از کوئری استرینگ‌ها نبوده و برای نمونه در این حالت، اولین لینک نمایش داده شده شکل زیر را خواهد داشت:
 http://localhost:1036/Home/Details/0/0
 البته باید دقت داشت، یک چنین اصلاح خودکاری تنها در حالت استفاده از متد Html.ActionLink رخ می‌دهد و اگر Urlها را دستی ایجاد کنید، تغییری را مشاهده نخواهید کرد.
  • #
    ‫۱۱ سال و ۷ ماه قبل، سه‌شنبه ۱۵ اسفند ۱۳۹۱، ساعت ۲۳:۵۹
    ممنونم از مطلب خوبتون
    در بعضی از پروژه‌ها که به صورت ماژول مانند هستند همانند Orchardl  میبینیم که برای هر قسمت یک قسمت مدیریت در نظر گرفته شده
    اما آدرس مدیریت  هر کدام در قسمت مدیریت بدین شکل میباشد
    مثلا ماژول تگ‌ها : که شامل 2 کنترلر یکی خود ماژول و دیگری مدیریت ماژول
    اما قسمت مدیریت  http://localhost:30320/OrchardLocal/Admin/Tags  بدین شکل است
    سوال اینجاست در اینجا بر اساس نام ماژول آن را به قسمت مدیریت آن هدایت میکند یا اینکه با امکانات مسیریابی؟


    • #
      ‫۱۱ سال و ۷ ماه قبل، چهارشنبه ۱۶ اسفند ۱۳۹۱، ساعت ۰۰:۳۱
      امکانات مسیریابی در MVC به صورت خودکار از ابتدای کار فعال است. این نوع مسیری را هم که ملاحظه می‌کنید آدرسی است به یک کنترلر و اکشن متد موجود در آن. برای توضیحات بیشتر مراجعه کنید به قسمت چهارم سری MVC.
  • #
    ‫۱۱ سال و ۳ ماه قبل، شنبه ۲۲ تیر ۱۳۹۲، ساعت ۱۵:۳۶
    آیا این امکان هست که یکی از پارامتر هارو نمایش ندیم مثلا به این صورت بشه
     url: "Details/{projectId}"
    @Html.ActionLink("detail","Details",new {issueId=10,projectId=11})
    من این تغییر رو ایجاد کردم و می‌خوام مقدار issueId  رو نمایش ندم اصلا اما url ساخته شده این شکلی میشه 
    http://localhost:2435/Home/Details?issueId=10&projectId=11 
    • #
      ‫۱۱ سال و ۳ ماه قبل، شنبه ۲۲ تیر ۱۳۹۲، ساعت ۱۶:۰۱
      در همان مثال فوق اگر projectId تقدم دارد، آن‌را ابتدا ذکر کنید (در تعریف MapRoute ایی به نام IssueDetails که پیش از مسیریابی پیش فرض ذکر شده).
      Details/{projectId}/{issueId}
      بعد امضای متد Details هم باید بر همین اساس و ترتیب تغییر کند.
      سپس اگر نمی‌خواهید یکی از پارامترها را ذکر کنید؛ پارامترهای این متد را nullable تعریف کنید. به این ترتیب با مقدار دهی null به issueId در ActionLink، خودبخود در لینک تولیدی نهایی ظاهر نخواهد شد.
      • #
        ‫۱۱ سال و ۳ ماه قبل، شنبه ۲۲ تیر ۱۳۹۲، ساعت ۱۸:۵۴
        من نیاز دارم که پارامتر هام فرستاده بشه اما url  باز نویسی بشه چیزی در حقیقت می‌خوام این هستش 
        یک url دارم به این شکل  http://mysite/Project/Detail /ProjectId ولی می‌خوام به این صورت نمایش داده بشه  http://mysite/Project/Detail /ProjectTitle   آیا راهی برای این وجود داره ؟ 
  • #
    ‫۱۰ سال و ۱۲ ماه قبل، شنبه ۶ مهر ۱۳۹۲، ساعت ۱۳:۴۶
    ممنون از مطلب عالیتون یه سوال کوچیک
    شما تو سایتتون از نوشته‌های انگلیسی برای روتینگ صفحاتتون استفاده کردید مثل
    به نظر شما اگه فارسی باشه از نطر سئو بهتره یا نه مثل این
    مقالات-جدید/https://www.dntips.ir 
    یا با این کار مشکلات دیگه ای بوجود میاد ؟
    • #
      ‫۱۰ سال و ۱۲ ماه قبل، شنبه ۶ مهر ۱۳۹۲، ساعت ۱۳:۵۷
      اکثر خزنده‌ها با آدرس‌های فارسی مشکل دارند. اگر لاگ‌های خطای سرور رو بررسی کنید عموما عاجزند از درک encoding این نوع urlها و مدام به خطای 404 برخورد می‌کنند. برای نمونه این تصویر خروجی یکی از همین خزنده‌هایی است که سایت را برای بودن آدرس یا جستجوی خاصی در سایت مدام چک می‌کند. به نظر Bing است.

      بنابراین آدرس شما باید چند قسمتی باشد؛ اگر عبارت فارسی یا یونیکد قرار است در آن درج شود. قسمت ابتدایی آن باید به نحوی انگلیسی باشد و قسمت نهایی آن فارسی و این قسمت فارسی باید در کار مسیریابی بی‌اهمیت باشد تا اگر خزنده در تفسیر آن اشتباه کرد، به خطای 404 برخورد نکند.
  • #
    ‫۱۰ سال و ۱۲ ماه قبل، شنبه ۶ مهر ۱۳۹۲، ساعت ۱۵:۳۳
    بازم یه سوال دیگه
    این صفحه‌ی اصلی یک سایته
    وقتی روتینگ انجام میدیم انگار فایل‌های جی کوئری لود نمیشه یعنی اینجوری میشه(منو‌ها کار نمیکنه)
    به نظر شما مشکل کجاست ممنون
    • #
      ‫۱۰ سال و ۱۲ ماه قبل، شنبه ۶ مهر ۱۳۹۲، ساعت ۱۵:۵۴
      - بحث مطلب جاری در مورد ASP.NET MVC است و ساز و کار استاندارد آن؛ نه در مورد وب فرم‌ها یا روش‌های سفارشی دیگر. هنگام تعریف مسیر اسکریپت‌ها در MVC اگر از Url.Content و ~ برای ذکر ریشه سایت، استفاده شده باشد، موتور توکار MVC مسیرها را به صورت خودکار اصلاح می‌کند. مثلا:
      <script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>
      - پیشتر در مورد دیباگ اسکریپت‌های یک سایت مطلبی تهیه شده بود: (^)

      الان مرورگر، مسیر اسکریپت‌های شما را از انتهای مسیر یک مطلب دریافت می‌کند نه از ریشه سایت. برای وب فرم‌ها هم روش ذیل وجود دارد:
      <script language="javascript" src='<%=ResolveUrl("~/App_Themes/MainTheme/jquery.js")%>' type='text/javascript'></script>
      البته در این حالت هدر صفحه باید runat server داشته باشد:
      <head runat="server">
      و یا از اسکریپت منیجر استفاده کنید:
      <asp:ScriptManager ID="ScriptManager1" runat="server">
              <Scripts>
                  <asp:ScriptReference Path="~/js/somefile.js" />
              </Scripts>
      </asp:ScriptManager>
  • #
    ‫۱۰ سال و ۹ ماه قبل، شنبه ۳۰ آذر ۱۳۹۲، ساعت ۰۵:۴۴
    این راه حل برای area admin جواب نمی‌دهد ,  هر کاری می‌کنم مشکل حل نمی‌شه ...

            public virtual ActionResult Manage(int ? page)
            {...}
    in Routeconfig.cs
                routes.MapRouteLowercase(
        name: "myroute",
        url: "Manage/{page}", //تطابق با یک چنین مسیرهایی
        defaults: new
        {
            controller = "Post", //کنترلری که این نوع مسیرها را پردازش خواهد کرد
            action = "Manage", // اکشن متدی که نهایتا پارامترها را دریافت می‌کند
            page = UrlParameter.Optional //این خواص نیاز است هم نام پارامترهای اکشن متد تعریف شوند
        }
    );

     

    Or in AdminAreaRegistration 
                context.MapRouteLowercase(
                    name: "myroute",
                    url: "Manage/{page}", //تطابق با یک چنین مسیرهایی
                    defaults: new
                    {
                        controller = "Post", //کنترلری که این نوع مسیرها را پردازش خواهد کرد
                        action = "Manage", // اکشن متدی که نهایتا پارامترها را دریافت می‌کند
                        page = UrlParameter.Optional //این خواص نیاز است هم نام پارامترهای اکشن متد تعریف شوند
                    }
                );


  • #
    ‫۱۰ سال و ۹ ماه قبل، شنبه ۳۰ آذر ۱۳۹۲، ساعت ۰۵:۵۸
    حل شد :
                context.MapRouteLowercase(
                    "Admin_default2",
                    "Admin/Post/Manage/{page}",
                    new { controller = "Post", action = "Manage", page = UrlParameter.Optional }
                );
    ممنون ...
  • #
    ‫۹ سال و ۱۲ ماه قبل، چهارشنبه ۱۶ مهر ۱۳۹۳، ساعت ۱۶:۲۷
    با سلام؛ میخواستم بدونم اگه آدرس فایل مثل تصویر رو هم با استفاده از این آموزش rewrite کنیم، مناسبه؟ اصلا پیشنهاد میشه یا روش مناسبی نیست، تاثیر زیادی توی سرعت میزاره؟برای اینکار پیشنهادتون چیه ؟
    ممنون