【问题标题】:How to validate query string parameters in GET method如何在 GET 方法中验证查询字符串参数
【发布时间】:2018-07-28 09:13:41
【问题描述】:

我已经构建了一个 ASP.NET Core MVC 应用程序并且我使用了默认的 MVC URL 路由:

app.UseMvc(routes =>
{
    routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
});

我想创建GET 方法来创建和编辑用户。

要创建新用户,我需要转到 url /Admin/User 并编辑现有用户 url /Admin/User/{id:int}

我尝试过创建这样的方法:

[HttpGet]
public async Task<IActionResult> User(int? id)
{
}

如何限制 id 参数的类型?

我只需要允许访问 /Admin/User/Admin/User/{id:int} - 但如果我尝试即 - /Admin/User/ABCD - (使用字符串作为 ID) - 它也是允许的。

如果参数 ID 将是另一种类型而不是数字,那么我想返回 404

【问题讨论】:

    标签: c# asp.net-mvc asp.net-core asp.net-core-mvc asp.net-mvc-routing


    【解决方案1】:

    最简单的选择是创建具有此约束的路由。请注意,如果您像这样在路由中设置所需的参数,则没有理由将id 设置为可空。

    [HttpGet("Admin/User")]
    public async Task<IActionResult> Add()
    {
    }
    
    [HttpGet("Admin/User/{id:int}")]
    public async Task<IActionResult> Edit(int id) 
    {
    }
    

    或者保留名为User的操作方法并使用:

    app.UseMvc(routes =>
    {
        routes.MapRoute("AdminUser", "Admin/User/{id:int}");
        routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
    });
    

    请注意,基于约定的方法不区分 GET/POST。

    或者,如果您想将所有 ID 参数设为 int,您可以像这样为整个站点配置路由:

    routes.MapRoute(
        name: "defaultWithId",
        template: "{controller}/{action}/{id:int}");
    routes.MapRoute(
        name: "default",
        template: "{controller=Home}/{action=Index}");
    

    参考:Routing in ASP.NET Core

    【讨论】:

    • 如何创建视图来创建新用户?出于这个原因,我想创建可以为空的 ID。
    • 最好使用一种操作方法进行创建,另一种操作方法进行编辑——关注点分离。所有这些路由配置都涵盖了这一点。
    【解决方案2】:

    您必须为此编写自定义模型绑定器,或者为返回 404 的所有其他类型创建重载。我会简单地重新考虑您的设计,并使用不同的 /Admin/CreateUser 操作来创建新用户,然后只是不允许用户在没有 ID 的情况下调用。

    【讨论】:

    • 我对这些类型的操作使用了单一视图 - 用于创建和编辑 - 是否可以像你提到的那样创建两种类型的方法 - /Admin/CreateUser 和 /Admin/EditUser 并使用相同的视图?
    • 是的,可以使用相同的方法 names 但不同的 arguments(不同的签名)
    • @Jenan 您可以在调用 View 时简单地通过指定视图的名称来使用相同的视图,例如。 - 返回视图(“视图名称”,模型对象);在两个动作中只需使用相同的视图名称
    • 谢谢 - 相同的方法名称是什么意思?
    【解决方案3】:

    可以使用单一方法实现。

    如果您使用数字 ID,则现有用户 ID 将大于零。对于新用户 ID 将为零或小于零。

    如果您使用的是字符串 id,那么对于现有用户,id 将是非空字符串。例如。 A B C D。对于新用户 ID 将为空。

    基于此逻辑,您可以发送适当的响应或 404 响应。 如果您使用的是字符串 ID,则更改 Get 方法的数据类型。而不是使用可为空的 int 使用字符串。

    以下代码可能会有所帮助

    [HttpGet("{id}")]
        public async Task<IActionResult> User(string id)
        {
            if (string.IsNullOrWhiteSpace(id))
            {
                //Replace NewUser view name by Appropriate View name in your project
                return View("NewUser");
            }
            else
            {
               var isValidUser= IsValidUser(id);
                if(isValidUser)
                {
                    //Replace ExistingUser view name by Appropriate View name in your project
                    return View("ExistingUser");
                }
                else
                {
                    //User Appropriate overload of NotFound
                    return NotFound();
                }
            }
        }
        private bool IsValidUser(string userId)
        {
            //Your logic to validate the existing user.            
        }
    

    【讨论】:

    • 你能修改这个ID类型整数的用户方法吗?出于这个原因,我使用了可为空的 ID 参数。
    猜你喜欢
    • 1970-01-01
    • 2021-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-23
    • 2011-04-15
    • 2016-07-07
    • 2020-01-08
    相关资源
    最近更新 更多