آموزش ASP.NET MVC5 – فصل۲ – بخش۲

آموزش ASP.NET MVC5 – فصل۲ – بخش۲

مشخصات مقاله

آموزش ASP.NET MVC5 – فصل۲ – بخش۲

 آموزش ASP.NET MVC5 – فصل2 – بخش2 

 

دوستان در بخش اول از جلسه دوم سری آموزشی ASP.NET MVC موارد زیر آموزش داده شد:

  • آشنایی با Razor View در ASP.NET MVC
  • خروجی ViewResult در اکشن
  • ایجاد View برای اکشن
  • تعریف متغیر در View
  • نحوه نگارش بلاک کد
  • کامنت کردن کدهای #C در Razor View
  • نمایش تصویر در ویو
  • ارسال پارامتر از Controller به View
  • متغیرهای ViewData و ViewBag

 

نحوه ارسال آبجکت به View در MVC

در این مقاله نحوه ارسال شئ به ویو (View) و پارشیال ویو (Partial-View) را خواهیم دید .

 

نحوه ارسال شئ (Object) به ویو (View):

برای اینکار ابتدا در فولدر Models کلاسی میسازیم بنام Person :

namespace Models { 
public class Person : System.Object { 
public Person() { } 
public int Age { get; set; } 
public string FullName { get; set; } 
public string Description { get; set; } 
} 
}

نکات تعریف کلاس (Class) در Model:

  • معمولا بهتر است nameSpace کلاس با نام فولدر Models یکی باشد .
  • بهتر است قید کنیم که کلاس ما از چه چیز ارث می برد مانند System.Object
  • بهتر است namespace های اضافی بالای کلاس را پاک کنیم

 

این کلاس دارای سه property است که public تعریف شده است و یک Default Constructor دارد .

اکشن Learn1160:

اکشن مربوطه بدین صورت است :

[System.Web.Mvc.HttpGet] 
public System.Web.Mvc.ViewResult Learn1160() 
{ 
 Models.Person oPerson = new Models.Person() 
 { 
  Age = 28, FullName = "Ehsan Safari", 
 }; 
 ViewBag.Person = oPerson; 
 return (View()); 
}

ایجاد شی از کلاس در اکشن:

دستورات ابتدایی این اکشن کارش اینست که از کلاس Person یک شئ میسازد و همانجا به property هایش مقدار میدهد .

ارسال آبجکت به ویو توسط ViewBag:

روش نسبتا اشتباه اینست که مانند اکشن بالا ، شئ تولید شده را بهمراه مقادیرش داخل ViewBag بریزیم و به view پاس کنیم . و در view این اکشن از ViewBag تولید شده استفاده می کنیم:

Age: @ViewBag.Person.Age
Full Name: @ViewBag.Person.FullName

یکی از ایرادات روش فوق اینست که intellisence ندارد یعنی در view با نوشتن ViewBag.Person ، لیست property ها نشان داده نمیشود . برای مثال اگر دستور فوق را بصورت ViewBag.Person.Ageee بنویسیم ، خطایی در view نمی بینیم و تنها در زمان کامپایل پروژه خطای کد فوق نمایان می شود .

ارسال شی بعنوان پارامتر view بهنگام return:

راه حل توسعه یافته روش فوق این است که شئ ساخته شده را بعنوان پارامتر View در هنگام return بفرستیم :

[System.Web.Mvc.HttpGet] 
public System.Web.Mvc.ViewResult Learn1190() 
{ 
 Models.Person oPerson = new Models.Person() 
 { 
  Age = 20, FullName = "Ehsan Safari", 
 }; 
return (View(model: oPerson)); 
}

و در View میتوان شئ ارسال شده را توسط Model بگیریم :

Age: @Model.Age 
Full Name: @Model.FullName

 

ولی مشکل روش فوق باز هم اینست که اولا intellisence ندارد دوما اگر غلط املایی در property ها داشته باشیم ارور نمیدهد و در زمان کامپایل خطا مشخص می شود .

بهترین روش ارسال آبجکت از View به Controller:

بهترین روش برای ارسال و دریافت شئ از کنترولر به ویو روش زیر است :

[System.Web.Mvc.HttpGet]
public System.Web.Mvc.ViewResult Learn1220()
{
    Models.Person oPerson =
        new Models.Person()
        {
            Age = 20,
            FullName = "Ehsan Safari",
        };
    return (View(model: oPerson));
}

و view متناظر آن :

@model Models.Person
Age: @Model.Age
Full Name: @Model.FullName

