我正在构建OData v4服务,我需要有关模型的帮助以及OData可以完成和不能完成的工作。我正在使用.NET Core 2.2和Entity Framework Core和ASP.NET Core。这是我第一次使用.NET Core。
我现在有这个POST请求
[HttpPost]
[ODataRoute("Events({eventKey})/Bookings")]
public async Task<IActionResult> PostBooking([FromODataUri] Guid eventKey, [FromBody] Booking booking)
{
// ...
}
还有我的POCO(EF实体)
public class Booking
{
[Key]
public Guid Id { get; set; }
[Required]
public Event Event { get; set; }
[Required]
public User Student { get; set; }
[Required]
public int Position { get; set; } // Position in the registration queue
[Required]
public DateTime ReservationTime { get; set; }
public DateTime? CancelTime { get; set; } // null by default
}
在此POCO预订中,仅不需要CancelTime。在PostBooking()期间,系统将设置所有必需的属性:
POST https://www.example.com/odata/Events(84a5c788-4f57-4983-b074-4a03a401484a)/Bookings
BODY
{
// In fact my body is empty because Position and ReservationTime I given by system. (now)
// Id is simply a new guid
// Event is in my oData link (84a5c788-4f57-4983-b074-4a03a401484a). I need to check it can be found
// Position is the number of booking register for this event + 1.
// UserId will be in my header (in a session token I will implement later with all security)
}
我看到3种解决方案
1)使用OData Action? 2)我不需要预订来自JSON主体的对象。我可以这样写POST方法吗:
[HttpPost]
[ODataRoute("Events({eventKey})/Bookings")]
public async Task<IActionResult> PostBooking([FromODataUri] Guid eventKey)
{
// ...
}
3)或这样
[HttpPost]
[ODataRoute("Events({eventKey})/Bookings")]
public async Task<IActionResult> PostBooking([FromODataUri] Guid eventKey, [FromBody] BookingPostActionDto booking)
{
// ...
}
其中
public class BookingPostActionDto() // Is a data tranfert object that I use only for API, not save in database
{
[Required]
public Guid RegistrationUserId { get; set; }
}
根据OData标准,这里有哪些可行的解决方案?我不是要最好的,而是要按标准要求有效的。例如,我什至不知道OData是否允许像我在解决方案3中那样使用Dto系统。如果我从不验证模型状态,则解决方案2在工作,因为我验证模型状态会丢失所有必需的数据。当我可以进行POST且似乎更合适时,是否可以在解决方案1中创建类似的动作?
答案 0 :(得分:0)
我在学习the recommended way方面取得了一些不错的经验。如果您想总体上使用DTO,this可能会为您提供帮助。
关于您的问题,我将采用标准的ODataAction:
[HttpPost]
[ODataRoute("Events({eventKey})/Bookings")]
public async Task<IActionResult> PostBooking([FromODataUri] Guid eventKey, [FromBody] Booking booking)
{
// ...
}
您的JSON负载是什么样的都没关系。如果您只需要发送RegistrationUserId
,则可以这样做:
{
"Student":{
"Id:"1"
}
}
或者存储UserId的任何地方...
如果您不需要客户端提供其他数据,也可以自由选择第二种方法。
如果没有理由(例如性能问题或隐藏的敏感信息),我不会使用DTO。只要不需要额外的复杂性,整个API就将保持简单明了。