آموزش نکات کاربردی ASP.NET MVC 4 (قسمت چهارم: بخش اول helperها)

در این سلسله مقالات قصد ندارم آموزش گام به گام MVC را دنبال کنم؛ خوشبختانه منابع خوبی هم به زبان انگلیسی و حتی به زبان فارسی (مانند مقالات آقای امیر مددی در 30sharp.com یا کتاب آموزش کاربردی آموزش کاربردی ASP.NET MVC 2 از آقای مرتضی پورمحمد) وجود دارد که شما می توانید به آن ها مراجعه کنید. من می خواهم به نکات کاربردی و مفید این تکنولوژی که معمولا در طراحی سایت و پروژه ها به آن ها نیاز داریم، بپردازم. اما قبل از هرچیز یادآوری چند نکته را لازم می دانم:

نکته اول: MVC چیست؟در این مورد سخن زیاد گفته شده؛ به طور خلاصه: MVC (مخفف Model-View-Controler) الگوی نوینی از پروژه های ASP.NET است که در آن، بخش های مختلف یک اپلیکشن به خوبی و با یک استاندارد ویژه ساماندهی شده است. همچنین MVC از نسخه 3 به بعد با دستور زبان (syntax) جدید به نام Razer همراه شد که مزایای فراوانی دارد.
برای درک معماری MVC شکل ذیل را ببینید:

همان گونه که شکل می گوید: در معماری MVC کاربر آدرسی (URL) را وارد می کند؛ این تقاضا به یک متد در داخل یک کلاس کنترلر فرستاده می شود (در روش معمول، URL ها به یک فایل html, aspx, php و غیره هدایت شده و سرور آن فایل را پردازش کرده نتیجه را بر می گرداند). سپس کنترلر به کلاس های مدل مراجعه می کند؛ مدل، داده های مورد نیاز را از منبع داده خوانده و به کنترلر تحویل می دهد (یا داده ها را در منبع داده نوشته و نتیجه را بر می گرداند). آنگاه کنترلر، ویو متناسب را به کاربر برمی گرداند.

نکته دوم: آیا حتما باید MVC را انتخاب کنم؟از این سوال طبیعی نباید سرسری گذشت؛ آن گونه که مایکروسافت می گوید، MVC جایگزین ASP.NET کلاسیک نیست؛ بلکه در کنار آن به عنوان راه حل جدید مطرح است. اما کارشناسان معتقدند MVC به خاطر مزایایی (و مزه ای!!!) که دارد، عملا جایگزین آن خواهد شد.
البته در مورد مزایا و معایب MVC نیز سخن فروان است؛ به عقیده من به خاطر:
* سرعت بالاتر نسبت به ASP.NET کلاسیک و صفحات سبک تر (به خاطر حذف ViewState و دیگر بهبودها)
* ساماندهی خوب پروژه و جداسازی قسمت ها و لایه ها (که هم امکان کار گروهی را راحت می کند و هم خود شما هر وقت که لازم باشد، به آسانی بخش های مورد نظر را بازبینی و اصلاح کنید).
* تعامل و درهم آمیختن با تکنولوژی های روز (مانند HTML5, CSS3, Jqury و...)
* دستور زبان Razer که به آسانی با تگهای HTML ترکیب می شود (مشابه PHP)
* و دلایل متعدد دیگر ...
حتما باید با MVC کار کرده و کم کم ASP.NET کلاسیک را فراموش کنید. (هرچند کسانی که مزه MVC را چشیده اند عملا نسبت به آن علاقه و تعصب پیدا می کنند!!)

نکته سوم: برای کار با MVC به چه چیزهایی نیاز دارید؟ابتدا باید نسخه 4 ام وی سی را از آدرس زیر دانلود کرده و نصب کنید
http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=27419
طبیعی است که باید Vusual Studio 2010 sp1 یا Visual Studio 11 (نسخه کامل یا Exprees) که به تازگی انتشار یافته است را نصب کرده باشید.
راه دیگر استفاده از WebMatrix است که از سایت asp.net می توانید این پلاتفرم کارا و سبک را به راحتی دانلود کنید. خوشبختانه نسخه 2 این نرم افزار که به تازگی منتشر شده، از Intellecence هم پشتیبانی می کند؛ شکل ذیل را ببینید:

