带有Protocol的RouteValueDictionary的Url.Action

Rob*_*per 15 asp.net-mvc

一直在看这个,觉得我只是愚蠢想要更多的目光...

我需要生成一个完整的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");
Run Code Online (Sandbox Code Playgroud)

我已经开始组建一个返回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"
Run Code Online (Sandbox Code Playgroud)

任何导致facepalm的指针都非常感谢:)

更新:

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

我只是不明白为什么这适用于匿名对象,但包裹在同一对象中的相同对象包含在一个RouteValueDictionary帮助器中.

Dav*_*ney 13

有趣的是,看起来您的具体示例是匹配将"object"作为属性而不是RouteValueDictionary的方法签名.因此,它只是ToString()输出typename,而不是正确序列化RouteValueDictionary

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

最后注意"string.Empty".

这足以强制代码使用不同的重载,接受RouteValueDictionary,因此,正确序列化.

// http://localhost:55110/?a=1&b=2
Run Code Online (Sandbox Code Playgroud)

  • 删除拉取请求以在队列中为vNext添加缺少的重载:http://aspnetwebstack.codeplex.com/SourceControl/network/forks/davidwhitney/aspnetwebstack/contribution/4236#!/tab/comments (2认同)

Oli*_*ver 5

您正在使用的重载期望为您传递的参数键入"object" RouteValueDictionary.由于某些原因,这导致了问题,可能与.ToString()有关.使用接受a的重载,RouteValueDictionary这应该工作.

要测试这个,请添加一个hostName参数以选择下面显示的重载:

正确的过载

编辑

您可以在项目中使用此扩展名来向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);
}
Run Code Online (Sandbox Code Playgroud)