Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/rest/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 通过核心Web API中的可选参数删除多个记录的最佳实践是什么?_C#_Rest_Asp.net Core_Asp.net Web Api - Fatal编程技术网

C# 通过核心Web API中的可选参数删除多个记录的最佳实践是什么?

C# 通过核心Web API中的可选参数删除多个记录的最佳实践是什么?,c#,rest,asp.net-core,asp.net-web-api,C#,Rest,Asp.net Core,Asp.net Web Api,我正在为一个应用程序创建一个web API,我有一个资源的DELETE操作。该资源是名称,所有这些名称都位于SQL名称表中。每个名称都有一个记录的外键(全部在记录表中),每个记录都有一个文件名,是有效的列 这意味着我可以通过FileName、IsValid或这些值的组合来删除一组名称。这正是将使用API的应用程序所需要的 然而,在我看到的所有API DELETE端点示例中,它们总是按id删除一条记录,这让我怀疑我的方法是否被认为是最佳实践 这也提出了一个问题,我该如何做我想做的事情?目前,我的D

我正在为一个应用程序创建一个web API,我有一个资源的
DELETE
操作。该资源是
名称
,所有这些名称都位于SQL
名称
表中。每个名称都有一个
记录
的外键(全部在
记录
表中),每个
记录
都有一个
文件名
是有效的

这意味着我可以通过
FileName
IsValid
或这些值的组合来删除一组
名称。这正是将使用API的应用程序所需要的

然而,在我看到的所有API DELETE端点示例中,它们总是按
id
删除一条记录,这让我怀疑我的方法是否被认为是最佳实践

这也提出了一个问题,我该如何做我想做的事情?目前,我的
DELETE
Names
端点是
api/Names/{fileName}
,我不知道如何将
IsValid
也包括在这个端点中。至少需要一个或两个
FileName
IsValid
值。我不希望用户能够调用
api/Names
并删除数据库中的每个名称

在NamesController中删除操作:

[HttpDelete("{fileName}")]
public void DeleteBySourceFileName(string fileName)
{
    _repo.DeleteNamesByFileName(sourceFileName);
}
我曾考虑在操作中添加
IsValid
作为查询参数,但这仍然会使
fileName
保持必需状态


实现这一点的最佳方法是什么?这样的端点是否适合RESTful API?

我在postman中测试了这段代码。所有3条线路都正常工作。感谢@PavelAnikhouski的isValid:bool创意

        [Route("~/api/Delete/{fileName}")]
        [Route("~/api/Delete/{isValid:bool}")] 
        [Route("~/api/Delete/{fileName}/{isValid}")] 
        public  void Delete(string fileName, bool? isValid)
        {
            .....
        }

如果愿意,您可以为每个路由使用不同的名称,例如“DeleteByFileName”或“DeleteIsValid”,而不是“Delete”。它仍然可以正常工作。

如果您想使用RESTful方法,我认为您可以使用以下三种方法之一一次删除多个项目:


  • 使用查询字符串删除
  • ,如前所述:
    DELETE api/names?filenames={file name}&isvalid={true | false}
    • 它很简单,但缺点是将过滤器声明为可选的,而您已经说过不是,因为您不允许删除所有名称。操作代码类似于:

  • POST
    deletions
    资源,返回标识符,然后使用标识符
    DELETE
    ,如下工作流:
  • --->a)发布请求,如:

    POST api/names/deletions
    {
       'filenames': [],
       'isValid': false
    }
    
    到编码如下的端点:

    public class DeletionInput
    {
        public string[] FileNames { get; set; }
        public bool? IsValid { get; set; }
    }
    
    [HttpPost("deletions")]
    public Task<IActionResult> CreateDeletion([FromBody] DeletionInput input)
    {
        // Based on the inputs, gather a list of Names to be deleted
        // and assign an ID to it. The ID is returned in the response
    }
    
    (有关此选项的详细信息)


  • 删除带有正文的
    。HTTP删除请求可能有正文()
    • 请求举例:
    • 行动实例:
    公共类删除输入
    {
    公共字符串[]文件名{get;set;}
    公共bool?有效{get;set;}
    }
    [HttpDelete]
    公共任务删除([FromBody]删除输入)
    {
    //要删除的代码,但使用空/空参数避免删除(避免全部删除)
    }
    
    • 这也是一个简单的选择。ASP.NET支持它,但可能有供应商不支持。但是,HTTP规范允许这样做

    就个人而言,我从不删除任何记录。你永远不知道将来是否需要它们。只需为“已删除”创建一个字段,并将其设置为0或1。(您可以使用bools,但我更喜欢tinyint而不是bools)所有其他逻辑都遵循是否设置该值。似乎你需要UID,除非你能保证文件名是唯一的。如果你在服务器上删除一个文件,可能会考虑把文件移到一个“删除”文件夹中。使用UID和表名作为文件名的一部分。@pcalkins是否删除是另一个问题,但这里的主要问题是如何按照restful样式正确构建URL。这仅仅是简单的,如果我们认为端点只是一个普通的Web API操作,接受POST请求并获得删除操作所需的所有数据(文件名,…)。将您的操作头更改为:[路由(“~API/DETENENAMS/{文件名}”)[路由(“~API/DeleTeSeValue/{IsReal}}”)] [路由(“~API/DELTEE/{FielnNe}/{ISVALID}”)]。public void DeleteBySourceFileName(字符串文件名,bool?isValid)-所有3条路线都应该在下一条路线下。我认为删除操作应该只接受一个Id,并且应该询问确认。通过类似这样的参数进行筛选看起来确实相当危险:D我们进行筛选,但通常结果会首先显示在用户界面上,以便用户清楚地看到应该删除的内容。当我们删除al时,有一个例外l、 这确实有效!谢谢。在我的代码中,我只是让端点说
    Names
    ,而不是
    Delete
    ,因为我们正在删除
    Names
    资源,而
    Delete
    的操作是在请求的某个地方指定的。
    public class DeletionInput
    {
        public string[] FileNames { get; set; }
        public bool? IsValid { get; set; }
    }
    
    [HttpPost("deletions")]
    public Task<IActionResult> CreateDeletion([FromBody] DeletionInput input)
    {
        // Based on the inputs, gather a list of Names to be deleted
        // and assign an ID to it. The ID is returned in the response
    }
    
    [HttpDelete("deletions/{id}")]
    public Task<IActionResult> DeleteByDeletionId([FromRoute] string id)
    {
        // the Names in the deletion list are effectively deleted only now
    }
    
    DELETE api/names
    {
       'filenames': [],
       'isValid': false
    }
    
    public class DeletionInput
    {
        public string[] FileNames { get; set; }
        public bool? IsValid { get; set; }
    }
    
    [HttpDelete]
    public Task<IActionResult> Delete([FromBody] DeletionInput input)
    {
        // code to delete, but avoid delete with null/empty parameters (avoid delete all)
    }