نحوه سفارشی سازی Model Binding در MVC
شنبه 16 مرداد 1395دراین مقاله ما با نحوه ی عملکرد Model Binding آشنا خواهید شد و همچنین در این مقاله یاد خواهید گرفت که چگونه Model Binding را سفارشی سازی کنید.
Model Binding یکی از بهترین ویژگی ها در فریم ورک ASP.NET MVC می باشد. ModelBinder درخواست های http را از view data به model مسیریابی می کند. MVC در حال اجرا از ModelBinder پیش فرض ،برای ساخت پارامترهای model استفاده می کند.این کار به صورت خودکار توسط Model Binder مربوط بهMVC ، انجام می شود.
به ما اجازه دهید تا با یک مثال ساده ، ببینیم که چگونه اطلاعات model به Controller توسط model binding از view در mvc ، پاس داده شده است.
ابتدا action ساده ی زیر را ببینید.
1. public ActionResult Index() 2. { 3. return View(); 4. }
ما یک model به نام StudentViewModel به شکل زیر داریم.
public class StudentViewModel { [DisplayName("شماره دانشجویی")] public int StudenId { get; set; } [DisplayName("نام")] public string Name { get; set; } [DisplayName("آدرس")] public string Address { get; set; } [DisplayName("شهر ")] public string City { get; set; } [DisplayName("ایالت")] public string State { get; set; } [DisplayName("کشور")] public string Country { get; set; } [DisplayName("گروه")] public string Department { get; set; } [DisplayName("نمره")] public int Marks { get; set; } }
در View های index برای ما view مربوط به Index را برمی گرداند، و ما Index.cshtmlرا مانند زیر داریم.
@model ModelBinding1.Models.StudentViewModel <div dir="rtl"> @{ ViewBag.Title = "Index "; } <h2>صفحه ی اصلی</h2> @using (Html.BeginForm()) { @Html.EditorForModel("StudentViewModel") <input type="submit" value="ذخیره" /> } @section Scripts { @Scripts.Render("~/bundles/jqueryval") } </div>
ما یک دکمه ی submit داریم ، و زمانی که ما بر روی دکمه ی submit کلیک کنیم، action ی به نام Index را فراخوانی میکنیم .زمانی که ما Viewی Index را اجرا می کنیم ، صفحه ی زیر را خواهیم دید.
ما می توانیم داده ها را از راه های مختلفی پاس دهیم ، تعدادی از این راه ها در زیر آمده است.
راه 1: از طریق Collection
1. [HttpPost] 2. public ActionResult Index(FormCollection frm) 3. { 4. Var StudentId= studentformcollection["StudentId"].ToString(); 5. var studentName = studentformcollection["Name"].ToString(); 6. var studentAddress = studentformcollection["Address"].ToString(); 7. 8. var studentCity = studentformcollection["City"].ToString(); 9. var studentState = studentformcollection["State"].ToString(); 10. 11. var studentCountry = studentformcollection["Country"].ToString(); 12. var studentDepartment = studentformcollection["Department"].ToString(); 13. 14. var studentMarks = studentformcollection["Marks"].ToString(); 15. return View(); 16. }
ما همچنین می توانیم model را به جای استفاده از FormCollection ، به صورت مستقیم پاس دهیم.
راه 2: از طریق QueryString
راه دیگری که برای گرفتن داده وجود دارد ، استفاده از Request.querystring می باشد که مانند زیر از نسخه های قبلی asp.net می باشد.
var studentName = Request.QueryString["Name"].ToString();
راه3 : دادن پارامتر به صورت مستقیم
همچنین ما می توانیم به وسیله گرفتن پارامتر به صورت مستقیم، پاس بدهیم.
[HttpPost] public ActionResult Index(int StudentId, string Name, string Address, string City, string State,string Country, string Department, int Marks) { return View();
در فریم ورک MVC ، به صورت معمول ، model شامل همه ی فیلدهایی است که با viewها مطابقت داشته باشند.گاهی اوقات در برنامه، property مربوط به کلاس ViewModel یا Propperty کلاس Entity یا فیلد دیتابیس ، به درستی در هر صفحهی UI ، نگاشته نمی شوند.می خواهیم فیلد آدرس را در دیتابیس در یک فیلد Single ، بررسی کنیم اما در صفحه ی UI ، ترکیبی از سه فیلد می باشد : شماره پلاک ، شماره خیابان ، نام محل
فیلد Name در دیتابیس ، یک فیلد Single می باشد اما در صفحه UI سه تا فیلد وجود دارد نام ، نام دوم ، نام خوانوادگی.
برخی از شما ممکن است این طور فکر کنید که برای الحاق فیلد ها در کنترلرلازم است آن ها را به یک model property و entity class property متصل کنید تا دقیقا با پایگاه داده مطابقت داشته باشند. انجام این کار ، راه مناسبی نمی باشد.MVC دارای binding model سفارشی سازی شده می باشد.که ما یک بار تعریف می کنیم ، و این منطق ، در هرجایی که ما می خواهیم برای اشاره به Model، اعمال خواهد شد.
اگر ما در بخش های زیادی نیاز داشته باشیم تا ازاین روش استفاده کنیم باید از ویژگی ای در MVC به نام Custom Model Binding استفاده کنیم. این ویژگی کار را برای ما آسان تر می کند.
به ما اجازه دهید تا یک مثال ساده را بررسی کنیم.
ما فیلدهای UI و کلاس ViewModel داریم که دارای نگاشت های مختلف می باشد اما ما باید آن را با استفاده از Model binding سفارشی سازی شده ، نگاشت کنیم و آن را در دیتابیس با استفاده از entity framework ذخیره کنیم.
به ما اجازه دهید یک دیتابیس به نام student و یک جدول به نام studentInfo ایجاد کنیم .
Query برای ایجاد یک جدول
SQL Query برای ایجاد یک جدول
1. USE [Student] 2. GO 3. 4. 5. SET ANSI_NULLS ON 6. GO 7. 8. SET QUOTED_IDENTIFIER ON 9. GO 10. 11. CREATE TABLE [dbo].[StudentInfo]( 12. [StudentId] [int] NOT NULL, 13. [Name] [nvarchar](50) NULL, 14. [Address] [nvarchar](50) NULL, 15. [City] [nvarchar](50) NULL, 16. [State] [nvarchar](50) NULL, 17. [Country] [nchar](10) NULL, 18. [Department] [nchar](10) NULL, 19. [Marks] [int] NULL, 20. CONSTRAINT [PK_StudentInfo] PRIMARY KEY CLUSTERED 21. ( 22. [StudentId] ASC 23. )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 24. ) ON [PRIMARY] 25. 26. GO
ما یک Stored Procedure برای قرار دادن اطلاعات دانش آموزان ایجاد کرده ایم.
1. USE [Student] 2. GO 3. /****** Object: StoredProcedure [dbo].[InsertStudentInfo] Script Date: 6/24/2016 10:40:58 AM ******/ 4. SET ANSI_NULLS ON 5. GO 6. SET QUOTED_IDENTIFIER ON 7. GO 8. 9. CREATE PROCEDURE [dbo].[InsertStudentInfo] 10. @StudentId [int], 11. @Name [nvarchar](50), 12. @Address [nvarchar](50), 13. @City [nvarchar](50), 14. @State [nvarchar](50), 15. @Country [nchar](10), 16. @Department [nchar](10), 17. @Marks [int] 18. AS 19. BEGIN 20. 21. SET NOCOUNT ON; 22. 23. INSERT INTO dbo.StudentInfo(StudentId, Name,Address,City,State,Country,Department,Marks ) 24. VALUES(@StudentId, @Name,@Address,@City,@State,@Country,@Department,@Marks) 25. 26. END
حال stored procedure ما آماده است و از این Stored Procedure برای قرار دادن رکوردها با استفاده از entity framework ، استفاده می کنیم.
حال ما یک ASP.NET MVC Web Application ساده ایجاد می کنیم.به Visual Studio بروید و یک پروژه جدید ایجاد کنید.
در مرحله ی بعدی MVC را انتخاب کنید و روی دکمه ی OK کلیک کنید.
حال ما یک Item جدید برای آوردن داده با استفاده از entity framework ایجاد می کنیم.
به قسمت Project بروید و Add new Item را می زنیم.
ADO.NET Entity Data Model را انتخاب کنید و روی ADD کلیک کنید.در مرحله ی بعدی صفحه ی زیر را می بینیم.
Generate را انتخاب کنید و سپس روی Next کلیک کنید.
در این مرحله نام دیتابیس سرور خودتان ونام دیتابیس در این wizard را انتخاب کنید .
در اینجا در این مرحله گزینه ی Stored Procedure را انتخاب کنید و “InsertStudentInfo” را که ما برای قرار دادن در دیتابیس ایجاد کرده ایم ، انتخاب کنید.سپس روی Next کلیک کنید.
روی Next کلیک کنید تا به مرحله ی بعدی بروید.
حال ، ما خواهیم دید که StudentEntities برای ما ایجاد شده است .در مرحله ی بعد روی Finish کلیک کنید.حال ما model ایجاد خواهیم کرد .به پوشه Model بروید و یک Model جدید به نام StudentViewModel مانند زیر ،ایجاد کنید.
1. using System; 2. using System.Collections.Generic; 3. using System.ComponentModel.DataAnnotations; 4. using System.Linq; 5. using System.Web; 6. 7. namespace CustomModelBinding.Models 8. { 9. public class StudentViewModel 10. { 11. 12. public int StudentId { get; set; } 13. public string Name { get; set; } 14. public string Address { get; set; } 15. 16. public string City { get; set; } 17. public string State { get; set; } 18. 19. 20. public string Country { get; set; } 21. public string Department { get; set; } 22. 23. public int Marks { get; set; } 24. } 25. }
برای ایجاد کردن model Binding سفارشی سازی شده ما باید یک کلاس که از DefaultModelBinder ارث بری کرده است و متد BindModel() را که در آنoverride شده است ،بنویسیم. متد BindModel() از کلاس ، دوتا پارامتر ControllerContext و ModelBindingContext را می گیرد ، که ControllerContext اطلاعات درخواست را که از view پاس داده شده، نگهداری می کند.ما اطلاعات درخواست را از request query string میگیریم ، آن را به هم پیوسته می کند و به Model ما اختصاص می دهد مانند زیر:
1. public class StudentModelBinder : DefaultModelBinder 2. { 3. 4. public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 5. { 6. if (bindingContext.ModelType == typeof(StudentUIModel)) 7. { 8. HttpRequestBase request = controllerContext.HttpContext.Request; 9. 10. int frmStudentId = Convert.ToInt32(request.Form.Get("StudentId").ToString()); 11. string frmAddress = request.Form.Get("Address"); 12. string frmCity = request.Form.Get("City"); 13. string frmState = request.Form.Get("State"); 14. 15. string frmFName = request.Form.Get("FName"); 16. string frmMName = request.Form.Get("MName"); 17. string frmLName = request.Form.Get("LName"); 18. 19. string frmDoorNo = request.Form.Get("DoorNo"); 20. string frmStreetNo = request.Form.Get("StreetNo"); 21. string frmAreaName = request.Form.Get("AreaName"); 22. 23. string frmCountry = request.Form.Get("Country"); 24. int frmMarks = Convert.ToInt32(request.Form.Get("Marks").ToString()); 25. 26. return new StudentUIModel 27. { 28. StudentId = frmStudentId, 29. Address = frmDoorNo + " " + frmStreetNo + " " + frmAreaName, 30. 31. City = frmCity, 32. State = frmState, 33. Name = frmFName + " " + frmMName + " " + frmLName, 34. Country=frmCountry, 35. Marks= frmMarks 36. }; 37. 38. 39. } 40. else 41. { 42. return base.BindModel(controllerContext, bindingContext); 43. } 44. } 45. 46. }
ما این کلاس را برای global.asax.cs مانند زیر ، برای پاسخ به این model binding در هرجای برنامه ، ثبت می کنیم.
1. public class MvcApplication : System.Web.HttpApplication 2. { 3. protected void Application_Start() 4. { 5. AreaRegistration.RegisterAllAreas(); 6. FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 7. RouteConfig.RegisterRoutes(RouteTable.Routes); 8. BundleConfig.RegisterBundles(BundleTable.Bundles); 9. ModelBinders.Binders.Add(typeof(StudentUIModel), new StudentModelBinder()); 10. } 11. }
به ما اجازه دهید به Controller برویم و این model Binding را که از Controller به نام Action فراخوانی شده است ، را بگیریم.
ابتدا ، زمانی که صفحه لود شده است ما action به نام Index را فراخوانی می کنیم.
1. public ActionResult Index() 2. 3. { 4. 5. return View(new StudentUIModel()); 6. 7. }
زمانی که action به نام Index اجرا شد view به نام Index به صورت زیر render می شود.
زمانی که ما اطلاعات را پر می کنیم و داده را ارسال می کنیم ، در Home Controller ما action به نام StudentInformation داریم و زمانی که view پست شد ،درخواست را می گیرد .
actionبه نام StudentInformation ، Model را به ModelBinder پاس می دهد که ModelBinding را سفارشی سازی می کند.
1. [HttpPost] 2. public ActionResult StudentInformation([ModelBinder(typeof(StudentModelBinder))] StudentUIModel studentmodel) 3. { 4. 5. try 6. { 7. var name = studentmodel.Name; 8. 9. StudentEntities s = new StudentEntities(); 10. s.InsertStudentInfo(studentmodel.StudentId, studentmodel.Name, studentmodel.Address, 11. studentmodel.City, studentmodel.State, studentmodel.Country, studentmodel.Department, studentmodel.Marks); 12. 13. ViewBag.InsertMessage = " اطلاعات وارد شده با موفقیت ذخیره شده است"; 14. } 15. catch(Exception ex) 16. { 17. 18. } 19. 20. return View("Index"); 21. 22. }
حال متد ()InsertStudentInfo را فراخوانی کنید از StudentEntities که داده را در جدول StudentInfo با استفاده از Stored Procedure خودمان ، وارد می کند.
ما میبینیم که رکورد ما در دیتابیس قرار گرفته است .به فیلدهای Name و Address نگاه کنید. که شامل همه ی داده هایی می باشد که به وسیله model Binder اضافه کرده ایم.
در برخی موارد ما می خواهیم فیلدهای متفاوتی را برای وارد کردن روز، ماه ، سال و زمان در نظر بگیریم در حالی که در پایگاه داده فقط یک فیلد برای ذخیره این مقادیر وجود دارد. در برخی موارد نیز ما می خواهیم متنی را قبل از قرار دادن فیلد ها در پایگاه داده به فیلد جاری اضافه کنیم .
آموزش asp.net mvc
- ASP.net MVC
- 1k بازدید
- 3 تشکر