0

因此,客户端可以通过多种方式将值传递给服务器。请求正文、标头和/或 Cookie。

在服务器端,这些值可以通过 ModelBinders、ValueProviders MediaFormatters、FromBody、FromUri、Dependency 来检索 注入一个从当前 http 上下文读取它的组件或直接从当前 HTTP 上下文读取(我知道这是单元测试最糟糕的一个。所以,永远不要那样做)。

问题是如何决定哪个用于什么。

我认为所有用户输入都使用 ModelBinder。对于其他任何事情,例如标头中的身份验证令牌,不要使用模型绑定器,而是使用身份验证属性。从标头或 cookie 中读取。

如果您有类似cartId 之类的东西,并且您正在更新购物车中的商品、送货地址、付款地址等,那么现在,使用 DDD 购物车必须是根对象,而商品、送货地址和付款必须是子对象,并且每个请求必须收到一个购物车和依赖对象。但是,这将是一个非常沉重的负担。那么,为什么不只传递cartId 以及为什么不将该cartId 存储在cookie 中,如果我们这样做的话。我们应该如何读取 cartId 的值,使用 ModelBinder,依赖注入从当前 HTTP 上下文读取它的组件或直接从当前 HTTP 上下文读取(我知道这是最糟糕的单元测试。所以,永远不要这样做)

因此,任何不是身份验证令牌或会话令牌的 id 都需要在操作方法中。但它不会作为请求正文或查询字符串中的输入传递。读取此类参数的最佳方法是什么

4

1 回答 1

1

如果您有类似cartId 之类的东西,并且您正在更新购物车中的商品、送货地址、付款地址等,那么现在,使用 DDD 购物车必须是根对象,而商品、送货地址和付款必须是子对象,并且每个请求必须收到一个购物车和依赖对象。

不要将 DDD 与 HTTP/REST 混淆。DDD 适用于您的域。HTTP/REST 适用于您的 Web 资源。

为什么不这样呢?

add product to the cart
POST /my/carts/1/products { body/model: productId=6&quantity=2 }

update quantity
PUT /my/carts/1/products/6 {body/model: quantity=4 }

...我不得不与您的 DDD 设计争论。送货地址和帐单地址实际上是 Order 聚合的一部分,而不是 Cart 聚合的一部分。但我离题了...

如果你组织你的 HTTP 资源来模仿你的 DDD 聚合,那么你不需要在每个请求中传递整个购物车。您可以让不同的用户操作调用不同的资源/方法组合来与聚合进行交互。您甚至不需要将 cartId 与请求正文一起发送,因为它已经在 URL 中:

[POST("my/carts/{cartId:int}/products")]
public HttpResponseMessage PostProduct(int cartId, CartProductPostModel model)
{
    // ensure user owns the cart (based on cookie or authentication info)
    // get the cart aggregate based on the cartId,
    // add the product to the cart
    // tell the client you succeeded by passing back an appropriate response
    // 201 Created
    // Location: http://www.site.com/my/carts/1/products/6
    // note the response does not send back the whole cart, it only tells you
    // the new resource was created and where you can access it
}

如果你设计你的 HTTP 资源 URL 的 RESTfully,那么你不需要在 headers、cookies、session 等中传递任何 id,因为你需要的所有信息都已经在请求中——要么在 URL 本身中,要么在请求正文中。

更新

所以,在我们的例子中,cartId 不是一个整数,它是一个实际上有一些“/”的字符串(IIS/ASP.net MVC 崩溃了)。我知道很奇怪,但就是这样,我无法改变它。因此,它不能作为 url 的一部分存在。它可能是查询字符串的一部分。但是,为了使其与其他客户交互操作。我们有点被迫把它放在饼干上。

是的,您可以将其放在 URL 中。您只需要先对其进行编码。所以像这样的购物车 IDcart/with/slashes在 URL 中是这样结束的:

add product to the cart
POST /my/carts/cart%2fwith%2fslashes/products

update quantity
PUT /my/carts/cart%2fwith%2fslashes/products/6

这适用于 MVC 或 WebAPI 路由而不会崩溃。

[POST("my/carts/{cartId}/products")]
public HttpResponseMessage PostProduct(string cartId, CartProductPostModel model)
{
    // cartId will be "cart/with/slashes", decoded
}
于 2013-08-09T18:00:01.090 回答