在 ASP.NET MVC 模型中调用 UrlHelper

我需要在 ASP.NET MVC 中的模型中生成一些 URL。我想叫做 UrlHelper。Action () ,它使用路由来生成 URL。我不介意填补通常的空白,如主机名,方案等。

有什么方法可以调用吗? 有没有构造 UrlHelper 的方法?

95414 次浏览

我觉得你要找的是这个:

Url.Action("ActionName", "ControllerName");

可以从 Controller 操作中构造 UrlHelper,具有以下内容:

 var url = new UrlHelper(this.ControllerContext.RequestContext);
url.Action(...);

在控制器之外,可以通过从 RouteTable.RouteData 创建 RequestContext 来构造 UrlHelper。

HttpContextWrapper httpContextWrapper = new HttpContextWrapper(System.Web.HttpContext.Current);
UrlHelper urlHelper = new UrlHelper(new RequestContext(httpContextWrapper, RouteTable.Routes.GetRouteData(httpContextWrapper)));

(根据布莱恩的回答,添加了一个小的代码更正。)

是的,您可以实例化它。您可以这样做:

var ctx = new HttpContextWrapper(HttpContext.Current);
UrlHelper helper = new UrlHelper(
new RequestContext(ctx,
RouteTable.Routes.GetRouteData(ctx));

RouteTable.Routes是一个静态属性,因此在那里应该没问题; 要获得 HttpContextBase引用,HttpContextWrapper引用 HttpContext,而 HttpContext提供这个引用。

有用的提示,在任何 ASP.NET 应用程序中,您都可以获得当前 HttpContext 的引用

HttpContext.Current

因此,下面的代码可以在 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属性将返回有效的 Url,以根据 Global.asax 中的路由查看 Model

我喜欢奥马尔的回答,但我不喜欢。顺便说一句,这是我现在使用的解决方案:

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 不允许我像 Pablos 回答那样简单地构造它,但后来我想起了一个有效做同样事情的老技巧:

string ResolveUrl(string pathWithTilde)

在尝试了所有其他的答案之后,我得到了

$"/api/Things/Action/{id}"

憎恨者将憎恨 _ (ツ) _/

之前的回答对我没有帮助。我的方法是在 Home 控制器中创建一个动作,其功能与 UrlHelper 相同。

    [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 += $"&parameters={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();

你可以得到匿名类型 给你的源代码。