به هر حال، من از نسخه Visual Studio 2010 Express sp1 استفاده می کنم.

نکته چهارم: مروری بر یک پروژه MVC1- ویژوال استودیو را اجرا کرده و یک پروژه جدید از نوع ASP.NET MVC 4 Web Application مانند شکل ذیل انتخاب کرده و نامی دلخواه برای آن انتخاب کنید (شکل ذیل).

2- پس از کلیک بر روی دکمه OK پنجره ذیل را می بینید:

در این شکل چند نکته قابل توجه است: اول این که یک الگوی جدید به نام Mobile Application را مشاهده می کنید که شامل الگویی کم حجم و سازگار با مرورگرهای همراه می باشد (از جمله کتابخانه جدید Jquery Mobile). دوم اینکه باید View engine خود را انتخاب کنید که می تواند Razer یا ASPX باشد. همچنین HTML 5 به صورت پیش فرض انتخاب شده است. با کلیک بر روی دکمه OK ویژوال استودیو پروژه را ایجاد می کند. (شکل ذیل)

همان گونه که در شکل مشاهده می کنید، در یک پروژه MVC علاوه بر پوشه های معمول ASP.NET (مانند Properties, References, App_Data) شامل پوشه های ذیل است:
Content: در این پوشه محتویات غیر دینامیک مورد استفاده در سایت مانند استایل ها، تم ها و... نگهداری می شود.
Controllers: در این پوشه کلاس هایی قرار می گیرد که وظیفه مدیریت برنامه را به عهده می گیرد؛ بدین معنی که در هر کلاس متد یا متدهایی نوشته می شود که به کاربر پاسخ داده، داده ها را از Model می گیرد و View مناسب را به کاربر تحویل می دهد.
Image: برای تصاویر مورد استفاده در اپلیکیشن.
Model: شامل کلاس هایی برای کار با داده ها.
Scripts: شامل فایل های JavaScript که به طور پیش فرض کتابخانه Jquery، Modernizer (پلتفرمی برای مرورگرهایی که از HTML 5 و CSS 3 پشتیبانی نمی کنند) و... می باشد.
Views: شامل نماها که فایل هایی با پسوند cshtml (یا vbhtml) بوده و بخش رابط کاربری (UI) اپلیکیشن را می سازد. برای ساماندهی بهتر نماها، برای هر کلاس به طور معمول یک پوشه جداگانه ایجاد می کنیم. همچنین در این پوشه یک پوشه به نام Shared وجود دارد که شامل اجزای مشترک رابط کاربری مانند Layout (که در ASP.NET کلاسیک MasterPage نامیده می شد).
توجه داشته باشید که یک فایل Web.config در این پوشه نیز وجود دارد که برای تنظیمات نماها و جلوگیری از پردازش فایل های این پوشه توسط IIS است (نماها به طور مستقیم توسط کاربر مورد دسترسی قرار نمی گیرد؛ بلکه توسط کنترلرها پردازش می شود).
اکنون در فایل HomeController.cs (که به طور پیش فرض باز است)، پیامی را همانند ذیل نوشته و برنامه را تست کنید:
public ActionResult Index()
    {
      ViewBag.Message = "This is my first MVC 4 test!";
      return View();
    }

همان گونه که در شکل نیز مشخص است، قالب پیش فرض صفحه در MVC 4 با MVC 3 متفاوت است؛ در این قالب بهبودهایی در THML و CSS افزوده شده و همچنین لینک های Register و Login در صفحات جداگانه باز نمی شود؛ بلکه به صورت یک پنجره Modal نمایان می شود.

