Web Api 路由多个 DTO 相同的 POCO
Web Api Routing Multiple DTOs Same POCO
我对如何在同一个 POCO 有多个 DTO 时实现 Web API 路由有疑问。
让我们想象以下场景:
- 你有一个 POCO Class。假设 100 个属性
- 您需要在不同的 platforms/UIs
中显示 class 的列表
即
List 1 Prop A1 | Prop A2 | Prop A3 | Prop A4
List 2 Prop A21 | Prop A22 | Prop A23 | Prop A24 | Prop A25 | Prop A26 | Prop A27 | Prop A28 |
我会称之为公司,因为有很多例子使用这个 class 名称
像这样实施 Web API + DTO 策略是否正确?
Class是:
- 公司(POCO class)
- CompanyDetailDTO
- CompanyLightListDTO
- CompanyMediumListDTO
示例:
public class CompaniesController : ApiController
{
private MultiTierWebApiContext db = new MultiTierWebApiContext();
private static readonly Expression<Func<Company, CompanyDetailDTO>> AsCompanyDetailDTO =
x => new CompanyDetailDTO
{
Name = x.Name,
Email = x.Email,
isCustomer = x.isCustomer,
isSupplier = x.isSupplier,
Id = x.Id
};
private static readonly Expression<Func<Company, CompanyMediumListDTO>> AsCompanyMediumListDTO =
x => new CompanyMediumListDTO
{
Name = x.Name,
Email = x.Email,
Id = x.Id
};
private static readonly Expression<Func<Company, CompanyLightListDTO>> AsCompanyLightListDTO =
x => new CompanyLightListDTO
{
Name = x.Name,
Id = x.Id
};
// GET: api/Companies/LightList
[Route("api/Companies/LightList")] **It works, but is this a correct way to do it?**
[ResponseType(typeof(CompanyLightListDTO))]
public IQueryable<CompanyLightListDTO>GetCompaniesLightList()
{
return db.Companies.Select(AsCompanyLightListDTO); // default
}
// GET: api/Companies/MediumList
[Route("api/Companies/MediumList")]
[ResponseType(typeof(CompanyMediumListDTO))]
public IQueryable<CompanyMediumListDTO> GetCompaniesMediumList()
{
return db.Companies.Select(AsCompanyMediumListDTO); // default
}
// remaining code removed for simplicity
}
在此先感谢您的进一步帮助。
我会说你走在正确的轨道上,只提供与特定 DTO 相关的相关信息。不要提供不必要的数据。
如果您查看以下演练,您将看到它们如何遵循与示例中的相似模式。
Create a REST API with Attribute Routing in ASP.NET Web API 2
引用供参考:
Instead, I want this request to return a subset of the fields. Also, I
want it to return the author's name, rather than the author ID. To
accomplish this, we'll modify the controller methods to return a data
transfer object (DTO) instead of the EF model. A DTO is an object that
is designed only to carry data.
// Typed lambda expression for Select() method.
private static readonly Expression<Func<Book, BookDto>> AsBookDto =
x => new BookDto
{
Title = x.Title,
Author = x.Author.Name,
Genre = x.Genre
};
// GET api/Books
public IQueryable<BookDto> GetBooks()
{
return db.Books.Include(b => b.Author).Select(AsBookDto);
}
我的建议是将 transformation/projection 功能从控制器 (SoC) 分离到它们自己的服务 (SRP) 中,并将它们注入 (DI) 到 ApiController 中。它将使您的控制器保持轻便。
我对如何在同一个 POCO 有多个 DTO 时实现 Web API 路由有疑问。
让我们想象以下场景:
- 你有一个 POCO Class。假设 100 个属性
- 您需要在不同的 platforms/UIs 中显示 class 的列表
即
List 1 Prop A1 | Prop A2 | Prop A3 | Prop A4
List 2 Prop A21 | Prop A22 | Prop A23 | Prop A24 | Prop A25 | Prop A26 | Prop A27 | Prop A28 |
我会称之为公司,因为有很多例子使用这个 class 名称
像这样实施 Web API + DTO 策略是否正确?
Class是:
- 公司(POCO class)
- CompanyDetailDTO
- CompanyLightListDTO
- CompanyMediumListDTO
示例:
public class CompaniesController : ApiController
{
private MultiTierWebApiContext db = new MultiTierWebApiContext();
private static readonly Expression<Func<Company, CompanyDetailDTO>> AsCompanyDetailDTO =
x => new CompanyDetailDTO
{
Name = x.Name,
Email = x.Email,
isCustomer = x.isCustomer,
isSupplier = x.isSupplier,
Id = x.Id
};
private static readonly Expression<Func<Company, CompanyMediumListDTO>> AsCompanyMediumListDTO =
x => new CompanyMediumListDTO
{
Name = x.Name,
Email = x.Email,
Id = x.Id
};
private static readonly Expression<Func<Company, CompanyLightListDTO>> AsCompanyLightListDTO =
x => new CompanyLightListDTO
{
Name = x.Name,
Id = x.Id
};
// GET: api/Companies/LightList
[Route("api/Companies/LightList")] **It works, but is this a correct way to do it?**
[ResponseType(typeof(CompanyLightListDTO))]
public IQueryable<CompanyLightListDTO>GetCompaniesLightList()
{
return db.Companies.Select(AsCompanyLightListDTO); // default
}
// GET: api/Companies/MediumList
[Route("api/Companies/MediumList")]
[ResponseType(typeof(CompanyMediumListDTO))]
public IQueryable<CompanyMediumListDTO> GetCompaniesMediumList()
{
return db.Companies.Select(AsCompanyMediumListDTO); // default
}
// remaining code removed for simplicity
}
在此先感谢您的进一步帮助。
我会说你走在正确的轨道上,只提供与特定 DTO 相关的相关信息。不要提供不必要的数据。
如果您查看以下演练,您将看到它们如何遵循与示例中的相似模式。 Create a REST API with Attribute Routing in ASP.NET Web API 2
引用供参考:
Instead, I want this request to return a subset of the fields. Also, I want it to return the author's name, rather than the author ID. To accomplish this, we'll modify the controller methods to return a data transfer object (DTO) instead of the EF model. A DTO is an object that is designed only to carry data.
// Typed lambda expression for Select() method. private static readonly Expression<Func<Book, BookDto>> AsBookDto = x => new BookDto { Title = x.Title, Author = x.Author.Name, Genre = x.Genre }; // GET api/Books public IQueryable<BookDto> GetBooks() { return db.Books.Include(b => b.Author).Select(AsBookDto); }
我的建议是将 transformation/projection 功能从控制器 (SoC) 分离到它们自己的服务 (SRP) 中,并将它们注入 (DI) 到 ApiController 中。它将使您的控制器保持轻便。