OData v4的正确路由是什么?

时间:2019-03-25 06:28:59

标签: c# asp.net-core entity-framework-core odata-v4

我正在构建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中创建类似的动作?

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就将保持简单明了。