2009年10月23日 星期五

ModelBinder In Asp.Net MVC

What is ModelBinder.
在 MSDN 中是這麼定義的

IModelBinder
Defines the methods that are required for a model binder.亙 費話

ModelBinder在 ASP.NET 中最主要的作用是讓POST回來的值在進入 Cotroller 之前可以先做一點整理。讓 Controller 可以直接使用已整理後的 Class 而不是一堆 Form 上面的資料

How.
要使用 ModelBinder 有幾個步驟
1. 建立 ModelBinder, 要 Implement IModelBinder
    public class Service1ModelBinder : IModelBinder
    {
        #region IModelBinder Members
 
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            var request = controllerContext.HttpContext.Request;
 
            Service1 service = new Service1(new User())
            {
                Name = request["name"]

..... other fields you need

            };
 
            return service;
        }
 
        #endregion
    }

2.定義 這個 ModelBinder 是 Bind 那個Class,這個要寫在 HttpApplication 中,一般是 Global.asax.cs

        protected void Application_Start()
        {

            //ModelBinders
            ModelBinderDictionary binders = System.Web.Mvc.ModelBinders.Binders;
            binders[typeof(Service1)] = new Service1ModelBinder();
            RegisterRoutes(RouteTable.Routes);
        }

3. 改寫 Controller 的 method

        [AcceptVerbs("POST")]
        public ActionResult Index(Service1 service)
        {
            ViewData["Message"] = service.Name;
 
            return View();
        }
View 的 code 如下
    <% Html.BeginForm(); %>
        <input type="text" name="name" value="Service1" />
        <button type="submit">Submitbutton>
    <%Html.EndForm(); %>

如此一來,在我們按下按鈕時會先觸發 ModelBinder 再將 ModelBinder 過後的 object 送給 Controller

Reference

IPrincipal (User) ModelBinder in ASP.NET MVC for easier testing


IModelBinder Interface

2009年10月21日 星期三

Unity 學習筆記 in Asp.Net MVC

1.Container.Resolve(Type t)
Resolve an instance of the default requested type from the container.
會將所指定的 class 產生一個 instance 並且將 Constructor 中的 parameter 注入

        container.Resolve(typeof(HomeController))

        public HomeController(Service service, Service2 service2)
        {
            this.service = service;
            this.service2 = service2;
        }

container 會將 Service 及 Service2 注入到 HomeController 中
但有個地方值得注意的。就是如果 HomeController 的 Constructor parameter 的 type 是 interface 時,就必需要注冊
            container.RegisterType<IService, Service>();

否則會有錯誤產生

2. Singleton
底下以 RegisterInstance 的方來來注冊 IUser

        protected void Application_Start()
        {
            IUnityContainer container = new UnityContainer();
 
            container.RegisterInstance<IUser>(new User() { Name = "Unity" });
 
 
            CustomUnityControllerFactory factory = new CustomUnityControllerFactory(container);
 
 
            ControllerBuilder.Current.SetControllerFactory(factory);
 
            RegisterRoutes(RouteTable.Routes);
        }

HomeController
Constructor 中有兩個參數 Service1, Service2
    [HandleError]
    public class HomeController : Controller
    {
        Service1 service1;
        Service2 service2;
 
        public HomeController(Service1 service1, Service2 service2)
        {
            this.service1 = service1;
            this.service2 = service2;
        }
 
        public ActionResult Index()
        {
            ViewData["Message"] = service1.Message();
 
            ViewData["Message2"] = service2.Message();
 
            return View();
        }
 
        public ActionResult About()
        {
            return View();
        }
 
    }

Service1
在呼叫 Message 後會改變 User.Name 的值
    public class Service1 : IService
    {
        IUser user;
 
        public Service1(IUser user)
        {
            this.user = user;
        }
 
 
        #region IService Members
 
 
        public string Message()
        {
            string t = user.Name;
            user.Name = "Yes!! I'm Sigleton";
            return t;
        }
 
        #endregion
    }

Service2
    public class Service2 : IService
    {
        IUser user;
 
        public Service2(IUser user)
        {
            this.user = user;
        }
 
        #region IService Members
 
        public string Message()
        {
            return user.Name;
        }
 
        #endregion
    }
需注意的是 在 Service 的 constructor 中需以 IUser ,如以Class 來當為參數的話。unity會產生一個新的實體。


Reference
Unity framework with ASP.Net MVC Framework