首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用ASP.NET Web创建基于路由的模板化hrefs

使用ASP.NET Web创建基于路由的模板化hrefs
EN

Stack Overflow用户
提问于 2014-09-22 18:45:22
回答 1查看 834关注 0票数 1

在Web控制器中添加到资源表示的链接非常容易。使用控制器的Url属性(属于UrlHelper类),您可以使用路由名称构建链接的href,如下所示:

代码语言:javascript
运行
复制
var href = Url.Link("RouteName", new { id = 123 });

href的值是根据路由配置计算的--在本例中,类似于http://example.org/api/products/123。这是很棒的,因为我可以调整路由配置,而不需要更新所有生成的地方。所有发出的链接都符合新的配置。

但是,这一技术,或者任何类似的基于路由的技术,能被用来创建模板化的 hrefs吗?例如,要使用HAL的templated链接属性创建从某些资源到任意产品的链接:

代码语言:javascript
运行
复制
"_links": {
  "self": {
    "href": "http://example.org/api/productfinder"
  },
  "product": {
    "href": "http://example.org/api/products/{productId}",
    "templated": true
  }  
}

(我真的没有一个叫做productfinder的资源-只是这个问题的一个人为的例子)。

我尝试将routeValues参数设置为模板的字符串。

代码语言:javascript
运行
复制
var href = Url.Link("RouteName", new { id = "{productId}" });

这会产生一个URL编码的字符串:http://example.org/api/products/%7BproductId%7D。我可以使用.Replace,但由于另一个原因,这种方法失败了。如果路由配置具有类型约束,例如{id:int},则href变为空。

我试着将null传递给routeValues,希望能够添加模板部分。Link()返回null,因此href最终只是模板部分。另外,对于像api/{this}/something/{that}{?q}这样复杂的线路,这是行不通的。

所以我卡住了。我可以使用路线来生成模板化的参考资料吗?如果是这样的话,是怎么做的?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-09-24 21:19:56

好吧,我花了一段时间,但我有一些有用的东西。诀窍是从配置的路由表中查找RouteTemplate。每个控制器都有一个对配置的引用。从那里开始很容易。

我为ApiController创建了一个扩展类。实际上,我可能会对ApiController进行子类处理,但想法是相同的。另外,我可以返回Uri对象,而不是使用.ToString()

代码语言:javascript
运行
复制
public static class ApiControllerExtensions
{
    public static string GetTemplatedHref(this ApiController controller, string routeName, string controllerName = "")
    {
        var routeTemplate = controller.Configuration.Routes[routeName].RouteTemplate;

        var baseUri = new Uri(controller.Request.RequestUri.GetLeftPart(UriPartial.Authority));
        var templatedHref = new Uri(baseUri, routeTemplate).ToString();

        return string.IsNullOrEmpty(controllerName) ? 
            templatedHref : 
            templatedHref.Replace("{controller}", controllerName.ToLower());
    }
}

现在,当在控制器的方法中,我需要一个模板的href时,我可以这样做:

代码语言:javascript
运行
复制
var href = this.GetTemplatedHref("RouteName");

这与路由属性一起工作得很好。它也适用于预先配置的路由,例如:

代码语言:javascript
运行
复制
config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );

因此,我可以提供控制器名称,并获得如下模板化的href:

代码语言:javascript
运行
复制
var href = this.GetTemplatedHref("DefaultApi", "product");

在实践中,我将再次修改和调整,例如添加绝对/相对选项等。但是,使用路由名称获取模板的核心问题现在已经解决了。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25981084

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档