如何使用 ASP.NET Core 将查询字符串参数转换为看起来像目录部分?

Posted

技术标签:

【中文标题】如何使用 ASP.NET Core 将查询字符串参数转换为看起来像目录部分?【英文标题】:How can I convert query string parameters to look like a directory parts with ASP.NET Core? 【发布时间】:2020-11-23 22:51:19 【问题描述】:

我有一个在 ASP.NET Core 3.1 框架之上使用 C# 编写的应用程序。

通常,Http Get 请求会生成一个带有参数的 URL,看起来像这样

/for_sale/Virginia_Heights/WV?beds=3+&type=MULTI-FAMILY,SINGLE-FAMILY_HOME_type

但是,我想要一种方法将以前的 URL 转换为如下所示

/for_sale/Virginia_Heights/WV/3+_beds/MULTI-FAMILY,SINGLE-FAMILY_HOME_type

Trulia 在他们的网站上做了类似的事情(即https://www.trulia.com/for_sale/Virginia_Heights,WV/3p_beds/MULTI-FAMILY,SINGLE-FAMILY_HOME_type/)

如果您转到上一个 URL 并更改过滤器,您会注意到您选择的任何过滤器都会将该过滤器作为目录添加到 URL,而不添加 ?=... 查询参数。

我猜测 URL 生成和数据获取是在 javascript 的帮助下使用 AJAX 技术进行的。不是吗?或者,是否有更好的方法来处理 URL 生成?

我在这里苦苦挣扎的部分是在 ASP.NET Core 中构建一个灵活的路由来处理多个可选参数。

问题 如何在 ASP.NET Core 中创建一个路由,让我能够处理带有许多可选参数的请求,看起来像上面的示例?

【问题讨论】:

Trulia 似乎是一个单页应用程序,它通过 javascript 从位置栏中获取值。您会注意到它们是由斜线分隔的值-键对。所以它变成了单页...... javascript解析地址栏,用“/”分割,然后用“[下划线]”分割每个。您会注意到,如果您使用两个“__”,它将从位置栏中删除该变量。 Onhashchange 可能用作事件处理程序来向服务器发送请求。 您可以使用相同的策略并使用 Javascript 将 get/post 请求发送到不同的 ASP.NET 页面。您可以将 html 返回到请求或 JSON... 然后相应地填充您的单个页面。 (有一些东西需要修改才能让它工作,特别是如果你使用带有 renderbody 调用的布局......如果你要使用完整的 Ajax,你真的不想要那个......) 路由似乎是/for_sale/,后跟所有这些可选参数。如果您将 URL 复制/粘贴到不同的浏览器中,您会注意到所有过滤器都是自动选择的,这些过滤器在页面加载时由 javascript 处理。但是路由引擎如何路由这样的请求呢?如何创建一个路由 for_sale 允许我使用 / 传递尽可能多的参数 您基本上想关闭所有路由...我猜 trulia 只是在服务器级别执行此操作...所有传入请求都转到一个页面。然后,您有一个 onhashchange 函数,该函数在位置更改时触发,并且您在第一次加载时触发 hashchange。我猜他们使用“pushstate”来更改位置栏。我还没有尝试过,我通常只使用“#”将 URL 与查询变量分开。 其实再看Trulia网站,我觉得它只是部分单页网站。第一个值发生了一些路由......所以“/for_sale”、“/for_rent”和“/mortgages”。我认为这些是 3 条单独的路线/页面。我认为路径的其余部分没有路由,但是......那些被视为 onhashchange 的查询值。 【参考方案1】:

你必须像这样设置路线:

[Route("/for_sale/Virginia_Heights/WV/beds/type]
public IActionResult GetPropertyInfo(string beds, string type)

   // .....

/for_sale/Virginia_Heights/WV 当然不是答案的一部分。无论您的域和其他 url 结构是什么。

【讨论】:

在这种情况下 Virginia_HeightsWV 也将是参数。但是如果用户没有选择typebeds怎么办?说明这些是可选参数? @John 不,他们不是。这取决于您是否为控制器设置了基本路由,以及是否有其他文件夹,或者您只是想要一个不同的 url。 @John 检查this 的可选参数【参考方案2】:

可以通过编写如下控制器方法来完成。我们可以使用属性[FromRoute]指定beds和type参数来自路由。

[Route("/for_sale/Virginia_Heights,WV/beds/type]
public IActionResult GetPropertyInfo([FromRoute]string beds, [FromRoute]string type)

   // do something


We can also specify other model into it using [FromBody] atrribute.

[Route("/for_sale/Virginia_Heights,WV/beds/type]
public IActionResult GetPropertyInfo([FromRoute]string beds, [FromRoute]string type,[FromBody]Home model)

   // do something

【讨论】:

以上是关于如何使用 ASP.NET Core 将查询字符串参数转换为看起来像目录部分?的主要内容,如果未能解决你的问题,请参考以下文章