如何使用 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 将查询字符串参数转换为看起来像目录部分?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 ASP.NET Core 从查询字符串中读取值?

如何让 ASP.NET Core 支持绑定查询字符串中的数组

将数组传递到 ASP.NET Core 路由查询字符串

如何让 ASP.NET Core 支持绑定查询字符串中的数组

如何从 Asp.net Core 中的查询字符串验证 Azure AD B2C 令牌?

ASP.NET Core Web API - 如何处理 URL 查询字符串中的“null”与“undefined”?