2010-09-09 12 views
6

Đối với số năm tôi đã làm hình thức web ASP.NET phát triển Tôi đã hư hỏng do một thư viện độc quyền, cho phép tôi làm những việc như:Mẫu Binder trong ASP.NET WebForms

UpdateToObject(ControlsCollection, obj) 
    UpdateFromObject(ControlsCollection, obj) 

đang Về mặt lý thuyết đã làm một cái gì đó rất tương tự như những gì MVC Model Binder làm, tức là cho các giá trị được gửi của biểu mẫu như đầu vào nó sẽ cư trú đối tượng tùy chỉnh. Về cơ bản nó giải phóng phát triển từ làm đang khỉ như

employee.Name = txtName.Text; 
employee.DOB = DateTime.Parse(txtDOB.Text); 

và vân vân ..

Bây giờ, thư viện độc quyền này không có sẵn trên dự án mới Tôi tham gia với, và đó là một dự án hình thức Web . Vì vậy, tôi tự hỏi nếu có một cách sử dụng System.Web.Mvc.DefaultModelBinder trong bối cảnh của các hình thức Web. Mục tiêu là để đạt được số lượng điều khiển đơn giản và dễ dàng từ các đối tượng miền và ngược lại, lý tưởng với chú thích xác thực được xem xét. Nếu như vậy là không thể ai đó có thể chỉ cho tôi một giải pháp nguồn mở để giải quyết nhu cầu này. Tôi thực sự không cảm thấy như viết lại mã như vậy.

Xin cảm ơn trước.

Trả lời

1

Sherlock, bạn sẽ gặp phải một số sự cố khi cố gắng sử dụng ModelBinder từ MVC vì chúng dựa trên ControllerContext.

Tôi đã trả lời một câu hỏi tương tự trước đó ChangeType, Convert - Converting from one type to another nhưng đó thực sự là những gì bạn đang tìm kiếm.

Kiểm tra bài viết trên blog này trên blog của tôi ChangeType – Changing the type of a variable in C#

Về cơ bản, bạn sẽ có được một phương pháp duy nhất gọi là ChangeType<T> mà trả về giá trị của tham số bạn đang tìm kiếm một cách mạnh mẽ gõ hoặc một giá trị mặc định nếu tham số không tồn tại.

Bây giờ liên quan đến các lớp tùy chỉnh (DTO loại lớp chủ yếu), nếu bạn không nhớ bằng cách sử dụng phản ánh sau đó tôi có một giải pháp mà sẽ xử lý hầu hết các lớp tùy chỉnh là tốt. Lớp DtoBinder đã đề cập đến phần cuối của công việc sẽ độc đáo.

Về cơ bản, 3 danh sách mã cuối cùng chứa tất cả mã bạn cần để xử lý hầu hết mọi nhu cầu bạn có trong một kịch bản ứng dụng web điển hình. Thêm vào đó nó có thể mở rộng, vì vậy nếu bạn cần phải thực hiện chất kết dính của riêng bạn, bạn có thể làm điều đó rất đơn giản và đăng ký chất kết dính của bạn với RequestBinder từ bất cứ đâu trong ứng dụng của bạn. Vì vậy nếu bạn không muốn sử dụng sự phản chiếu cho một số đối tượng DTO thường xuyên sử dụng, bạn có thể thực hiện một chất kết dính cho loại và đăng ký nó và từ thời điểm đó trên nó sẽ sử dụng chất kết dính tùy chỉnh của bạn. Theo nhiều cách, nó tương tự như khái niệm MVC ModelBinder.

Đã chỉnh sửa -

Dưới đây là một tệp .cs mà trước đây tôi đã sử dụng để thực hiện chính xác những gì bạn cần. Người đầu tiên MsPropertyAssignerProvider là một trong những bạn đang làm việc với từ bên trong trang của bạn.

Bạn muốn lặp qua các điều khiển của mình và gọi phương thức GetPropertyAssigner chuyển cho nó tên kiểu của điều khiển. Phương thức này trả về một cá thể của một ObjectPropertyAssigner có một phương thức được gọi là SetPropertyValue mà bạn có thể truyền thể hiện đối tượng của bạn và cá thể điều khiển đến.

internal class MsPropertyAssignerProvider 
    { 
    private Hashtable propertyAssigners; 

    internal MsPropertyAssignerProvider() 
    { 
     propertyAssigners = new Hashtable(); 
     RegisterPropertyAssigner(typeof(TextBox).ToString(), new TextBoxValueExtractor()); 
     RegisterPropertyAssigner(typeof(DropDownList).ToString(), new DropDownListValueExtractor()); 
     RegisterPropertyAssigner(typeof(Label).ToString(), new LabelValueExtractor()); 
     RegisterPropertyAssigner(typeof(CheckBox).ToString(), new CheckBoxValueExtractor()); 
    } 

    internal void RegisterPropertyAssigner(string identifier, IMsObjectPropertyAssigner assigner) 
    { 
     if (propertyAssigners.ContainsKey(identifier)) 
     throw new DuplicatePropertyAssignerRegistrationException(identifier); 
     propertyAssigners.Add(identifier, assigner); 
    } 

    internal IMsObjectPropertyAssigner GetPropertyAssigner(string identifier) 
    { 
     return (propertyAssigners.ContainsKey(identifier)) ? (IMsObjectPropertyAssigner)propertyAssigners[identifier] : null; 
    } 
    } 