با نوشتن دستور خط اول یعنی model Models,Person  مشکل intellisence و خطا ندادن حل می شود .

 

ارسال ViewModel از کنترولر به view:

سناریو : فرض کنید می خواهیم دو موجودیت را به سمت ویو بفرستیم . مثلا یک شئ person و یک factoryName . روش اول و کلاسیک اینست که بخش مهمتر را بصورت model به view بفرستیم و بخش کوچکتر را توسط viewBag . در این مثال شئ person را توسط model و factoryName را بوسیله ViewBag یا ViewData به سمت view ارسال می کنیم . اکشن مورد نظر به این صورت می شود :

[System.Web.Mvc.HttpGet] 
public System.Web.Mvc.ViewResult Learn1230() 
{ 
 ViewBag.FactoryName = "Iran Khodro Co."; 
 Models.Person oPerson = new Models.Person() 
 { 
  Age = 28, 
  FullName = "Ehsan Safari"
 }; 
 return (View(model: oPerson)); 
}

استفاده از ViewModel برای ارسال چند شئ به View :

راه حل هوشمندانه استفاده از ViewModel است . مورد استفاده ViewModel وقتی است که می خواهیم کنار شئی که میخواهیم ارسال کنیم ، اشیاء دیگر و یا property های دیگر قرار دهیم (مانند مثال فوق) . مثال ملموس تر برای استفاده از ViewModel را میتوان در فرم ثبت نام کاربران ببینیم . در این فرم ، کاربران باید username , password , confirmPassword ,email , confirmEmail را وارد کنند . کلاس user فقط فیلدهای username , password, email  دارد . پس برای اینکه بتوان فیلدهای تایید را نیز به آن استفاده کنیم میتوان یک ViewModel ایجاد میکنیم و تمام فیلدهای confirmPassword , confirmEmail را بهمراه خود کلاس user در آن تعریف میکنیم . برای ایجاد ViewModel در پروژه خود ، باید به اینصورت عمل کنیم :

 

نحوه ایجاد ViewModel :

روی پروژه راست کلیک کرده و سپس Add–>NewFoler را انتخاب میکنیم . نام فولدر را ViewModels قرار میدهیم و روی آن راست کلیک کرده و زیر فولدری بنام کنترولر جاری (در این مثال Home) میسازیم و سپس روی فولدر Home راست کلیک کرده و Add–>Class را انتخاب کرده و بخش اول نام کلاس را همان نام اکشن و بخش دوم را به کلمه ViewModel ختم می کنیم . بعنوان مثال نام ViewModel برای ارسال در اکشن Learn1240 برابر Learn1240ViewModel.cs می باشد .

کد Learn1240ViewModel.cs:

namespace ViewModels.Home { 
 public class Learn1240ViewModel : System.Object 
 { 
  public Learn1240ViewModel() { } 
  public string FactoryName { get; set; } 
  public Models.Person Person { get; set; } 
 } 
}

اکشن Learn1240:

و در اکشن باید یک شئ از کلاس فوق بسازیم و سپس مقداردهی کنیم :

[System.Web.Mvc.HttpGet]
public System.Web.Mvc.ViewResult Learn1240()
{
    ViewModels.Home.Learn1240ViewModel oViewModel =
        new ViewModels.Home.Learn1240ViewModel();
    oViewModel.FactoryName = "Iran Khodro Co.";
    Models.Person oPerson =
        new Models.Person()
        {
            Age = 28,
            FullName = "Ehsan Safari",
        };
    oViewModel.Person = oPerson;
    return (View(model: oViewModel));
}

نحوه ارسال ویومدل از اکشن به کنترولر:

همانطور که مشاهده می کنید ابتدا باید از کلاس Person یک شئ بسازیم و مقداردهی را انجام دهیم (Age,FullName) و سپس این شئ تولید شده را به شئ ViewModel خود نسبت دهیم و در نهایت آنرا به view ارسال کنیم .

در سمت view ، ویومدل ارسالی از کنترولر را به این صورت باید بگیریم :

@model ViewModels.Home.Learn1240ViewModel

با تعریف دستور اول ، میگوییم که منظور ما از Model که داخل view استفاده شده است ، همان ViewModel است . در این حالت intellisence نیز داریم .

به منظور تکمیل آموخته های خود در زمینه ViewModel میتوانید به مرجع اصلی آموزش viewModel در mvc مراجعه کنید .

 

ارسال لیستی از اشیاء به ویو (View):

