2013-04-05 28 views
12

Tôi đã đăng ký một mô hình tùy chỉnh chất kết dính cho MyList trong global.asax. Tuy nhiên mô hình chất kết dính không cháy cho thuộc tính lồng nhau, cho các loại đơn giản nó hoạt động tốt. Trong ví dụ dưới đây, nó cháy cho Index() nhưng không phải không cháy cho Index2()Tùy chỉnh Mẫu Binder không cháy

Global.asax

protected void Application_Start() 
{ 
    AreaRegistration.RegisterAllAreas(); 

    ModelBinders.Binders.Add(typeof(MyList), new MyListBinder()); 

    WebApiConfig.Register(GlobalConfiguration.Configuration); 
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
    RouteConfig.RegisterRoutes(RouteTable.Routes); 
} 

Code:

public class MyListBinder : IModelBinder 
{ 
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     return new MyList(); 
    } 
} 

public class MyList 
{ 
    public List<int> items { get; set; } 
} 

public class MyListWrapper 
{ 
    public MyList listItems { get; set; } 
} 

public class TestController : Controller 
{ 
    public ActionResult Index(MyList list) // ModelBinder fires :-) 
    {    
     return View(); 
    } 

    public ActionResult Index2(MyListWrapper wrapper) // ModelBinder does not fire! :-(
    { 
     return View(); 
    } 
} 
+0

Bạn đã tìm thấy giải pháp cho vấn đề này chưa? –

Trả lời

0

model binder của bạn được kết hợp với lớp MyList của bạn, không phải với MyListWrapper. MyListBinder chỉ được sử dụng với lớp MyList hoặc một lớp được thừa hưởng từ MyClass.

+0

Vui lòng thêm nhận xét dưới câu hỏi chứ không phải là câu trả lời. – newbie

2

Trình kết nối mô hình được sử dụng để cho phép các hành động chấp nhận các loại đối tượng phức tạp làm tham số. Các loại phức tạp này phải được tạo thông qua các yêu cầu POST, ví dụ: bằng cách gửi biểu mẫu. Nếu bạn có một đối tượng rất phức tạp mà không thể bị ràng buộc bởi trình kết nối mô hình mặc định (hoặc nó sẽ không hiệu quả), bạn có thể sử dụng các bộ mô hình tùy chỉnh.

Để trả lời câu hỏi của bạn: nếu bạn không thêm một mô hình tùy chỉnh chất kết dính cho lớp MyListWrapper quá, các BindModel (của MyListBinder) sẽ không được gọi trong một yêu cầu GET, đây là cách ASP.NET MVC hoạt động. Tuy nhiên, nếu bạn sửa đổi mã của bạn bằng cách thêm một hành động POST với tham số MyListWrapper, bạn có thể thấy rằng phương pháp BindModel được gọi là đúng.

[HttpGet] 
public ActionResult Index2() // ModelBinder doesn't fire 
{ 
    return View(); 
} 

[HttpPost] 
public ActionResult Index2(MyListWrapper wrapper) // ModelBinder fires 
{ 
    return View(); 
} 

Và Index2 xem

@model fun.web.MyListWrapper 

@using (Html.BeginForm()) 
{ 
    @Html.HiddenFor(m => m.listItems) 
    <input type="submit" value="Submit" /> 
} 

Nếu bạn muốn "kiểm soát" các tham số hành động trong yêu cầu GET, bạn nên sử dụng action filters.

+0

trong một yêu cầu POST quá các chất kết dính sẽ không cháy trừ khi tôi thêm chất kết dính cho MyListWrapper quá đúng không? – newbie

+0

Tôi đã thử rằng, ngay cả với một binder cho MyListWrapper, trong cả hai GET và POST yêu cầu các chất kết dính MyListWrapper bị sa thải nhưng MyListBinder không cháy – newbie

+0

Vấn đề là không nhận được hoặc đăng nhưng chất kết dính phải được đăng ký nếu không khuôn khổ mvc sẽ biết về nó...Cách tốt nhất để làm điều này là cách tốt nhất là đăng ký mô hình JUST Binder của bạn cho một kiểu dữ liệu đơn MyList của bạn ... như được đề xuất trong các câu trả lời khác. –

1

Thêm phần này vào thế giới của bạn:

ModelBinders.Binders.Add(typeof(MyListWrapper), new MyListWrapperBinder()); 

Và sau đó tạo ra một MyListWrapperBinder có thể xử lý các ràng buộc.

+1

Câu hỏi đặt ra là kích hoạt câu hỏi khi loại tùy chỉnh là thuộc tính của loại khác. – newbie

+1

Điểm mấu chốt là bạn cần một ModelBinder cho bất kỳ loại nào đang được chuyển đến ActionMethod của bạn. –

1

Bạn đã xác định liên kết cho MyList, do đó, trình kích hoạt chỉ kích hoạt khi tham số nhập phương thức hành động thuộc loại MyList.

ModelBinders.Binders.Add(typeof(MyList), new MyListBinder()); 

Nếu bạn muốn mô hình chất kết dính để kích hoạt ngay cả khi MyList của bạn được lồng vào mô hình khác, bạn phải làm điều này:

[ModelBinder(typeof(MyListBinder))] 
public class MyList 
{ 
    public List<int> items { get; set; } 
} 

Sau đó, mô hình chất kết dính gây nên bất cứ khi nào nó gặp MyList loại, thậm chí khi nó lồng nhau.

+0

Không trả lời câu hỏi, để kích hoạt mô hình kết dính cho Mylist tôi không cần phải thêm thuộc tính. Điều này có làm cho Trình mô phỏng kích hoạt khi MyList là một thuộc tính của MyListWrapper không? – newbie

Các vấn đề liên quan