Getting full URL of action in ASP.NET MVC
是否有一种内置的方式来获取操作的完整URL?
我在找一些像
我寻找这个的原因是为了避免在自动生成的电子邮件中对URL进行硬编码,这样就可以始终相对于站点的当前位置生成URL。
有一个url.action的重载,它将您所需的协议(如http、https)作为参数-如果指定此参数,您将得到一个完全限定的url。
下面是一个在操作方法中使用当前请求的协议的示例:
1 |
htmlhelper(@html)还具有ActionLink方法的重载,您可以在Razor中使用该方法来创建锚元素,但它还需要主机名和片段参数。所以我选择再次使用@url.action:
1 2 3 4 5 | <span> Copy this link and post it anywhere on the internet! </span> |
正如Paddy所提到的:如果使用一个明确指定要使用的协议的
我写了一篇名为"如何使用urlhelper类构建绝对操作URL"的博客文章,我建议在其中编写一个自定义扩展方法,以提高可读性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | /// <summary> /// Generates a fully qualified URL to an action method by using /// the specified action name, controller name and route values. /// </summary> /// <param name="url">The URL helper.</param> /// <param name="actionName">The name of the action method.</param> /// <param name="controllerName">The name of the controller.</param> /// <param name="routeValues">The route values.</param> /// <returns>The absolute URL.</returns> public static string AbsoluteAction(this UrlHelper url, string actionName, string controllerName, object routeValues = null) { string scheme = url.RequestContext.HttpContext.Request.Url.Scheme; return url.Action(actionName, controllerName, routeValues, scheme); } |
然后您可以像在视图中那样简单地使用它:
1 | @Url.AbsoluteAction("Action","Controller") |
我有一个问题,我的服务器在负载均衡器后面运行。负载平衡器正在终止SSL/TLS连接。然后,它使用HTTP将请求传递给Web服务器。
使用带有request.url.schema的url.action()方法,它不断地创建一个HTTP URL,在我的例子中,它在自动电子邮件中创建一个链接(我的pentester不喜欢)。
我可能有点作弊,但这正是我强制使用https URL所需要的:
1 | Click Here |
实际上,我使用web.config appsetting,以便在本地调试时使用HTTP,但所有测试和prod环境都使用转换来设置https值。
这就是你需要做的。
1 | @Url.Action(action,controller, null, Request.Url.Scheme) |
这可能只是我非常,非常挑剔,但我只喜欢定义一次常量。如果您使用上面定义的任何方法,您的操作常量将被定义多次。
要避免这种情况,可以执行以下操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | public class Url { public string LocalUrl { get; } public Url(string localUrl) { LocalUrl = localUrl; } public override string ToString() { return LocalUrl; } } public abstract class Controller { public Url RootAction => new Url(GetUrl()); protected abstract string Root { get; } public Url BuildAction(string actionName) { var localUrl = GetUrl() +"/" + actionName; return new Url(localUrl); } private string GetUrl() { if (Root =="") { return""; } return"/" + Root; } public override string ToString() { return GetUrl(); } } |
然后创建控制器,例如DataController:
1 2 3 4 5 6 7 8 9 10 11 12 13 | public static readonly DataController Data = new DataController(); public class DataController : Controller { public const string DogAction ="dog"; public const string CatAction ="cat"; public const string TurtleAction ="turtle"; protected override string Root =>"data"; public Url Dog => BuildAction(DogAction); public Url Cat => BuildAction(CatAction); public Url Turtle => BuildAction(TurtleAction); } |
然后像这样使用它:
1 2 3 4 5 6 | // GET: Data/Cat [ActionName(ControllerRoutes.DataController.CatAction)] public ActionResult Etisys() { return View(); } |
以及来自.cshtml(或任何代码)的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <ul> <li> Dog </li> <li> Cat </li> </ul> |
这肯定是更多的工作,但我很容易知道编译时验证在我这边。
这个问题是针对ASP.NET的,但是我相信你们中的一些人会受益于系统不可知的javascript,这在许多情况下都是有益的。
更新:获取在页面本身之外形成的URL的方法在上面的答案中有很好的描述。
或者你可以做如下的一行:
1 2 3 4 5 6 |
从过滤器或:
1 2 3 4 5 6 |
然而,经常需要得到当前页面的URL,对于那些使用
一种方法是使用javascript获取URL,它是