سناریو : اگر بخواهیم آرایه ای از person را به view ارسال کنیم و در view توسط یک حلقه for اطلاعات ارسالی را نمایش دهیم .

یادآوری : فرق ArrayList با Generic.List اینست که در ArrayList هنگام add کردن خانه ای به آرایه ، میتوان هر object ای را به آن افزود و از لحاظ امنیتی خطرناک است ولی Generic بدین گونه است که در هنگام ایجاد آن به صراحت میگوییم که لیست Generic ما مثلا از جنس person است .

اکشن Learn1250:

[System.Web.Mvc.HttpGet] 
public System.Web.Mvc.ViewResult Learn1250() { 
 System.Collections.Generic.List oPeople = new System.Collections.Generic.List(); 
 for (int intIndex = 1; intIndex <= 10; intIndex++) { 
  Models.Person oPerson = new Models.Person() { 
   Age = 20 + intIndex, FullName = string.Format("Full Name ({0})", intIndex), }; 
   oPeople.Add(oPerson); 
  } 
return (View(model: oPeople)); 
}

ارسال لیست افراد بصورت شئ به ویو:

در دستور اول این اکشن ابتدا لیستی از person ها ایجاد کردیم و سپس در حلقه for به تعداد 10 نفر ، اطلاعات نمونه وارد کرده ایم ( در هر بار اجرای این حلقه توسط دستور oPeople.Add اطلاعات یک نفر به لیست اضافه میشود ) در نهایت هم لیست افراد را بصورت شئ به ویو ارسال کردیم .

در سمت view نیز model بالای ویو نیز میتواند به سه صورت تعریف شود :

@model System.Collections.Generic.List 
@model System.Collections.Generic.IEnumerable @model IEnumerable

هر سه روش درست است ولی مایکروسافت روش سوم را توصیه می کند .

پس view ما بطور کلی بصورت زیر است :

@model IEnumerable
@foreach (Models.Person oPerson in Model) {
 <div style="color: blue; background-color: khaki; margin: 4px; padding: 4px; border: thin outset;">I'm @oPerson.FullName, and @oPerson.Age years old.</div>
}

توسط حلقه foreach ، روی اطلاعات افراد ارسال از کنترولر ، یک لوپ زدیم و آنها را در یک div که توسط css استایل داده شده است ، نمایش میدهیم .

لزوم تعریف Partial-View در MVC:

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

 

تعریف PartialView در MVC:

مفهوم PartialView مانند userControl در ASP.NET webform می باشد . کاربرد آن بطور مثال اینگونه است : فرض کنید میخواهیم در چند جای پروژه خود ، تاریخ شمسی را با یک استایل خاصی به کاربر نمایش دهیم . می توان یکبار آنرا در یک نوع ویو بنام PartialView تعریف کنیم و در جاهایی که میخواهیم ، آنرا فراخوانی کنیم .

 

محل ایجاد PartialView :

اگر PartialView تعریف شده بعنوان مثال فقط بدرد Home میخورد ، آنرا در فولدر Home داخل فولدر Views ایجاد میکنیم ولی اگر بدانیم ممکن است از این PartialView در کنترولرها و view های دیگر نیز استفاده شود ، باید آنرا در داخل فولدر Shared تعریف کنیم . برای ایجاد این فولدر باید روی فولدر Views راست کلیک کرده و Add–>New Folder را انتخاب کنیم . نام فولدر را نیز Shared قرار میدهیم .

 

نحوه ایجاد PartialView :

روی فولدری که میخواهیم PartialView در آن قرار بگیرد راست کلیک کرده و Add–>View را انتخاب میکنیم . در پنجره باز شده ، تیک گزینه create as a partialview  را میزنیم و add میکنیم . توصیه مایکروسافت اینست که نام PartialView ما با یک underline و سپس کلمه Partial آغاز شود .

تعریف تاریخ شمسی در PartialView:

مثالی که میخواهیم انجام دهیم تعریف تاریخ شمسی در PartialView است :

 _Partial_DisplayCurrentPersianDate :
@{
    System.DateTime dtmNow = System.DateTime.Now;
    System.Globalization.PersianCalendar oPersianCalendar =
        new System.Globalization.PersianCalendar();
    int intYear = oPersianCalendar.GetYear(dtmNow);
    int intMonth = oPersianCalendar.GetMonth(dtmNow);
    int intDay = oPersianCalendar.GetDayOfMonth(dtmNow);
}
<div dir="ltr" style="color: blue; background-color: khaki; margin: 4px; padding: 4px; border: thin outset;">@intYear / @intMonth / @intDay </div>

 

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

