在MVC5控制器中,如何为HtmlHelper的htmlAttributes或routeValues创建IDictionary或routeValueDictionary?

问题描述 投票:0回答:1

MVC5

最终目标是在控制器中创建视图的链接,因为它们会根据程序逻辑进行更改。

以下链接编译并运行:

Dim myLink = HtmlHelper.GenerateLink(Request.RequestContext, RouteTable.Routes, "edit", "Default", "Edit", "Role", Nothing, Nothing)

上面的行生成:<a href=""/Role/Edit"">edit</a>。然后使用html.raw将其显示在视图中,并产生链接:http://localhost:53908/Role/Edit

上面显示的链接可以正确导航,但是由于我需要传递一个ID参数,因此不适用于action方法,因此我尝试如下更改辅助程序中的最后一个参数:

Dim myLink = HtmlHelper.GenerateLink(Request.RequestContext, RouteTable.Routes, "edit", "Default", "Edit", "Role", Nothing, New With {.ID = "somedata"})

但是上面的行返回语法警告,代码无法运行:

Runtime errors might occur when converting '<anonymous type: ID As String>' to 'IDictionary(Of String, Object)'

因此,我试图按如下方式创建IDictionary并传递给帮助器:

Dim temp As IDictionary(Of String, String)
temp.Add("ID", "somedata")
Dim myLink = HtmlHelper.GenerateLink(Request.RequestContext, RouteTable.Routes, "edit", "Default", "Edit", "Role", Nothing, temp)

上面的代码满足HtmlHelper,但是temp.Add行不起作用,因为:

temp is used before it has been assigned a value.

空引用异常在运行时发生。我对IDictionary并不特别了解,也无法弄清楚下一步该怎么做。

所以我有一系列问题:

  1. 有没有一种方法可以通过调用助手来“即时”创建助手所要求的[C0?
  2. 我应该以其他方式使用IDictionary方法吗?
  3. 如何创建HtmlHelper.GenerateLink

在原始帖子之后添加:

最初的问题涉及在Controller中创建就地IDictionary以利用HtmlHelpers,以便可以在代码中而不是在视图中完成链接的创建。总体目的是允许Controller代码执行必要的逻辑并计算链接,而不是在视图中执行。

最初提出的问题是偶然处理htmlAttributes的,因为在这种特殊情况下,真正的需要是创建routeValues。但是,下面的答案实际上有助于告知这两种方法。

成功的关键是使用适当的关键字。在创建New RouteValueDictionary或New IDictionary的情况下,必须使用New Dictionary(字符串,对象),这意味着关键字IDictionary是必需的,而关键字Object对于设置就地是必需的记录定义。在MVC5中,语法New Dictionary(Of String,From)被视为匿名类型,不能就地或以其他方式转换为IDictionary。

根据下面的答案,Controller在视图中用于设置等效ActionLink的最终代码是:

String

在上述情况下,第二个路由值已根据ActionResult方法的需要添加到routeValueDictionary。

如果还需要htmlAttributes,则可以添加它们,以代替上面的最终Dim editLink = HtmlHelper.GenerateLink(Request.RequestContext, RouteTable.Routes, "Edit", 'the link text "Default", 'a route name, can found in RouteConfig.vb "Edit", 'the target ActionResult method "Role", 'the target Controller New RouteValueDictionary(New Dictionary(Of String, Object) From {"ID", role.Id}, {"selectedDomain", selectedDomain}}), Nothing) 显示,如以下答案中所指定。

vb.net razor asp.net-mvc-5 html-helper
1个回答
1
投票

参数是类型Nothing。那只是一个接口,因此您需要创建一个实现该接口的类型的对象。显而易见的选择是IDictionary(Of String, Object),例如

Dictionary(Of String, Object)

我不记得何时在这种情况下开始支持匿名类型,但它似乎晚于MVC5。如果要使用匿名类型,则必须编写自己的接受匿名方法。类型,使用Reflection从中提取数据,构建字典,然后调用现有方法。您可能会这样:

Dim temp As IDictionary(Of String, Object) = New Dictionary(Of String, Object)
temp.Add("ID", "somedata")
Dim myLink = HtmlHelper.GenerateLink(Request.RequestContext, RouteTable.Routes, "edit", "Default", "Edit", "Role", Nothing, temp)

然后您可以像最初尝试的那样调用该方法:

Public Module HtmlHelperExtender

    Public Function GenerateLink(requestContext As RequestContext,
                                 routeCollection As RouteCollection,
                                 linkText As String,
                                 routeName As String,
                                 actionName As String,
                                 controllerName As String,
                                 routeValues As RouteValueDictionary,
                                 htmlAttributes As Object) As String
        'Create a dictionary from the properties of the anonymously typed object.
        Dim attributesType = htmlAttributes.GetType()
        Dim properties = attributesType.GetProperties()
        Dim htmlAttributesDictionary = properties.ToDictionary(Function(p) p.Name, Function(p) p.GetValue(htmlAttributes))

        Return HtmlHelper.GenerateLink(requestContext,
                                       routeCollection,
                                       linkText,
                                       routeName,
                                       actionName,
                                       controllerName,
                                       routeValues,
                                       htmlAttributesDictionary)
    End Function

End Module

我刚刚想到的另一种选择是坚持使用字典,但是就地创建并填充它,可以使用Dim myLink = HtmlHelperExtender.GenerateLink(Request.RequestContext, RouteTable.Routes, "edit", "Default", "Edit", "Role", Nothing, New With {.ID = "somedata"}) 关键字:

From
© www.soinside.com 2019 - 2024. All rights reserved.