我需要在ASP.NET MVC模型中生成一些URL。我想调用类似于UrlHelper.Action()的方法来使用路由生成URL。我不介意填写通常的空白,比如主机名、协议等。
有没有可以调用的方法?有没有构建UrlHelper的方法?
有没有可以调用的方法?有没有构建UrlHelper的方法?
在任何 ASP.NET 应用程序中,有一个有用的提示:您可以获取当前 HttpContext 的引用。
HttpContext.Current
这是从System.Web中派生出来的。因此,以下内容在ASP.NET MVC应用程序中的任何地方都可以正常工作:
UrlHelper url = new UrlHelper(HttpContext.Current.Request.RequestContext);
url.Action("ContactUs"); // Will output the proper link according to routing info
例子:
public class MyModel
{
public int ID { get; private set; }
public string Link
{
get
{
UrlHelper url = new UrlHelper(HttpContext.Current.Request.RequestContext);
return url.Action("ViewAction", "MyModelController", new { id = this.ID });
}
}
public MyModel(int id)
{
this.ID = id;
}
}
在创建了一个 MyModel 对象后,调用其 Link
属性会返回基于 Global.asax 中路由信息的用于查看该模型的有效 URL。
using
同时包括System.Web
和System.Web.Mvc
。 - Omar我喜欢Omar的答案,但对我没用。只是为了记录,这是我现在正在使用的解决方案:
var httpContext = HttpContext.Current;
if (httpContext == null) {
var request = new HttpRequest("/", "http://example.com", "");
var response = new HttpResponse(new StringWriter());
httpContext = new HttpContext(request, response);
}
var httpContextBase = new HttpContextWrapper(httpContext);
var routeData = new RouteData();
var requestContext = new RequestContext(httpContextBase, routeData);
return new UrlHelper(requestContext);
可以通过以下方式在控制器操作中构建UrlHelper:
var url = new UrlHelper(this.ControllerContext.RequestContext);
url.Action(...);
在控制器之外,可以通过从RouteTable.Routes RouteData创建一个RequestContext来构建UrlHelper。
HttpContextWrapper httpContextWrapper = new HttpContextWrapper(System.Web.HttpContext.Current);
UrlHelper urlHelper = new UrlHelper(new RequestContext(httpContextWrapper, RouteTable.Routes.GetRouteData(httpContextWrapper)));
(基于Brian的回答,稍作代码纠正后。)
var urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
翻译为中文: - bradlis7this.ControllerContext.RequestContext
是一个HttpRequestContext
,而UrlHelper
的构造函数需要一个RequestContext
。这两个类没有关联。 - Florian Winter可以实例化它。您可以执行类似以下内容的操作:
var ctx = new HttpContextWrapper(HttpContext.Current);
UrlHelper helper = new UrlHelper(
new RequestContext(ctx,
RouteTable.Routes.GetRouteData(ctx));
RouteTable.Routes
是一个静态属性,所以你不用担心;要获取HttpContextBase
引用,可以使用HttpContextWrapper
来获取对HttpContext
的引用,然后HttpContext
就可以提供它。
在尝试了所有其他答案后,我最终得到了
$"/api/Things/Action/{id}"
[HttpPost]
[Route("format-url")]
public ActionResult FormatUrl()
{
string action = null;
string controller = null;
string protocol = null;
dynamic parameters = null;
foreach (var key in this.Request.Form.AllKeys)
{
var value = this.Request.Form[key];
if (key.Similar("action"))
{
action = value;
}
else if (key.Similar("controller"))
{
controller = value;
}
else if (key.Similar("protocol"))
{
protocol = value;
}
else if (key.Similar("parameters"))
{
JObject jObject = JsonConvert.DeserializeObject<dynamic>(value);
var dict = new Dictionary<string, object>();
foreach (var item in jObject)
{
dict[item.Key] = item.Value;
}
parameters = AnonymousType.FromDictToAnonymousObj(dict);
}
}
if (string.IsNullOrEmpty(action))
{
return new ContentResult { Content = string.Empty };
}
int flag = 1;
if (!string.IsNullOrEmpty(controller))
{
flag |= 2;
}
if (!string.IsNullOrEmpty(protocol))
{
flag |= 4;
}
if (parameters != null)
{
flag |= 8;
}
var url = string.Empty;
switch (flag)
{
case 1: url = this.Url.Action(action); break;
case 3: url = this.Url.Action(action, controller); break;
case 7: url = this.Url.Action(action, controller, protocol); break;
case 9: url = this.Url.Action(action, parameters); break;
case 11: url = this.Url.Action(action, controller, parameters); break;
case 15: url = this.Url.Action(action, controller, parameters, protocol); break;
}
return new ContentResult { Content = url };
}
作为一个操作,您可以从任何地方请求它,甚至在中心内部:
var postData = "action=your-action&controller=your-controller";
// Add, for example, an id parameter of type integer
var json = "{\"id\":3}";
postData += $"¶meters={json}";
var data = Encoding.ASCII.GetBytes(postData);
#if DEBUG
var url = $"https://localhost:44301/format-url";
#else
var url = $"https://your-domain-name/format-url";
#endif
var request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/text/plain";
request.ContentLength = data.Length;
using (var stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
var response = (HttpWebResponse)request.GetResponse();
var link = new StreamReader(stream: response.GetResponseStream()).ReadToEnd();
我曾试图在页面内(控制器之外)执行类似的操作。
UrlHelper并没有像Pablo的答案那样轻松地让我构建它,但是我想起了一个旧技巧来有效地完成同样的事情:
string ResolveUrl(string pathWithTilde)
我想你要找的是这个:
Url.Action("ActionName", "ControllerName");