1

我是 vb9 和 .NET MVC 的新手。我想构建一个 MVC 辅助函数,我为其传递一个实体框架对象并让它构建一个选择。一般来说,我尝试过这样的事情:

Public Function RenderSelect(ByVal helper As HtmlHelper, ByVal sSelectName As String, ByVal aItmes As Array, Optional ByVal sTitleKeyName As String = "name", Optional ByVal sValueKeyName As String = "id") As String

        ' open select
        For Each Object In aItmes
            ' here i would like to do something like:
            Dim OptionValue = Object.(sValueKeyName) 
            ' NOTE: I have a var with the property name
            Dim OptionTitle = Object.(sTitleKeyName)

            . then add the option structure to the select
        Next
        ' close select

        Return String
    End Function

但是,它不起作用。有办法做到这一点并传递当前实体对象会很棒。数据类型打败了我。提前致谢。

4

3 回答 3

0

如果 VB 看起来,最终的缺点是它是冗长的内省。如果您有一个带有属性名称的字符串,则没有好的方法可以在随机对象上获取该属性的值。做某事需要接触每个班级。Dennis Palmer 的方法可能是允许创建泛型选择的最佳方式。

所以我提出了一个问题:Entity Framework 团队会在未来的版本中为此构建一些有用的东西吗?

于 2009-07-28T23:26:25.377 回答
0

什么不工作?你的代码能运行吗?它会生成一个字符串吗?

您至少有一个错字会导致生成的字符串无法在 HTML 表单中工作。应该<option value={0}>{1}</option>

编辑 2:为了IDictionary(Of Object, String)从您的 EF 对象中获取,我将编写部分类实现,GetSelectOptions为您的每个对象添加一个方法。或者使用您的每个 EF 对象实现的该方法创建一个接口。然后你只需调用该方法并作为参数RenderSelect传入。EFObject.GetSelectOptionsSelectOptions

编辑:这就是我将如何做到这一点。让您的调用代码负责从您的 EF 对象中读取键/值对。然后你的 RenderSelect 扩展方法可以更干净。您不希望视图辅助方法依赖于模型对象的结构。而且您当然不希望您的辅助方法依赖于您正在使用 EF 对象的事实。

    Public Function RenderSelect(ByVal helper As HtmlHelper, _
                                 ByVal name As String, _
                                 ByVal SelectOptions As IDictionary(Of Object, String), _
                                 ByVal SelectedKey As Object, _
                                 ByVal htmlAttributes As IDictionary(Of String, Object)) As String
        Dim result = <select name=<%= name %>/>
        Dim optElement As XElement
        For Each opt In SelectOptions
            optElement = <option value=<%= opt.Key.ToString %>><%= opt.Value %></option>
            If opt.Key.Equals(SelectedKey) Then
                optElement.@selected = "1"
            End If
            result.Add(optElement)
        Next
        If htmlAttributes IsNot Nothing Then
            For Each attr In htmlAttributes
                result.SetAttributeValue(attr.Key, attr.Value)
            Next
        End If
        Return result.ToString
    End Function

有关 VB.NET 中完整的重载 DropDownList 函数集,请查看 vbmvc.codeplex.com 项目中的此文件,从该文件中复制和修改了上述代码。

http://vbmvc.codeplex.com/sourcecontrol/changeset/view/19233?projectName=VBMVC#331689

该代码的返回类型为 XElement,但如果您想要的话,只需使用 result.ToString 来获取元素的字符串表示形式。

于 2009-07-20T19:23:58.537 回答
0

好的,所以 2.0 中的内省很差,但在 3.5 中有所改进。所以我几乎放弃了这个,直到我开始搞乱GetType,我偶然发现了这个:

Imports System.Runtime.CompilerServices
Imports System.IO

Public Module HtmlCtrlHelper
    <System.Runtime.CompilerServices.Extension()> _
    Public Function RenderSelect(ByVal helper As HtmlHelper, ByVal sName As String, ByVal Itmes As Object, Optional ByVal sValueName As String = "id", Optional ByVal sDisplayName As String = "name") As String
        Dim wOutputSrting As StringWriter = New StringWriter()
        Dim wHtml As HtmlTextWriter = New HtmlTextWriter(wOutputSrting)

        wHtml.RenderBeginTag(HtmlTextWriterTag.Select)

        wHtml.AddAttribute("name", sName)
        wHtml.AddAttribute("id", sName)

        For Each thing As Object In Itmes
            wHtml.RenderBeginTag(HtmlTextWriterTag.Option)
            wHtml.AddAttribute("value", thing.GetType().GetProperty(sValueName).GetValue(thing, Nothing).ToString())
            wHtml.Write(thing.GetType().GetProperty(sDisplayName).GetValue(thing, Nothing).ToString())
            wHtml.RenderEndTag()
        Next

        wHtml.RenderEndTag()

        Return wOutputSrting.ToString()
    End Function
End Module

现在,<%=Html.RenderSelect(Model)%>如果我愿意的话,我可以按照我的观点来称呼它。然后,如果实体模型对象没有“id”或“名称”属性,我可以像这样指定它们:

<%=Html.RenderSelect(Model, "nameofvalue", "nameofdisplay")%>
于 2009-08-14T20:22:55.347 回答