代码之家  ›  专栏  ›  技术社区  ›  Zack Peterson

如何在ASP.NET MVC视图中使用函数?

  •  0
  • Zack Peterson  · 技术社区  · 15 年前

    我想在我的ASP.NET MVC视图中使用类似这样的简单函数。它接受一个整数参数并返回一个字符串。

    Function FileSizeString(ByVal ByteCount As Integer) As String
        Select Case ByteCount
            Case Is < (2 ^ 10)
                Return ByteCount.ToString("N0") + "B"
            Case (2 ^ 10) To ((2 ^ 20) - 1)
                Return (ByteCount / (2 ^ 10)).ToString("N0") + "KB"
            Case (2 ^ 20) To ((2 ^ 30) - 1)
                Return (ByteCount / (2 ^ 20)).ToString("N0") + "MB"
            Case (2 ^ 30) To Integer.MaxValue
                Return (ByteCount / (2 ^ 30)).ToString("N0") + "GB"
        End Select
    End Function
    

    我把它放在我的控制器中,但是我不能在我的视图中执行它。这会产生编译时错误“name'filesizeString'未声明。”

    <ul>
        <% For Each d As Document In Model.Attachments%>
        <li>
            <a href="<%=Url.RouteUrl("Download", New With {.id = a.Id}) %>">
                <%=d.FileName %> (<%=FileSizeString(d.FileSize) %> bytes)
            </a>
        </li>
        <% Next %>
    </ul>
    

    我需要把我的功能放在哪里?如何使视图能够访问它?

    6 回复  |  直到 15 年前
        1
  •  3
  •   David Andres    15 年前

    您可能需要研究HTML扩展方法。您可以这样创建一个:

    Public Module FileSizeExtension
      <Extension()> _
      Public Shared Function FileSizeAsString(ByVal helper AS HtmlHelper,
                                              ByVal byteCount As Integer) As String
        Select Case ByteCount  
         Case Is < (2 ^ 10)
           Return ByteCount.ToString("N0") + "B"
         Case (2 ^ 10) To ((2 ^ 20) - 1)
           Return (ByteCount / (2 ^ 10)).ToString("N0") + "KB"
         Case (2 ^ 20) To ((2 ^ 30) - 1)
           Return (ByteCount / (2 ^ 20)).ToString("N0") + "MB"
         Case (2 ^ 30) To Integer.MaxValue
           Return (ByteCount / (2 ^ 30)).ToString("N0") + "GB"
        End Select
      End Function
    End Module
    

    现在您可以在视图中使用 <%= Html.FileSizeAsString(byteCount) %>

    尽管您可以通过以下方式访问视图的控制器: ViewContext.Controller ,您需要将该属性强制转换为您期望的确切类型。然后,如果愿意,可以调用控制器方法。许多人不喜欢这种方法,因为它将您的视图与特定的控制器结合起来。

    为了便于论证,应采取以下措施:

    <% Dim homeController AS HomeController = 
        TryCast(ViewContext.Controller, HomeController) %>
    <ul>
     <% For Each d As Document In Model.Attachments%>
     <li>
      <a href="<%=Url.RouteUrl("Download", New With {.id = a.Id}) %>">
       <%=d.FileName %> (<%= homeController.FileSizeString(d.FileSize) %> bytes)
      </a>
     </li>
     <% Next %>
    </ul>
    
        2
  •  2
  •   Franci Penov    15 年前

    您可以将它作为扩展方法添加到 HtmlHelper 类。然后你可以通过 Html 视图的属性。

    下面是一个如何 extend HtmlHelper .

        3
  •  1
  •   D'Arcy Rittich    15 年前

    一旦您在视图中,控制器就被释放了——相反,您可以创建一个实用程序类并将方法放在那里,或者在int上创建一个扩展方法。

        4
  •  1
  •   Charlino    15 年前

    你需要使它成为一个htmlhelper执行方法…

    完成后,请确保导入extension方法所在的名称空间,以便视图中的HTML对象了解该名称空间。

        5
  •  1
  •   Michael Stum    15 年前

    如果它是专门针对这个视图的,那么它应该进入视图的视图模型。如果它在多个视图之间共享,那么扩展htmlhelper是一个选项。但是,如果不返回HTML,只返回可以在其他部分使用的原始字符串,那么将它添加到有问题的模型类(这基本上意味着重写toString()方法或添加一个新方法)是很好的。

        6
  •  0
  •   Zack Peterson    15 年前

    我不太喜欢htmlhelper扩展建议。这似乎不适合这个用途。

    我在文档类中添加了一个函数:

    Partial Public Class Document
    
        Function FileSizeString() As String
            Select Case Me.FileSize
                Case 1 To ((2 ^ 10) - 1)
                    Return Me.FileSize.ToString("N0") + "B"
                Case (2 ^ 10) To ((2 ^ 20) - 1)
                    Return (Me.FileSize / (2 ^ 10)).ToString("N0") + "KB"
                Case (2 ^ 20) To ((2 ^ 30) - 1)
                    Return (Me.FileSize / (2 ^ 20)).ToString("N0") + "MB"
                Case (2 ^ 30) To Integer.MaxValue
                    Return (Me.FileSize / (2 ^ 30)).ToString("N0") + "GB"
                Case Else
                    Throw New ArgumentOutOfRangeException("byteCount", "Value must be a positive integer.")
                    Return "unknown size"
            End Select
        End Function
    
    End Class
    

    我在ASP.NET MVC视图中使用的:

    <ul>
        <% For Each d As Document In Model.Attachments%>
        <li>
            <a href="<%=Url.RouteUrl("Download", New With {.id = d.Id}) %>">
                <%=d.FileName %> (<%=d.FileSizeString %>)
            </a>
        </li>
        <% Next %>
    </ul>