这个问题在这里已经有了答案:How do I find the absolute url of an action in ASP.NET MVC? (9 个回答) 4 年前关闭。
是否有获取操作的完整 URL 的内置方法?
我正在寻找类似 GetFullUrl("Action", "Controller")
的东西,它会返回类似 http://www.fred.com/Controller/Action
的东西。
我正在寻找这个的原因是避免在生成的自动电子邮件中对 URL 进行硬编码,以便始终可以相对于站点的当前位置生成 URL。
Url.Action 有一个重载,它将您想要的协议(例如 http、https)作为参数 - 如果您指定它,您将获得一个完全限定的 URL。
这是一个在 action 方法中使用当前请求协议的示例:
var fullUrl = this.Url.Action("Edit", "Posts", new { id = 5 }, this.Request.Url.Scheme);
HtmlHelper (@Html) 还具有 ActionLink 方法的重载,您可以在 razor 中使用该方法来创建锚元素,但它还需要 hostName 和 fragment 参数。所以我会选择再次使用@Url.Action:
<span>
Copy
<a href='@Url.Action("About", "Home", null, Request.Url.Scheme)'>this link</a>
and post it anywhere on the internet!
</span>
正如 Paddy 所述:如果您使用 UrlHelper.Action()
的重载来明确指定要使用的协议,则生成的 URL 将是绝对的和完全限定的,而不是相对的。
我写了一篇名为 How to build absolute action URLs using the UrlHelper class 的博客文章,为了便于阅读,我建议在其中编写自定义扩展方法:
/// <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);
}
然后,您可以像在视图中那样简单地使用它:
@Url.AbsoluteAction("Action", "Controller")
UrlHelper.Action
方法之外没有做任何其他事情。
这是你需要做的。
@Url.Action(action,controller, null, Request.Url.Scheme)
这个问题是 ASP .NET 特有的,但是我相信你们中的一些人会受益于与系统无关的 javascript,这在许多情况下都是有益的。
更新:在页面本身之外形成 url 的方法在上面的答案中有很好的描述。
或者你可以做一个如下的oneliner:
new UrlHelper(actionExecutingContext.RequestContext).Action(
"SessionTimeout", "Home",
new {area = string.Empty},
actionExecutingContext.Request.Url!= null?
actionExecutingContext.Request.Url.Scheme : "http"
);
从过滤器或:
new UrlHelper(this.Request.RequestContext).Action(
"Details",
"Journey",
new { area = productType },
this.Request.Url!= null? this.Request.Url.Scheme : "http"
);
然而,经常需要获取当前页面的 url,对于那些使用 Html.Action
并将他的名称和页面控制器放在我来说感觉很尴尬的情况。在这种情况下,我的偏好是改用 JavaScript。这在一半重写 MVT 一半 web-forms 一半 vb-script 一半天知道是什么的系统中特别好 - 并且要获取当前页面的 URL,每次都需要使用不同的方法。
一种方法是使用 JavaScript 获取 URL,另一种方法是 window.location.href
- document.URL
我遇到了这个问题,我的服务器在负载均衡器后面运行。负载平衡器正在终止 SSL/TLS 连接。然后它使用 http 将请求传递给 Web 服务器。
使用带有 Request.Url.Schema 的 Url.Action() 方法,它不断创建一个 http url,在我的例子中是在自动电子邮件中创建一个链接(我的 PenTester 不喜欢它)。
我可能有点作弊,但这正是我强制使用 https url 所需要的:
<a href="@Url.Action("Action", "Controller", new { id = Model.Id }, "https")">Click Here</a>
我实际上使用了 web.config AppSetting,因此我可以在本地调试时使用 http,但所有测试和生产环境都使用转换来设置 https 值。
Request.Url.Schema
使用“当前请求”的架构来确定 HTTP 与 HTTPS。如果您的锚标记是由 HTTP 请求生成的,那么架构将不是 HTTPS。硬编码一个安全协议似乎很好;我不认为这样做是“作弊”,我很惊讶其他答案没有承认将 Request.Url.Schema
用于同时提供 HTTP 和服务的网站。 HTTPS 资源可能是个问题。如果协议需要在不同的环境中有所不同,App Settings / Web Config 可能是要走的路。
这可能只是我真的非常挑剔,但我喜欢只定义一次常量。如果您使用上面定义的任何方法,您的操作常量将被定义多次。
为避免这种情况,您可以执行以下操作:
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:
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);
}
然后像这样使用它:
// GET: Data/Cat
[ActionName(ControllerRoutes.DataController.CatAction)]
public ActionResult Etisys()
{
return View();
}
并从您的 .cshtml (或任何代码)
<ul>
<li><a href="@ControllerRoutes.Data.Dog">Dog</a></li>
<li><a href="@ControllerRoutes.Data.Cat">Cat</a></li>
</ul>
这绝对是更多的工作,但我很容易知道编译时验证在我身边。
https://127.0.0.1/Home/Index
,但它会生成https://127.0.0.1:444/Home/Index
。它必须没有端口。我在 Azure 模拟器上运行。请帮忙。<a href="@Url.Action("Login", "Account", null, Context.Request.Scheme)">Log in</a>