带有RouteValueDictionary和Protocol的Url.Action

17

我已经看了一段时间,感觉自己有些愚蠢,希望能有更多的人帮忙看看。

我需要生成一个完整的URL(例如: http://www.domain.com/controller/action?a=1&b=2),通常我只需使用Url.Action来指定协议,没有任何问题:

var url = Url.Action("Action", "Controller", new { a = 1, b = 2 }, "http");

我已经开始编写一个类,返回一个RouteValueDictionary以消除这些匿名对象。然而,我无法使它与助手一起工作。

var x = Url.Action("Action", "Controller", new RouteValueDictionary(new { a = 1, b = 2 }), "http");
// "http://127.0.0.1/Controller/Action?Count=2&Keys=System.Collections.Generic.Dictionary%602%2BKeyCollection%5BSystem.String%2CSystem.Object%5D&Values=System.Collections.Generic.Dictionary%602%2BValueCollection%5BSystem.String%2CSystem.Object%5D",

var y = Url.Action("Action", "Controller", new { a = 1, b = 2 }, "http");
// "http://127.0.0.1/Controller/Action?a=1&b=2"

非常感谢任何能带来"facepalm"(手掌自我打击)效果的指点 :)

更新:

最好澄清一下,在上面的示例中,我需要正确使用'X'变量,因为RouteValueDictionary在代码其他地方创建。假设RouteValueDictionary是正确的。

我只是不明白为什么使用匿名对象可以正常工作,但是将同一对象包装在RouteValueDictionary中就会使助手程序出错。


你是如何实际创建RouteValueDictionary的? - Oliver
2个回答

15

有趣的是,看起来你的特定示例匹配的方法签名使用 "object" 作为属性而不是 RouteValueDictionary。因此,它只是将类型名称 ToString() 出来,而没有正确地序列化 RouteValueDictionary。

 var x = Url.Action("Index", "Home", new RouteValueDictionary(new { a = 1, b = 2 }), "http", string.Empty);

注意在末尾添加 "string.Empty"

这足以强制代码使用不同的重载方法,该方法接受RouteValueDictionary并因此正确地进行序列化。

// http://localhost:55110/?a=1&b=2

1
他正在使用的重载期望一个对象,而大多数其他重载期望一个RouteValueDictionary,请参见我的答案。 - Oliver
有趣的是,您还可以将string.Empty添加为主机参数以获得您要查找的输出。 - DavidWhitney
好的,这真的让我感到困惑,string.Empty 起作用并且比每次都要使用 RequestContext 稍微好一点。 - Rob Cooper
请看我的编辑,有一个使用 string.Empty 的替代方法。奇怪的是这些重载在一开始就被创建成这样... - Oliver
2
提交了一个拉取请求,为vNext队列添加缺失的重载:http://aspnetwebstack.codeplex.com/SourceControl/network/forks/davidwhitney/aspnetwebstack/contribution/4236#!/tab/comments - DavidWhitney
显示剩余2条评论

5
您使用的重载函数期望参数类型为 "object",而您正在传递RouteValueDictionary。由于某种原因,这导致了问题,可能与.ToString()有关?请使用接受RouteValueDictionary的重载函数,这样应该可以解决问题。
为了测试这个问题,添加hostName参数以选择如下所示的重载函数: Correct overload 编辑:
您可以在项目中使用此扩展程序向Url.Action添加所需的重载函数。内部将从请求中解析并添加hostName。
public static string Action
    (this UrlHelper helper, string action, 
     string controller, RouteValueDictionary routeValues, string protocol)
{
     string hostName = helper.RequestContext.HttpContext.Request.Url.Host;
     return helper.Action(action, controller, routeValues, protocol, hostName);
}

谢谢,但不幸的是这对我没有帮助——因为匿名对象创建仍然是内联的——这已经被移动到其他地方以消除重复。我需要知道问题中的“X”变量为什么是错误的。 - Rob Cooper
匿名对象创建是在你的x示例中内联的吗?你省略了你正在使用的方法调用吗? - Oliver
我已经更新了以澄清 - “X”变量正在使用RouteValueDictionary - 假设它在代码的其他地方创建。这只是为了使重现案例更容易。 - Rob Cooper
我需要协议参数来强制助手生成完整的URL。否则,你只会得到路径(URL将进入电子邮件,所以我们需要整个URL)。 - Rob Cooper
1
很高兴!可惜一开始没有在框架中 :( - Oliver
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接