代码之家  ›  专栏  ›  技术社区  ›  DrydenMaker

实体框架对象上MVC帮助程序中的动态对象属性

  •  1
  • DrydenMaker  · 技术社区  · 15 年前

    我刚接触到VB9和.NET MVC。我想构建一个MVC助手函数,为此我传递一个实体框架对象,并让它构建一个select。一般来说,我尝试过这样的方法:

    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
    

    但是,它不起作用。如果有一种方法可以做到这一点并传递当前实体对象,那就太好了。数据类型让我头疼。事先谢谢。

    3 回复  |  直到 15 年前
        1
  •  0
  •   CoderDennis    15 年前

    什么不起作用?你的代码运行吗?它是否生成字符串?

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

    编辑2: 得到 IDictionary(Of Object, String) 从您的ef对象,我将编写部分类实现,这些实现添加 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获取元素的字符串表示形式。

        2
  •  0
  •   DrydenMaker    15 年前

    好吧,所以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”或“name”属性,我可以这样指定它们:

    <%=Html.RenderSelect(Model, "nameofvalue", "nameofdisplay")%>
    
        3
  •  0
  •   DrydenMaker    15 年前

    如果vb看起来是冗长的自省,那么它的最大缺点就是它。如果您有一个具有属性名称的字符串,那么就没有好的方法来获取随机对象上该属性的值。要想使某件事奏效,就需要接触每门课。丹尼斯·帕尔默的方法可能是允许创建通用选择的最佳方法。

    所以我提出了一个问题:在未来的版本中,实体框架团队是否会为此构建一些有用的东西?