2012-07-23 33 views
5

thực thể của tôi: (các PersonModel cần phải có một địa chỉ vào loại AddressOne hoặc AddressTwo (và có thể những người khác) nên PersonModel có một loại đối tượng cho các trường địa chỉ.)Asp.Net MVC 3 Tuỳ chỉnh mẫu Ràng buộc với đối tượng biến

public class Person 
{ 
    public int PersonId { get; set; } 
    public string Name { get; set; } 
    public string Surname { get; set; } 
    public object Address { get; set; } 
} 

public class AddressOne 
{ 
    public string Street { get; set; } 
    public string City { get; set; } 
} 

public class AddressTwo 
{ 
    public string Province { get; set; } 
    public string State { get; set; } 
} 

các mô hình: (tôi vượt qua một lĩnh vực tiềm ẩn trong typeOfAddress khớp với địa chỉ chính xác sau khi gửi biểu mẫu có)

public class PersonModel 
{ 
    private System.Type _typeOfAddress; 
    private object _address; 

    [Required] 
    public int PersonId { get; set; } 
    [Required] 
    public string Name { get; set; } 
    [Required] 
    public string Surname { get; set; } 

    public System.Type typeOfAddress 
    { 
     get { return _typeOfAddress; } 
     set { _typeOfAddress = value; } 
    } 

    public object Address 
    { 
     get { 
      return _address; 
     } 
     set { 
      _address = value; 
      _typeOfAddress = _address.GetType(); 
     } 
    } 
} 

public class AddressOneModel 
{ 
    [Required] 
    public string Street { get; set; } 
    [Required] 
    public string City { get; set; } 
} 

public class AddressTwoModel 
{ 
    [Required] 
    public string Province { get; set; } 
    [Required] 
    public string State { get; set; } 
} 

Quan điểm của tôi (đối với trường địa chỉ tôi có mẫu biên tập quảng cáo nào được bỏ qua trong mã này) :

@using (Html.BeginForm()) { 

<ul> 
<li> 
    PersonId: @Html.EditorFor(model => model.PersonId) 
</li> 
<li> 
    Name: @Html.EditorFor(model => model.Name) 
</li> 
<li> 
    Surname: @Html.EditorFor(model => model.Surname) 
</li> 
<li> 
    Address: 
</li> 
<li> 
    @Html.HiddenFor(model => model.typeOfAddress) 
    @Html.EditorFor(model => model.Address) 
</li> 
</ul> 
<button type="submit">Submit</button> 

} 

và sau đó điều khiển của tôi: (trong ví dụ này tôi tải AddressOne trong mô hình nhưng phải Một hoặc hai phụ thuộc vào thời gian chạy ...)

[HttpGet] 
    public ActionResult Index() 
    { 
     PersonModel myPerson = new PersonModel(); 

     myPerson.PersonId = 1; 
     myPerson.Name = "Michael"; 
     myPerson.Surname = "Douglas"; 

     AddressOneModel Address = new AddressOneModel(); 
     Address.Street = "5th Avenue"; 
     Address.City = "New York"; 

     myPerson.Address = Address; 

     return View(myPerson); 
    } 

    [HttpPost] 
    public ActionResult Index([ModelBinder(typeof(PersonModelBinder))]PersonModel myPerson) 
    { 
     if (ModelState.IsValid) { 
      // some things here 
     } 
     return View(); 
    } 

sau đó là Binder Mô hình PersonModel :

public class PersonModelBinder : IModelBinder 
{ 
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     PersonModel bindedModel = new PersonModel(); 

     foreach (var Property in typeof(PersonModel).GetProperties()) 
     { 
      PropertyInfo info = bindedModel.GetType().GetProperty(Property.Name); 
      object castedInfo = new object(); 

      var uType = info.PropertyType; 
      if (uType == typeof(string)) 
      { 
       castedInfo = bindingContext.ValueProvider.GetValue(Property.Name).AttemptedValue.ToString(); 
      } 
      else if (uType == typeof(Type)) 
      { 
       castedInfo = Type.GetType(bindingContext.ValueProvider.GetValue(Property.Name).AttemptedValue.ToString()); 
      } 
      else if (uType == typeof(object)) 
      { 
       string objType = bindingContext.ValueProvider.GetValue("typeOfAddress").AttemptedValue; 
       object address = (object)Activator.CreateInstance(Type.GetType(objType)); 

       // another foreach as previous 
      } 
      else 
      { 
       object uCasted = (object)Activator.CreateInstance(info.PropertyType); 
       uCasted = Convert.ChangeType(bindingContext.ValueProvider.GetValue(Property.Name).AttemptedValue, Property.PropertyType); 
       castedInfo = uCasted; 
      } 
      info.SetValue(bindedModel, castedInfo, null); 
     } 
     return bindedModel; 
    } 

Đây có phải là cách chính xác để triển khai ràng buộc PersonModel không? Và những gì về xác nhận trong bộ điều khiển [Post]?

Tôi cũng nhìn thấy một cách để sử dụng DefaultBinder theo một cách như thế này:

[ModelBinderType(typeof(PersonModel))] 
public class PersonModelBinder : DefaultModelBinder 
{ 
    //... 
} 

nhưng tôi không tìm thấy bất kỳ tài liệu tham khảo của ModelBinderType trong MVC3 !! Bất kì lời đề nghị nào?

Trả lời

2

Có vẻ như bạn đang cố gắng làm điều này một cách khó khăn. Bạn không nên cần một chất kết dính mô hình. Những gì tôi sẽ làm là thêm từng loại địa chỉ vào mô hình và trên trang hiển thị địa chỉ không phải là rỗng. Điều này sẽ giúp bạn tiết kiệm rất nhiều rắc rối.

public class PersonModel : IValidatableObject 
{ 
    private System.Type _typeOfAddress; 
    private object _address; 

    [Required] 
    public int PersonId { get; set; } 
    [Required] 
    public string Name { get; set; } 
    [Required] 
    public string Surname { get; set; } 

    public System.Type typeOfAddress 
    { 
     get { return (AddressOne ?? AddressTwo ?? AddressThree).GetType(); } 
    } 

    public AdressOneModel AddressOne {get;set;} 
    public AdressTwoModel AddressTwo {get;set;} 
    public AdressThreeModel AddressThree {get;set;} 
} 

Sau đó, có lẽ trên trang làm điều này

@using (Html.BeginForm()) 
{ 
    <ul> 
    <li> 
     PersonId: @Html.EditorFor(model => model.PersonId) 
    </li> 
    <li> 
     Name: @Html.EditorFor(model => model.Name) 
    </li> 
    <li> 
     Surname: @Html.EditorFor(model => model.Surname) 
    </li> 
    <li> 
     Address: 
    </li> 
    <li> 
    @if(model.AddressOne != null) 
    { 
     Html.EditorFor(model => model.AddressOne) 
    } 
    else if(model.AddressTwo != null) 
    { 
     Html.EditorFor(model => model.AddressTwo) 
    } 
    </li> 
    </ul> 
    <button type="submit">Submit</button> 
} 

Nhưng nó thực sự phụ thuộc vào lý do tại sao bạn đang làm

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