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");

我已经开始整理一个返回 a 的类,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 是正确的。

我只是不明白为什么这适用于匿名对象,但是包裹在同一对象中的同一对象包裹在 aRouteValueDictionary中使助手吓坏了。

4

2 回答 2

15

有趣的是,您的具体示例似乎与将“对象”作为属性而不是 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
于 2013-03-15T13:56:38.793 回答
5

您正在使用的重载需要类型“object”作为您传递RouteValueDictionary. 出于某种原因,这导致了问题,可能与 .ToString() 有关?使用接受 a 的重载,RouteValueDictionary这应该可以工作。

要对此进行测试,请添加一个 hostName 参数来选择如下所示的重载:

正确的过载

编辑

您可以在您的项目中使用此扩展来将所需的重载添加到 Url.Action。在内部,它将解析并从请求中添加主机名。

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);
}
于 2013-03-15T13:10:28.237 回答