در این قسمت به معرفی اجمالی MVC پرداختیم. از قسمت بعدی می خواهیم یک پروژه عملی را برنامه نویسی کنیم تا در خلال آن تمام نکات مورد نیاز برای کار با MVC را فراگیریم. انشاء الله

منبع : http://www.fekrenaw.com


آموزش نکات کاربردی ASP.NET MVC 4 (قسمت سوم)

قبل از ادامه مباحث، از آن جا که صفحات (به تعبیر دقیق تر: Viewها) را با دستور زبان Razer می نویسیم، لازم است نگاهی به آن داشته باشیم. MVC از نسخه 3 به بعد با Razer همراه شد.
دستوراتی که با Razer می نویسیم در فایل هایی با پسوند .cshtml یا .vbhtml ذخیره شده و در واقع همان کدهای سمت سرور است که در شکلی جدید با تگ های HTML ترکیب شده است. اکنون کافی است بجای این که کدهای سمت سرور خود را در بین <%= %> بنویسیم، قبل از آن ها علامت@ بگذاریم.
به طور مثال:

<span>ToDay is: @DateTime.Nowspan>
برای نمونه، دو نمونه Razer و ASP.NET کلاسیک را مقایسه کنید:
ASP.NET:
<% foreach(var item in items) { %>
    <li>Item is: <% item %>.li>
<% } %>

RAZER:
@ foreach(var item in items) { 
    <li>Item is: @ item.li>
 } 
همان گونه که مشاهده می کنید، کدهای Razer بسیار خواناتر و راحت تر است.
شما نباید نگران یادگیری Razer باشید؛ چرا که Razer چیزی جدید نیست و نباید ذهن خود را به آن مشغول کنید! کافی است قبل از کدهای c# یا vb خود از علامت @ استفاده کنید! به همین راحتی.
در این جا برخی از نکات در مورد به کارگیری Razer را مرور می کنیم:
* قبل از کدهای Inline خود علامت @ می گذاریم:
<p>Date is: @DateTime.Now.Datep>
* اگر خود @ را لازم داشته باشید، از دو علامت @@ استفاده می کنیم:
My email is: asif1358@@gmail.com
* دستورات چند سطری را میان @{...} قرار می دهیم:
@{
   var name = " Ali ";
   if(name == "Ali "){
   <p>Hello @name ¡p>
   } else {
   <p>Who is @name ?!!!p>
  }
}
* اگر بخواهیم متن خالص در میان کدهای خود داشته باشیم، قبل از آن، @: قرار داده یا آن را میان تگ ... قرار می دهیم:
@if (showMessage) {
  <text>This is plain texttext>
}

