2009-03-24 29 views
37

Tôi đang viết ứng dụng MVC asp.net đầu tiên của tôi và tôi có một câu hỏi về những người giúp đỡ tùy chỉnh Html:Tuỳ chỉnh giúp đỡ html: Tạo helper với "sử dụng" hỗ trợ tuyên bố

Để thực hiện một biểu mẫu, bạn có thể sử dụng:

<% using (Html.BeginForm()) {%> 
    *stuff here* 
<% } %> 

Tôi muốn làm điều gì đó tương tự với trình trợ giúp HTML tùy chỉnh. Nói cách khác, tôi muốn thay đổi:

Html.BeginTr(); 
Html.Td(day.Description); 
Html.EndTr(); 

thành:

using Html.BeginTr(){ 
    Html.Td(day.Description); 
} 

Đây có phải là có thể?

Trả lời

47

Dưới đây là một việc thực hiện tái sử dụng có thể trong C#:

class DisposableHelper : IDisposable 
{ 
    private Action end; 

    // When the object is created, write "begin" function 
    public DisposableHelper(Action begin, Action end) 
    { 
     this.end = end; 
     begin(); 
    } 

    // When the object is disposed (end of using block), write "end" function 
    public void Dispose() 
    { 
     end(); 
    } 
} 

public static class DisposableExtensions 
{ 
    public static IDisposable DisposableTr(this HtmlHelper htmlHelper) 
    { 
     return new DisposableHelper(
      () => htmlHelper.BeginTr(), 
      () => htmlHelper.EndTr() 
     ); 
    } 
} 

Trong trường hợp này, BeginTrEndTr trực tiếp viết trong dòng phản ứng. Nếu bạn sử dụng phương pháp mở rộng mà trả về một chuỗi, bạn sẽ phải xuất chúng sử dụng:

htmlHelper.ViewContext.HttpContext.Response.Write(s) 
+0

pweh .. và tôi nghĩ đây sẽ là dễ dàng .. Cám ơn nỗ lực của bạn. –

+0

Nó chỉ là một triển khai nhanh chóng và dơ bẩn. Các đại biểu "bắt đầu" có thể được gọi trực tiếp trong phương pháp mở rộng của bạn và lớp DisposableHelper có thể tái sử dụng cho các phần mở rộng khác – ybo

+0

Ok cảm ơn, tôi sẽ xem xét kỹ hơn sau này. –

18

Nếu bạn nhìn vào các nguồn cho ASP.NET MVC (phục vụ theo Codeplex), bạn sẽ thấy việc thi hành BeginForm cuối cùng gọi xuống để đoạn mã sau:

static MvcForm FormHelper(this HtmlHelper htmlHelper, string formAction, FormMethod method, IDictionary<string, object> htmlAttributes) 
{ 
    TagBuilder builder = new TagBuilder("form"); 
    builder.MergeAttributes<string, object>(htmlAttributes); 
    builder.MergeAttribute("action", formAction); 
    builder.MergeAttribute("method", HtmlHelper.GetFormMethodString(method), true); 
    htmlHelper.ViewContext.HttpContext.Response.Write(builder.ToString(TagRenderMode.StartTag)); 

    return new MvcForm(htmlHelper.ViewContext.HttpContext.Response); 
} 

Các MvcForm cụ lớp IDisposable, trong phương thức xử lý của nó là viết </form > cho phản hồi.

Vì vậy, những gì bạn cần làm là ghi các thẻ bạn muốn trong phương thức trợ giúp và trả về một đối tượng triển khai IDisposable ... trong phương pháp xử lý của nó, đóng thẻ.

31

Tôi thử làm theo các lời khuyên đưa ra ở đây trong MVC3, nhưng tôi chạy vào cố khi sử dụng:

htmlHelper.ViewContext.HttpContext.Response.Write(...); 

Khi tôi sử dụng mã này, trình trợ giúp của tôi đã viết vào luồng Trả lời TRƯỚC KHI Bố cục của tôi được hiển thị. Điều này đã không hoạt động tốt.

Thay vào đó tôi đã sử dụng này:

htmlHelper.ViewContext.Writer.Write(...); 
+2

Thanks heaps. Đã lưu tôi đống thời gian. –

+2

Làm việc cho tôi trong MVC 3 bằng cách sử dụng mã ban đầu đã được viết ra nội dung trợ giúp html ngay bên dưới cơ thể html. Điều này cố định nó. –

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