Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/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# post/put文档的Swashbuckle EF Core隐藏属性_C#_Asp.net Core_Entity Framework Core_Swagger_Swashbuckle - Fatal编程技术网

C# post/put文档的Swashbuckle EF Core隐藏属性

C# post/put文档的Swashbuckle EF Core隐藏属性,c#,asp.net-core,entity-framework-core,swagger,swashbuckle,C#,Asp.net Core,Entity Framework Core,Swagger,Swashbuckle,摘要 我想从生成的PUT/POST请求文档模型中隐藏属性 更多细节 我想为我正在开发的系统创建一个文档化良好的API。我想使用Swashback/Swagger自动生成文档。我使用实体框架来定义系统中对象之间的关系 下面是对象之间的关系示例 User.cs public class User { public int Id { get; set; } public string ExternalReference { get; set; } public string N

摘要

我想从生成的PUT/POST请求文档模型中隐藏属性

更多细节

我想为我正在开发的系统创建一个文档化良好的API。我想使用Swashback/Swagger自动生成文档。我使用实体框架来定义系统中对象之间的关系

下面是对象之间的关系示例

User.cs

public class User
{
    public int Id { get; set; }
    public string ExternalReference { get; set; }
    public string Name { get; set; }

    public ICollection<Post> Posts { get; }
}
public class Post
{
    public int Id { get; set; }
    public string ExternalReference { get; set; }
    public string Content { get; set; }
    public int UserId { get; set; }

    public User User { get; set; }

}
{
  "id": 0,
  "externalReference": "string",
  "content": "string",
  "userId": 0,
  "user": {
    "id": 0,
    "externalReference": "string",
    "name": "string"
  }
}
下面的示例值是为我的GET/api/posts/{id}端点生成的

GET/api/posts/{id}

{
  "id": 0,
  "externalReference": "string",
  "content": "string",
  "userId": 0,
  "user": {
    "id": 0,
    "externalReference": "string",
    "name": "string",
    "posts": [
      null
    ]
  }
}
这就是我希望看到的,它与可能返回用户对象也相关

下面是为我的POST/api/posts端点生成的示例值

POST/api/posts

public class User
{
    public int Id { get; set; }
    public string ExternalReference { get; set; }
    public string Name { get; set; }

    public ICollection<Post> Posts { get; }
}
public class Post
{
    public int Id { get; set; }
    public string ExternalReference { get; set; }
    public string Content { get; set; }
    public int UserId { get; set; }

    public User User { get; set; }

}
{
  "id": 0,
  "externalReference": "string",
  "content": "string",
  "userId": 0,
  "user": {
    "id": 0,
    "externalReference": "string",
    "name": "string"
  }
}
在我看来,至少我觉得示例的用户部分与POST或PUT无关,只有
userId
属性是。在这个简单的示例中,生成的示例值并不太糟糕,但是如果我开始使用具有多个关系的对象,我觉得它可能会变得混乱

问题又来了


是否有一种优雅的方法可以仅针对PUT/POST方法从生成的swagger文档中抑制关系对象?

您可以自定义如下操作筛选器:

public class CustomOperationFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        if (operation.OperationId == "Posts_post" || operation.OperationId == "Posts_put")
        {
            operation.RequestBody = new OpenApiRequestBody()
            {
                Content = new Dictionary<string, OpenApiMediaType> {
                {"application/json",
                    new OpenApiMediaType()
                    {

                        Schema = new OpenApiSchema(){
                            Example = new OpenApiObject
                                {
                                    ["ID"] = new OpenApiInteger(0),
                                    ["UserId"] = new OpenApiInteger(0),
                                    ["ExternalReference"] = new OpenApiString("string"),
                                    ["Content"] = new OpenApiString("string")
                                }
                        }
                    }
                }
            }
            };
        }
        else
        {
            return;
        }
       
    }
}
公共类CustomOperationFilter:IOperationFilter
{
公共无效应用(OpenApiOperation操作,OperationFilterContext上下文)
{
if(operation.OperationId==“Posts_post”| | operation.OperationId==“Posts_put”)
{
operation.RequestBody=new OpenApiRequestBody()
{
内容=新词典{
{“应用程序/json”,
新的OpenApiMediaType()
{
Schema=newopenapischema(){
示例=新的OpenApiObject
{
[“ID”]=新的OpenAPINEGER(0),
[“UserId”]=新的OpenApiInteger(0),
[“ExternalReference”]=新的OpenApiString(“字符串”),
[“内容”]=新的OpenApiString(“字符串”)
}
}
}
}
}
};
}
其他的
{
返回;
}
}
}
在HttpVerb属性上添加名称:

