Model Binder سفارشی در MVC
سه شنبه 4 خرداد 1395در این مقاله قصد داریم نحوه استفاده از مدل اتصال یا Model Binder سفارشی را برای نگاشت داده ها از درخواست بر روی مدل بررسی کرده و یک نمونه Model Binder پیاده سازی کنیم.
در ASP.NET MVC مدل های خود را می توانیم با استفاده از Entity Framework ، کدهای ADO.net یا هر تکنیک دسترسی به داده دیگر ایجاد کنیم. در هنگام توسعه لایه مدل، POCO یا Plain Old CLR Objects را تعریف میکنیم. اگر از Entity Framework استفاده کنیم ، برنامه عناصر POCO را فراهم میکند که می توان از آنها به عنوان موجودیت ها استفاده کرد. کنترلر MVC متدهایی را فراهم میکند که به اشیاء POCO به عنوان پارامتر ورودی دسترسی دارند و متد action از این اشیاء CLR برای ذخیره در دیتابیس استفاده میکند. MVC با کمک POCO ، چهارچوب بندی View ها را انجام می دهد. در میان فرایند Scaffolding ، مدل اتصال یا Model binder وارد صحنه می شود. Model Binder مسئول نگاشت عناصر View به ویژگیهای مدل POCO است. Model Binder به عنوان پلی بین View و مدل های MVC عمل میکند.
MVC از انواع زیر برای مدل های اتصال استفاده میکند.
اینترفیس IModelBinder : متدهایی که برای یک مدل اتصال نیاز است تعریف میکند، مانند متد BindModel . این متد با استفاده از ControllerContext و BindingContext مسئول اتصال یک مدل به بعضی مقادیر است.
اینترفیس IModelBinderProvider : این اینترفیس شامل متدهایی است که پیاده سازی داینامیک مدل اتصال را برای کلاس هایی که اینترفیس IModelBinder را پیاده سازی میکنند فعال میکند. برای مدیریت اتصالات سفارشی برای نوع داده های ارسال شده توسط کاربر نهایی در View ها استفاده می شود.
کلاس DefaultModelBinder :
- این کلاس برای نگاشت درخواست های مرورگر برای یک داده موجودیت استفاده می شود. این کلاس یک درخواست بهم پیوسته برای IModelBinder است.
- این کلاس به صورت پیش فرض توسط MVC برای نگاشت داده های ارسال شده توسط عناصر View به ویژگیهای POCO استفاده می شود بنابراین کنترلر می تواند از آن برای پردازش های بیشتر استفاده کند.
Model Binder را می توان توسط دیاگرام زیر ارائه داد.
یک پروژه جدید در ویژوال استودیو ایجاد میکنیم . قالب آن را به صورت Empty قرار داده و گزینه MVC را انتخاب میکنیم .
یک دیتابیس با نام ApplicationDB.mdf اضافه کرده و آن را به صورت خالی رها میکنیم. در پوشه Models یک ADO.NET Entity Data Model جدید با نام ApplicationEntities اضافه میکنیم. در پنجره باز شده گزینه Code-First from database را انتخاب میکنیم.
در پنجره بعدی ApplicationDB.mdf را انتخاب میکنیم که فایل کلاس ApplicationEntities.cs را اضافه خواهد کرد. این کلاس از کلاس DbContext مشتق شده است. از این کلاس برای انجام عملیات پایگاه داده استفاده خواهیم کرد.
در پوشه Models کلاس جدیدی با نام Employee.cs به صورت زیر اضافه میکنیم.
using System.ComponentModel.DataAnnotations; namespace ModelBinder.Models { public class Employee { [Key] public int EmpNo { get; set; } [Display(Name = "نام ")] public string EmpName { get; set; } [Display(Name = "حقوق")] public decimal Salary { get; set; } } }
Employee بالا یک کلاس Entity است که EmpNo به عنوان کلید اصلی تعریف شده است.
از آنجایی که به تولید جدول از این کلاس نیاز داریم ، خط زیر را در کلاس ApplicationEntities اضافه میکنیم.
public DbSet<Employee> Employees { get; set; }
یک کنترلر با نام Employee ایجاد کرده و در آن متد زیر را اضافه میکنیم.
using System.Linq; using System.Web.Mvc; using MVC_CustomModelBinder.Models; using System.Xml.Serialization; namespace MVC_CustomModelBinder.Controllers { public class EmployeeController : Controller { ApplicationEntities ctx; public EmployeeController() { ctx = new ApplicationEntities(); } // GET: Employee public ActionResult Index() { var Emps = ctx.Employees.ToList(); return View(Emps); } public ActionResult Create() { var empPostedData = new XmlSerializer(typeof(Employee)); var Emp = (Employee)empPostedData.Deserialize(HttpContext.Request.InputStream); ctx.Employees.Add(Emp); return View("Index") ; } } }
کد بالا شیء ApplicationEntities را برای ارتباط با دیتابیس استفاده میکند.در اینجا متد Create بسیار اهمیت دارد. از یک کلاس XmlSerializer برای تعریف نوع داده XML که از طریق درخواست Post دریافت می شود استفاده شده است. از متد Deserialize() هنگامی استفاده می شود که درخواست خوانده شده و در شیء Employee ذخیره شده است که در عملیات های دیتابیس استفاده خواهد شد. با قرار دادن breakpoint بر روی این متد می توانیم آن را تست کنیم . برای تست داده ها از fiddler می توان استفاده کرد. در اینجا از Postman استفاده شده است.
ابزار fiddler را باز کرده و آدرس زیر را استفاده میکنیم.
برنامه MVC را ایجاد کنید. با فشردن دکمه Execute نتیجه اشکال زدایی یا debug به صورت زیر در شیء Emp که در کد تعریف شده است نمایش داده خواهد شد.
کد داده Employee پست شده را نمایش می دهد. متد Deserializer درخواست ها را می خواند و داده ها بر روی شیء Employee نگاشت میکند. از این می توان برای فرایندهای سمت سرور استفاده کرد. اما برای هر متد action در کنترلر باید مکانیزمی داشته باشیم که با استفاده از آن داده ها به صورت خودکار با استفاده از شیء CLR نگاشت شوند. اینجا همان جایی است که Model Binder وارد می شود. در اینجا ما به پیاده سازی زیر ساختی با استفاده از داده های XML پست شده که بر روی شیء EMployee نگاشت می شوند احتیاج داریم. می توان آن را با استفاده از یک Model Binder سفارشی انجام داد.
پوشه جدیدی با نام CustomModelBinders درون پروژه ایجاد میکنیم. در این پوشه یک کلاس با کدهای زیر اضافه میکنیم.
using System; using System.Web; using System.Web.Mvc; using System.Xml.Serialization; namespace MVC_CustomModelBinder.CustomModelBinders { public class XMLToObjectModelBinder : IModelBinder { public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { try { //1. var model = bindingContext.ModelType; //2. var data = new XmlSerializer(model); //3. var receivedStream = controllerContext.HttpContext.Request.InputStream; //4. return data.Deserialize(receivedStream); } catch (Exception ex) { bindingContext.ModelState.AddModelError("Error", "Received Model cannot be serialized"); return null; } } } public class XMLToObjectModelBinderProvider : IModelBinderProvider { public IModelBinder GetBinder(Type modelType) { //5. var receivedContentType = HttpContext.Current.Request.ContentType.ToLower(); if (receivedContentType != "text/xml") { return null; } return new XMLToObjectModelBinder(); } } }
کلاس XMLToObjectModelBinder ویژگیهای زیر را دارد.
1. این دستورات نوع Model را تحت Model Context جاری می خواند.
2. نمونه ای از XmlSerializer برای کار با داده های پست شده تعریف شده است.
3. داده دریافت شده از درخواست پست شده خوانده می شود.
4. داده های دریافت شده Deserialize می شوند.
کلاس XMLToObjectModelBindingProvider ، اینترفیس IModelBinderProvider و متد GetBinder() آن را پیاده سازی میکند. این متد نوع محتوا را از درخواست ورودی می خواند. اگر نوع محتوای دریافت شده text/xml نباشد آنگاه Null بازگردانده خواهد شد در غیر اینصورت یک نمونه از XMLToObjectModelBindiner باز گردانده خواهد شد.
کلاس فراهم کننده Model سفارشی را در برنامه اضافه خواهیم کرد بنابراین برنامه آن را در فرایند Model Binder بارگذاری خواهد کرد. Global.asax را باز کرده و خطی که با highlighte مشخص شده است را در آن اضافه میکنیم.
protected void Application_Start() { ModelBinderProviders.BinderProviders.Insert(0, new XMLToObjectModelBinderProvider()); AreaRegistration.RegisterAllAreas(); RouteConfig.RegisterRoutes(RouteTable.Routes); }
ModelBinderProviders فراهم کننده اتصال را که در مرحله قبل ایجاد کردیم در برنامه اضافه خواهد کرد.
کد متد Create را به صورت زیر تغییر می دهیم.
public ActionResult Create(Employee Emp) { ctx.Employees.Add(Emp); ctx.SaveChanges(); return View("Index") ; }
یک breakpoint بر روی متد Create قرار داده و برنامه را با استفاده از Fiddler اجرا میکنیم. داده های Employee ارسال شده به صورت زیر نمایش داده خواهند شد.
کد نشان می دهد که داخل شیء Employee CLR داده ها deserialized شده اند.
آموزش asp.net mvc
- ASP.net MVC
- 2k بازدید
- 2 تشکر