// or:
@if (showMessage) {
  @:This is plain text.
}
* حلقه ها و بلوک های کد نیز به سادگی همانند ذیل می توانند به کار روند:
@{
  <h3>Students:h3> 
  string[] students = {"Ali", "Mohammad", "Mehdi", "Hasan"};
  foreach (var student in students)
  {
    <p>@studentp>
  }
}
* توضیحات در بین @*....*@ قرار می گیرد؛ البته همچنان از // و /*...*/ هم می توانید استفاده کنید:
@{
@*
  A Razor Comment
*@
  //A C# comment
  /* 
    A Multi
     line C# comment
  */
}
* Razer همانند PHP به سادگی با HTML درهم می آمیزد؛ هرجایی که لازم باشد آن را بگذارید:
<a href="Topics/@topicID">...a>
* در قسمت قبلی مشاهده کردید، Master page (که Layout نامیده می شود) با صفحه معمولی چگونه به کار می رود؛ همچنین بد نیست بدانید که در هر قسمت از صفحه که لازم باشد، می توانید از یک
استفاده کنید. بدین صورت که در View خود یک section ایجاد کرده و کدهای خود (کدهای HTML یا سمت سرور( را داخل آن بنویسید:
@section MySectionName {
   <h1>Welcom!h1>
  <img src= ................ />
}
آنگاه در داخل مسترپیج، آن section را در محل مورد نظر بگنجانید:
<div class="test">
   @RenderSection("MySectionName")
div>
شکل ذیل چگونگی به کارگیری section را توضیح می دهد:

همچنین می توانید در داخل یک بلوک if بررسی کنید که آیا چنین section وجود دارد یا خیر:
<footer>
  @if (IsSectionDefined("Footer")) {
    RenderSection("Footer");
  }
  else { 
    <span>This is the default footer.span>   
  }
footer>
تا اینجا آشنایی اجمالی با Razer پیدا کردید؛ در خلال کار، به نکات بیشتر پی خواهید برد؛ اجازه دهید اکنون پروژه خود را تکمیل کنیم:

ادامه پروژهیکی از امکانات بسیار خوب ویژوال استودیو برای پروژه های MVC بهره گیری از scaffolding است که به طور خودکار Viewهای مربوط به نمایش، ایجاد، حذف و ویرایش یک مدل (که معمولا یک جدول بانک اطلاعات است) را ایجاد می کند. این امکان به برنامه نویس اجازه می دهد بدون زحمت کد نویسی، به راحتی با چند کلیک، چندین صفحه از سایت خود را ایجاد کند.
قبل از پی گیری ادامه بحث، خوب است لیبل های فیلدها را برای نمایش صحیح تر اصلاح کنیم (در قسمت قبل در مورد DataAnnotations توضیح دادیم). بدین شکل که قبل از نام فیلد از برچسب [Display(Name=...)] استفاده می کنیم:
[Display(Name = "First and Last name")]
public string FullName { get; set; }
بنا بر این شما می توانید کلاس مربوط به Team را این گونه اصلاح کنید:
public class Team
  {
    [Key]
    public int TeamID { get; set; }

    [Display(Name = "نام تیم")]
    [Required(ErrorMessage = "نام تیم الزامی است")]
    public string TeamName { get; set; }

    [Display(Name = "تاریخ ثبت")]
    [DataType(DataType.Date)]
    public DateTime RegisterDate { get; set; }

    public virtual ICollection Player { get; set; }
  }
به همین ترتیب می توانید کلاس Player را اصلاح کنید.
اکنون بر روی پوشه Controllers کلیک راست کرده و گزینه Add> Contoller... را انتخاب کنید. در پنجره Add Controller، نام آن را TeamController گذاشته و از قسمت Template گزینه Controller with read/write.... را انتخاب کرده و از لیست Model class کلاس Team را برگزیده و بالاخره از قسمت Data context class کلاس PremierLeagDB را انتخاب کنید (شکل ذیل)

بر روی دکمه Add کلیک کنید؛ مشاهده می کنید که علاوه بر ایجاد یک کلاس کنترلر در پوشه Controllers، در پوشه Views یک پوشه به نام Team با چهار View برای ایجاد، نمایش، حذف و ویرایش Teamها ایجاد شده است؛ در واقع به جز فارسی سازی (یکی دو اصلاح کوچک) نیاز به هیچ چیز دیگری نیست؛ صفحات و کدها به طور خود کار اضافه شده اند. 

اکنون پروژه خود را تست کنید؛ به قسمت تیم ها رفته و با کلیک بر روی لینک Create New تیم ها را وارد کنید:

همان گونه که مشاهده می کنید، هم برچسب فیلدها فارسی شده است و هم اعتبارسنجی ها انجام می شود. همچنین با کلیک بر روی لینک های Delete و Edit می توان به حذف و ویرایش تیم پرداخت یا جزئیات یک تیم را با لینک Details مشاهده نمود.
اکنون نگاهی به کلاس TeamController بیاندازید؛ در این کلاس چندین متد برای نمایش و کار با داده ها (کلاس های مدل) ایجاد شده است. به طور نموده متد Index() را در نظر بگیرید:
public ViewResult Index()
{
   return View(db.Teams.ToList());
}
این متد یک View به نام Index بر می گرداند؛ پارامتر این متد، تمام عناصر کلاس Teams از DbContextی که قبلا نوشته بودیم و به لیست تبدیل شده است می باشد. اگر به نمای Index (داخل پوشه Team) نگاه کنید، مشاهده می کنید که در آغاز یک نمونه از آن کلاس (مدل) اعلان شده است:
@model IEnumerable<PremierLeague.Models.Team>
در قسمت HTML هم پس از ایجاد یک table، سطرهای مربوطه توسط یک حلقه foreach افزوده می شود:
@foreach (var item in Model) {
  <tr>
    <td>
      @Html.DisplayFor(modelItem => item.TeamName)
    td>
    <td>
      @Html.DisplayFor(modelItem => item.RegisterDate)
    td>
    <td>
      @Html.ActionLink("Edit", "Edit", new { id=item.TeamID }) |
      @Html.ActionLink("Details", "Details", new { id=item.TeamID }) |
      @Html.ActionLink("Delete", "Delete", new { id=item.TeamID })
    td>
  tr>
}
توجه داشته باشید که در کلاس TeamController دو متد Create()، Edit() و Delete() وجود دارد؛ متد اول خاصیت Get داشته و در واقع کاربر را به صفحه که برای آن عملیات در نظر گرفته شده، هدایت می کند؛ در حقیقت این متد دوم است که اصل عملیات ایجاد، حذف و ویرایش را انجام می دهد.
تمام این متدها کامل اند؛ اما ممکن است بخواهید کد درون آن ها را در داخل بلوک try...catch قرار دهید:
[HttpPost, ActionName("Delete")]
public ActionResult Delete(int id) { 
     try { 
        Team team = db.Teams.Find(id);
        db.Teams.Remove(team);
        db.SaveChanges();
        return RedirectToAction("Index");
   } catch { 
        return View(); 
   } 
}
به همین روش شما باید کنترلر و نماها (View)های مربوط به کلاس Player را نیز ایجاد کنید.
نکته جالب توجه این است که در صفحه ایجاد و ویرایش بازیکن، فیلد TeamID که کلید خارجی است، با یک لیست افتادنی نمایش داده می شود که شما می توانید نام تیم را انتخاب کنید (شکل ذیل)

همین طور اگر در نمای مربوطه، کد Razer را مشاهده کنید، مشابه ذیل خواهد بود:
<div class="editor-label">
   @Html.LabelFor(model => model.TeamID, "Team")
div>
<div class="editor-field">
   @Html.DropDownList("TeamID", String.Empty)
   @Html.ValidationMessageFor(model => model.TeamID)
div>
اکنون مقداری اطلاعات در جدول های Team و Player وارد کنید (داده هایی که ما وارد کرده ایم فقط به عنوان مثال است؛ صحت آن را هیچ بنی بشری تایید نمی کند!!! ضمنا من ابتدا نام ها را به صورت انگلیسی وارد کردم، بعد دیدم بهتر است فارسی کنم. به همین جهت در شکل های قبلی و بعدی ممکن است تفاوت ببینید).

نمایش فیلدها از جدول های مرتبطدر MVC و Entity framework اگر بخواهیم فیلدهای مورد نظر خود را از چند جدول بگیریم، بهتر است ابتدا یک کلاس Entity که حاوی فیلدهای مورد نظر است، ایجاد کنیم؛ سپس با join (و مانند آن) داده ها را در آن قرار داده و نمایش دهیم.
به طور مثال فرض کنید شما سه جدول ذیل را دارید:

در این موارد بهتر است یک کلاس دیگر شامل فیلدهای منتخب سه جدول ایجاد کنید؛ به طور مثال:

حال می توانید در یک کوئری، داده ها را در آن بارگزاری کرده و یا جستجو و فیلتر را انجام دهید؛ به طور مثال:
public ActionResult Index()
{
     try
     {
        var topics = from t in db.Topics
               join s in db.Subjects on t.SubjectID equals s.SubjectID
               join m in db.Members on t.MemberID equals m.MemberID
               select new TopicView
               {
                   ViewID = t.TopicID,
                   SubjectName = s.SubjectName,
                   FLName = m.FLName,
                   Title = t.Title,
                   // Other fields .........
               };
        return View(topics);
      }
    catch (Exception ex)
     {
      return View("Error");
     }
}
بر همین اساس ما می خواهیم لیستی از بازیکنان و تیم مربوط به هر بازیکن را در صفحه اول پروژه خود نمایش داده و امکان جستجو به کاربر بدهیم. پس قبل از هر چیز کلاس ذیل را به مدل خود (PremierLeagueDB.cs) اضافه می کنیم:
public class PlayerView
{
  [Key]
  public int PlayerID { get; set; }
  public string TeamName { get; set; }
  public string FullName { get; set; }
  public int Age { get; set; }
  public DateTime EnrollDate { get; set; }
}
پروژه را Build کرده و مراحل ذیل را انجام دهید: کلاس HomeConroller.cs را باز کرده و فضانام مدل را وارد کنید:
using PremierLeague.Models;
در داخل کلاس یک نمونه از DbContext ایجاد کنید:
PremierLeagueDB db = new PremierLeagueDB();
اکنون متد Index() را این گونه اصلاح کنید:
public ActionResult Index()
{
   var players = from p in db.Players
          join t in db.Teams on p.TeamID equals t.TeamID
          orderby p.PlyerID descending
          select new PlayerView
          {
              PlayerID = p.PlyerID,
              FullName = p.FullName,
              TeamName = t.TeamName,
              Age = p.Age,
              EnrollDate = p.EnrollDate
           };
    return View(players.ToList());
 }
اکنون ابتدا فایل Index.cshtml از پوشه Views>Home را حذف کرده سپس بر روی متد بالا کلیک راست کرده و گزینه Add View... را انتخاب کنید؛ در پنجره Add View از لیست Model class کلاس PlayerView را انتخاب کرده و از قسمت scaffold template گزینه لیست را انتخاب کنید (شکل ذیل)

بر روی دکمه Add کلیک کنید تا نمای Index شامل کدهای مورد نظر (مطابق داده های کلاس PlayerView) ایجاد شود. اکنون اگر پروژه را تست کنید، شکلی مشابه ذیل را خواهید دید (البته من لینک های ویرایش را حذف کرده ام):

افزودن جستجوبدون شک در پروژه های واقعی، نیاز به جستجو در میان داده ها وجود دارد؛ در این ما یک مثال ساده از نحوه به کارگیری آن را در MVC ارائه می کنیم.
بدین منظور ابتدا کد ذیل را قبل از تگ table در نمای Index اضافه کنید:
@using (Html.BeginForm("Index", "Home"))
{ 
  <p>نام بازیکن: @Html.TextBox("name") 
  <input type="submit" value="جستجو" />p> 
}
اکنون در HomeController.cs روایت دیگر از متد Index را (پس از PostBack) این گونه اضافه کنید:
[HttpPost]
public ActionResult Index(string name)
{
     var players = from p in db.Players
           join t in db.Teams on p.TeamID equals t.TeamID
           where p.FullName.Contains(name)
           select new PlayerView
           {
            PlayerID = p.PlyerID,
            FullName = p.FullName,
            TeamName = t.TeamName,
            Age = p.Age,
            EnrollDate = p.EnrollDate
           };
     return View(players.ToList());
}
اکنون می توانید بر اساس نام بازیکن، جستجو انجام دهید (شکل ذیل):


آنچه تا این جا انجام دادیم، مراحل کامل یک پروژه کوچک بود. در بخش های بعدی به مطالب پیشرفته تر مانند نحوه استفاده از ادیتور، ویژگی Display mode برای تنظیم دینامیک صفحه برای مروگرهای معمولی و دستگاه های همراه (که از ویژگی های جدید MVC 4 است)، آژاکس در MVC، استفاده از کتابخانه Microsoft.Web.Helpers (که کار با آپلود فایل، تصاویر، ارسال ایمیل و... ساده می کند) و موارد دیگر را خواهیم آموخت. انشاء الله..

منبع : http://www.fekrenaw.com

.