در view ای که قصد استفاده از این PartialView را داریم بصورت زیر عمل میکنیم :


نکته 1) : روش اول اشتباه است یعنی بعد از نام PartialView خود نباید پسوند آنرا نیز بنویسیم .

نکته 2) : همانطور که می بینید ، آدرس PartialView ذکر نشده است . پیش فرض مایکروسافت این است که ابتدا در فولدر کنترولر مربوطه واقع در فولدر view میگردد . اگر چنین PartialView ای پیدا نکرد ، سراغ فولدر Shared می رود . (بنابراین در این مثال اولویت با فولدر Home است)

نکته 3) : در ASP.NET webform هنگام استفاده از TextBox در واقع یک شئ ایجاد می کردیم از کلاس TextBox ولی در معماری MVC ، در هنگام استفاده از Textbox در واقع یک متد صدا زده می شود که دارای پارامترهای مختلفی است . در واقع یک HtmlHelper است .

نکته 4) : بصورت runTime نیز میتوان به View یک یا چند PartialView اضافه کنیم مثلا پس از بررسی دیتابیس ، اگر شرط خاصی True بود فلان Partial را نمایش دهد .

 

ارسال پارامتر به پارشیال ویو:

همانند view به partialView نیز میتوان شئ ارسال کرد (چون partialView نوعی view است) . پس در مثال بعدی میخواهیم شئ person را به partial ارسال کنیم .

اکشن مثال بعد بصورت زیر است :

[System.Web.Mvc.HttpGet] 
public System.Web.Mvc.ViewResult Learn1280() { 
 System.Collections.Generic.List oPeople = new System.Collections.Generic.List(); 
 for (int intIndex = 1; intIndex <= 10; intIndex++) { 
  Models.Person oPerson = new Models.Person() { 
   Age = 20 + intIndex, FullName = string.Format("Full Name ({0})", intIndex), }; 
   oPeople.Add(oPerson); 
 } 
 return (View(model: oPeople)); 
}

کد view مربوطه نیز بدین صورت است :

@model IEnumerable<models.person> 
<!DOCTYPE html> 
<head>
<meta name="viewport" content="width=device-width" /> 
<title>Learn 1280</title> 
</head> 
<body>     
@foreach (Models.Person oPerson in Model)     
{         
 @Html.Partial("_Partial_DisplayPerson1", model: oPerson)     
} 
</body> 
</html>

کد PartialView بصورت زیر است :

_Partial_DisplayPerson1 :
@model Models.Person
@if (Model == null)
{
    return;
}
<div dir="ltr" style="color: blue; background-color: khaki; margin: 4px; padding: 4px; border: thin outset;">I'm @Model.FullName and @Model.Age years old.</div>

 

استفاده از دستور Html.Raw:

گر فیلدی از کلاس person دارای تگ html باشد مثلا Description ، برای نمایش محتویات آن بصورت صحیح در view باید از دستور Html.Raw استفاده کنیم (یک HtmlHelper می باشد) فرض کنید اکشن ما بصورت زیر است :

[System.Web.Mvc.HttpGet] 
public System.Web.Mvc.ViewResult Learn1340() { 
 Models.Person oPerson = new Models.Person() { 
  Age = 28, 
  FullName = "Ehsan Safari", 
  Description = "Nothing!", 
 }; 
 return (View(model: oPerson)); 
}

همانطور که می بینیم فیلد Description دارای تگ <b> می باشد . پس باید در هنگام نمایش ، Render شود . بنابراین در view کد ما بصورت زیر است :

بنابراین با اجرای اکشن فوق در مرورگر ، فیلد توضیحات بصورت بولد نمایش داده می شود .

امیدوارم این مقاله مورد استفاده شما کاربران عزیز قرار گرفته باشد .

لطفا ما را از دیدگاه های خود درباره این مقاله  بی بهره نگذارید .

برای تکمیل آموزه های خود درباره PartialView به وب سایت اصلی ASP.NET MVC مراجعه کنید .

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

0/5 (0 نظر)

اطلاعات مقاله

آموزش ASP.NET MVC5 – فصل۲ – بخش۲

فرم ارسال دیدگاه درباره

آموزش ASP.NET MVC5 – فصل۲ – بخش۲

دیدگاه کاربران درباره

آموزش ASP.NET MVC5 – فصل۲ – بخش۲

دیدگاهی وجود ندارد