[HttpPut("{id}",Name = "Posts_put")]
public async Task<IActionResult> PutPost(int id, Post post)
{....}

[HttpPost(Name ="Posts_post")]
public async Task<ActionResult<Post>> PostPost(Post post)
{...}
[HttpPut(“{id}”,Name=“Posts\u put”)]
公共异步任务PutPost(int-id,Post-Post)
{....}
[HttpPost(Name=“Posts\u post”)]

公共异步任务

您可以自定义如下操作筛选器:

public class CustomOperationFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        if (operation.OperationId == "Posts_post" || operation.OperationId == "Posts_put")
        {
            operation.RequestBody = new OpenApiRequestBody()
            {
                Content = new Dictionary<string, OpenApiMediaType> {
                {"application/json",
                    new OpenApiMediaType()
                    {

                        Schema = new OpenApiSchema(){
                            Example = new OpenApiObject
                                {
                                    ["ID"] = new OpenApiInteger(0),
                                    ["UserId"] = new OpenApiInteger(0),
                                    ["ExternalReference"] = new OpenApiString("string"),
                                    ["Content"] = new OpenApiString("string")
                                }
                        }
                    }
                }
            }
            };
        }
        else
        {
            return;
        }
       
    }
}
公共类CustomOperationFilter:IOperationFilter
{
公共无效应用(OpenApiOperation操作,OperationFilterContext上下文)
{
if(operation.OperationId==“Posts_post”| | operation.OperationId==“Posts_put”)
{
operation.RequestBody=new OpenApiRequestBody()
{
内容=新词典{
{“应用程序/json”,
新的OpenApiMediaType()
{
Schema=newopenapischema(){
示例=新的OpenApiObject
{
[“ID”]=新的OpenAPINEGER(0),
[“UserId”]=新的OpenApiInteger(0),
[“ExternalReference”]=新的OpenApiString(“字符串”),
[“内容”]=新的OpenApiString(“字符串”)
}
}
}
}
}
};
}
其他的
{
返回;
}
}
}
在HttpVerb属性上添加名称:

[HttpPut("{id}",Name = "Posts_put")]
public async Task<IActionResult> PutPost(int id, Post post)
{....}

[HttpPost(Name ="Posts_post")]
public async Task<ActionResult<Post>> PostPost(Post post)
{...}
[HttpPut(“{id}”,Name=“Posts\u put”)]
公共异步任务PutPost(int-id,Post-Post)
{....}
[HttpPost(Name=“Posts\u post”)]

公共异步任务

在我看来,解决方案是不将数据库实体公开为API DTO。而是指定API DTO并将数据从数据库实体映射到DTO或从DTO映射数据。AutoMapper或Mapster之类的工具可以帮助您完成这些映射,如果它们非常琐碎。即使您在文档中隐藏它们,用户仍然可以指定它们,并且如果您将该DB模型作为参数,它们将被绑定。@juunas谢谢您,那么实际上为我希望通过API公开的每个项目创建DTO对象?我是否必须为POST和GET方法创建单独的DTO对象,以解决我在原始问题中遇到的问题?我们通常为读和写端点创建单独的DTO,因此模型中只有与请求相关的字段。通常读取模型中包含更多数据。我认为解决方案是不将数据库实体公开为API DTO。而是指定API DTO并将数据从数据库实体映射到DTO或从DTO映射数据。AutoMapper或Mapster之类的工具可以帮助您完成这些映射,如果它们非常琐碎。即使您在文档中隐藏它们,用户仍然可以指定它们,并且如果您将该DB模型作为参数,它们将被绑定。@juunas谢谢您,那么实际上为我希望通过API公开的每个项目创建DTO对象?我是否必须为POST和GET方法创建单独的DTO对象,以解决我在原始问题中遇到的问题?我们通常为读和写端点创建单独的DTO,因此模型中只有与请求相关的字段。通常,read模型中包含更多数据。我感谢您的详细回答,但在之前的评论和一点研究(现在我知道我在寻找什么)之后,我认为我最好沿着DTO的路线走,而不是尝试自动化这些事情。我感谢您的详细回答,但遵循之前的评论和建议