Model Binder در MVC

پنجشنبه 3 دی 1394

همانطور که می دانید زمانی که یک درخواست مرورگر، برای شیئ کلاس ایجاد می کنیم و نام Property های کلاس مشابه نام کنترل HTML ای باشد داده به صورت اتوماتیک به Property های کلاس map می شود، این نوع mapping را Model Binder می گویند. در این مقاله می خواهیم مفهوم Model Binder را در MVC مورد بررسی قرار دهیم. همچنین یک Model binding را پیاده سازی می کنیم تا مزایای آن را ببینید.

Model Binder در MVC

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

کلاسی با نام Customer به همراه Property ها

public class Customer   
{  
  
    public string Code  
    {  
        get;  
        set;  
    }  
  
    public string Name  
    {  
        get;  
        set;  
    }  
}

 

سپس یک صفحه HTML به صورت زیر طراحی می کنیم که شامل فرمی است که اطلاعات را به کلاس Customer ارسال می کند:

<form action="Customer/Submit" method="post">  
    <table>  
        <tr>  
            <td>CustomerCode</td>  
            <td>  
                <input id="Code" name="Code" type="text" />  
            </td>  
        </tr>  
        <tr>  
            <td>Customer Name</td>  
            <td>  
                <input id="Name" name="Name" type="text" />  
            </td>  
        </tr>  
        <tr>  
            <td>  
                <input id="btnSubmit" name="btnSubmit" type="submit" value="Login" />  
            </td>  
        </tr>  
    </table>  
    </form> 

 

در اینجا زمانی که فرم را به controller ارسال(submit) کنیم form data به صورت اتوماتیک به شیئ کلاسی که نام مشابهی با نام کنترل HTML دارد map می شود، که به صورت زیر است:

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

 

حالا اگر Property های خود را داشته و کنترل های Html نام متفاوتی داشته باشد، مراحل بالا را به صورت مشابه انجام می دهیم تا ببینیم چه اتفاقی می افتد:

نام کنترل HTML و View

<div>  
    <form action="Customer/Submit" method="post">  
        <table>  
            <tr>  
                <td>CustomerCode</td>  
                <td>  
                    <input id="TxtCustomerCode" name="TxtCustomerCode" type="text" />  
                </td>  
            </tr>  
            <tr>  
                <td>Customer Name</td>  
                <td>  
                    <input id="TxtCustomerName" name="TxtCustomerName" type="text" />  
                </td>  
            </tr>  
            <tr>  
                <td>  
                    <input id="btnSubmit" name="btnSubmit" type="submit" value="Login" />  
                </td>  
            </tr>  
        </table>  
        </form> 

 

Property های کلاس

public class Customer   
{  
  
    public string Code  
    {  
        get;  
        set;  
    }  
  
    public string Name   
    {  
        get;  
        set;  
    }  
} 

خروجی:

 

 

با استفاده از Break Point می توان دید، زمانی که نام در form data متفاوت می شود، به صورت اتوماتیک map نمی شود.

 

همانطور که می دانید رابط کاربری توسط طراحان و کد C# توسط برنامه نویسان ایجاد می شود. پس آنها می توانند name را با توجه به اولویت خود تغییر دهند، سپس mapping خودکار همانطور که در بالا دیدیم اتفاق نمی افتد زیرا نام  Property و نام رابط کاربری متفاوت است و Form data به شیئ کلاس متصل نمی شود. بنابراین در اینجا Model Binder به تصویر می آید. Model Binder شامل کدی است که درخواست مرورگر را به شیئ داده map می کند.

فضای نام System.Web.Mvc پیاده سازی model binder را امکان می سازد.

به عبارت دیگر برای پیاده سازی Model binder باید IModelBinder interface را به صورت زیر پیاده سازی کنیم:

publicclassCustomerBinder : IModelBinder

برای همین یک کلاس با نام CustomerBinder ایجاد کرده و بعد متد Interface را پیاده سازی می کنیم:

همانطور که می دانید وب بر روی اصول ساده و اولیه درخواست و پاسخ کار می کند. کاربر درخواست را با کمک مرورگر به سرور می فرستد و سرور درخواست را تفسیر کرده پاسخ مورد نظر را روی مرورگر به کاربر تحویل می دهد:

حالا هردو شیئ درخواست و پاسخ متعلق به شی Context می باشد و آنها را به صورت زیر با هم map می کند:

publicclassCustomerBinder: IModelBinder   
{  
  
    publicobjectBindModel(ControllerContextcontrollerContext, ModelBindingContextbindingContext)  
    {  
        HttpContextBaseobjContext = controllerContext.HttpContext;  
        stringCustomerCode = objContext.Request.Form["TxtCustomerCode"]; //binding with UI txtCustomerCode  
        stringCustomerName = objContext.Request.Form["TxtCustomerName"]; //binding with UI txtCustomerName  
        CustomerobjCustomer = newCustomer() {  
            Code = CustomerCode, //mapping to the properties  
                Name = CustomerName //mapping to the properties  
        };  
        returnobjCustomer; //returning the object  
  
    }  
}

 

حالا از این کلاس استفاده کرده و به CustomerObject در هنگام ارسال، map می کنیم. مانند شکل زیر:

publicActionResult Submit([ModelBinder(typeof(CustomerBinder))] Customerobj)  
    //call the CustomerBinder class and fill this Customer Object   
    {  
        if (ModelState.IsValid) {  
            return View("Customer", obj);  
        } else {  
            return View("Index", obj);  
        }  
    }

([ModelBinder(typeof(CustomerBinder))] Customerobj

 

در این جا کلاس CustomerBinder از Http Context فراخوانی شده و می توانیم درخواست form data را بگیریم و آن را به Property  های کلاس map کنیم:

 

model binding:

 

 

 

حالا می توان دید که mapping توسط کلاس Model Binder  انجام شده و برنامه نویسان و طراحان می توانند به صورت جداگانه کار کنند. پس دیدیم که چگونه Model Binders به ما کمک می کند تا UI data را با Property های کلاس map کنیم. این بسیار ساده است زیرا ما وابسته به name کنترل های رابط کاربری نیستیم، و می توانیم به سادگی name را در کد Model Binder mapping قرار دهیم.

 

فایل های ضمیمه

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان

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

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید