在 ASP.NET MVC 的模型中调用 UrlHelper
我需要在 ASP.NET MVC 的模型中生成一些 URL。我想调用类似 UrlHelper.Action() 的方法,它使用路由来生成 URL。我不介意填写常见的空白,例如主机名、方案等。
我可以调用任何方法吗?有没有办法构造一个UrlHelper?
I need to generate some URLs in a model in ASP.NET MVC. I'd like to call something like UrlHelper.Action() which uses the routes to generate the URL. I don't mind filling the usual blanks, like the hostname, scheme and so on.
Is there any method I can call for that? Is there a way to construct an UrlHelper?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
发布评论
评论(8)
我喜欢奥马尔的回答,但这对我不起作用。仅供记录,这是我现在使用的解决方案:
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);
可以通过以下方式从 Controller 操作内部构造 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 ctx = new HttpContextWrapper(HttpContext.Current);
UrlHelper helper = new UrlHelper(
new RequestContext(ctx,
RouteTable.Routes.GetRouteData(ctx));
RouteTable.Routes
是一个静态属性,所以你应该没问题;为了获取 HttpContextBase
引用,HttpContextWrapper
获取对 HttpContext
的引用,然后 HttpContext
传递该引用。
之前的回复对我没有帮助。我的方法是在我的 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 };
}
作为一个操作,您可以从任何地方请求它,甚至在 Hub 内部:
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();
您可以获取 AnonymousType 的源代码 此处。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
当前 HttpContext 的引用
有用的提示,在任何 ASP.NET 应用程序中,您都可以获取派生自 System.Web 的 。因此,以下内容将在 ASP.NET MVC 应用程序中的任何位置工作:
示例:
在创建的 MyModel 对象上调用
Link
属性将返回有效的 Url,以根据 Global.asax 中的路由查看模型Helpful tip, in any ASP.NET application, you can get a reference of the current HttpContext
which is derived from System.Web. Therefore, the following will work anywhere in an ASP.NET MVC application:
Example:
Calling the
Link
property on a created MyModel object will return the valid Url to view the Model based on the routing in Global.asax