Lớp kèm được liệt kê dưới đây

public interface IMsObjectPropertyAssigner 
    { 
    void SetPropertyValue(object obj, System.Web.UI.Control control); 
    } 

    internal abstract class BaseValueExtractor : IMsObjectPropertyAssigner 
    { 
    protected MsReflectionHelper reflectionHelper = new MsReflectionHelper(); 
    protected string FixStringForNumber(string stringValue) 
    { 
     if (stringValue.Length == 0) 
     return "0"; 
     else 
     return stringValue; 
    } 
    public abstract void SetPropertyValue(object obj, System.Web.UI.Control control); 
    } 

    internal class TextBoxValueExtractor : BaseValueExtractor 
    { 
    public override void SetPropertyValue(object obj, System.Web.UI.Control control) 
    { 
     TextBox textBox = (TextBox)control; 
     PropertyInfo propInfo = reflectionHelper.GetPropertyInfo(obj, control.ID); 
     Type propType = propInfo.PropertyType; 
     if (propType == typeof(System.String)) 
     reflectionHelper.SetPropertyValue(obj, control.ID, textBox.Text); 
     else if (propType == typeof(System.Int16)) 
     reflectionHelper.SetPropertyValue(obj, control.ID, Int16.Parse(FixStringForNumber(textBox.Text), System.Globalization.NumberStyles.Currency)); 
     else if (propType == typeof(System.Int32)) 
     reflectionHelper.SetPropertyValue(obj, control.ID, Int32.Parse(FixStringForNumber(textBox.Text), System.Globalization.NumberStyles.Currency)); 
     else if (propType == typeof(System.Int64)) 
     reflectionHelper.SetPropertyValue(obj, control.ID, Int64.Parse(FixStringForNumber(textBox.Text), System.Globalization.NumberStyles.Currency)); 
     else if (propType == typeof(System.Double)) 
     reflectionHelper.SetPropertyValue(obj, control.ID, Double.Parse(FixStringForNumber(textBox.Text), System.Globalization.NumberStyles.Currency)); 
     else if (propType == typeof(System.Single)) 
     reflectionHelper.SetPropertyValue(obj, control.ID, Single.Parse(FixStringForNumber(textBox.Text), System.Globalization.NumberStyles.Currency)); 
     else 
     reflectionHelper.SetPropertyValue(obj, control.ID, textBox.Text); 
    } 
    } 

    internal class DropDownListValueExtractor : BaseValueExtractor 
    { 
    public override void SetPropertyValue(object obj, System.Web.UI.Control control) 
    { 
     DropDownList dropDownList = (DropDownList)control; 
     reflectionHelper.SetPropertyValue(obj, control.ID, dropDownList.SelectedValue); 
    } 
    } 

    internal class LabelValueExtractor : BaseValueExtractor 
    { 
    public override void SetPropertyValue(object obj, Control control) 
    { 
     Label label = (Label)control; 
     reflectionHelper.SetPropertyValue(obj, control.ID, label.Text); 
    } 
    } 

    internal class CheckBoxValueExtractor : BaseValueExtractor 
    { 
    public override void SetPropertyValue(object obj, Control control) 
    { 
     CheckBox checkbox = (CheckBox)control; 
     reflectionHelper.SetPropertyValue(obj, control.ID, checkbox.Checked); 
    } 
    } 

Xin lỗi không có vấn đề gì tôi làm biên tập hoàn toàn messes lên danh sách mã. Nhưng tôi hy vọng điều này sẽ giúp.

+0

Chỉ các đoạn 1 và đoạn cuối có phần liên quan đến câu hỏi được nêu ra. Tôi không nhớ sử dụng sự phản chiếu. Đây là cách thư viện sở hữu độc quyền làm việc. – Sherlock

+0

Tôi đoán trong trường hợp của bạn bởi vì bạn đang làm việc với Điều khiển giải pháp có liên quan nhiều hơn một chút. Lớp DtoBinder có thể tạo một thể hiện của đối tượng Dto của bạn và gán tất cả các giá trị thuộc tính cho một tập hợp các NameValues. Vì vậy, những gì bạn cần làm là lắp ráp bộ sưu tập này từ tên và giá trị của điều khiển và đưa nó cho DtoBinder. –

+0

Chỉ cần chỉnh sửa câu trả lời ban đầu của tôi với một số lớp bổ sung mà tôi đã sử dụng trong quá khứ. –

1

Bạn sẽ không thể sử dụng AutoMapper cho một cái gì đó như thế này? Chỉ cần thiết lập bản đồ của bạn và nó sẽ tạo ra các đối tượng mới và sao chép các giá trị vào chúng.

0

Đây là một câu hỏi khá cũ nhưng tôi đã gặp phải vấn đề này trong khi cố gắng tìm ra cách trình kết nối mô hình mặc định thực sự hoạt động.

Tôi có một dự án về CodeProject thực sự thực hiện những gì bạn muốn (ed), have a look.

Chúc mừng!