【问题标题】:Dynamic Object Properties in a MVC Helper on a Entity Framework object实体框架对象上的 MVC 助手中的动态对象属性
【发布时间】:2009-07-20 19:09:40
【问题描述】:

我是 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

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

【问题讨论】:

  • 也许你可以先阅读编译器错误...
  • 实际上,我更容易帮助您识别真实代码的问题。你的伪代码看起来不错。

标签: asp.net-mvc vb.net entity-framework html-helper


【解决方案1】:

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

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

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

编辑:我会这样做。让您的调用代码负责从您的 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 来获取元素的字符串表示形式。

【讨论】:

  • 太好了,这就是我想做的,但我没有字典。我实际上从一个实体框架对象开始,我想通过字符串指定对象属性,所以我可以执行以下操作:跨度>
  • 我确实喜欢 Xhtml 元素方法,但它们都要求您传递字典,这需要我对对象进行预处理。这将使我回到基本问题。我有一个带有属性的对象,以及一个带有我想要的属性名称的字符串。 VB中是否可以从对象中获取值?
【解决方案2】:

好的,所以 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

现在,如果我愿意,我可以将其称为 &lt;%=Html.RenderSelect(Model)%&gt;。然后,如果实体模型对象没有“id”或“名称”属性,我可以像这样指定它们:

<%=Html.RenderSelect(Model, "nameofvalue", "nameofdisplay")%>

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 2015-08-27
      • 1970-01-01
      • 2011-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多