带有Protocol的RouteValueDictionary的Url.Action

时间:2013-03-15 13:00:18

标签: asp.net-mvc

已经看了一会儿,觉得我只是愚蠢想要多看一眼......

我需要生成一个完整的网址(例如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中的同一对象中包含的同一对象会让帮助器变得怪异。

2 个答案:

答案 0 :(得分:13)

有趣的是,看起来您的具体示例是匹配将“object”作为属性而不是RouteValueDictionary的方法签名。因此,它只是ToString()输出typename,而不是正确序列化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 :(得分:5)

您正在使用的重载需要为传递RouteValueDictionary的参数键入“object”。由于某些原因,这导致了问题,可能与.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);
}