【问题标题】:Web API OData Actions with Entity as parameter以实体为参数的 Web API OData 操作
【发布时间】:2014-09-14 17:31:03
【问题描述】:

我需要在 OData Web API 服务的事务中封装业务逻辑片段。其中一些片段需要接受一个或多个实体。

示例用例可能是 StockProduct,它可能接受 Product 实体和 Location 实体。它将创建产品并更新位置的库存记录。

我采用的方法是创建一个接受这些实体的未绑定 OData 操作,以便可以在单个事务中对这两个实体进行操作。不幸的是,Entities 既不能用作 ODataActionParameter,也不能作为类的一部分并用作复杂参数。

我可以想到两种解决方法:

  • 创建一个不是实体的 DTO 类,它是我的每个镜像类的镜像,并在我的操作中从 DTO 转换为模型。这里的问题是我已经为每个模型都有一个 DTO,例如。 Product.cs 和 ProductDTO.cs 并不想创建第三类。 (目前,ProductDTO.cs 用于 Posts、Puts、Patches 和 Deletes,Product.cs 用于 Gets)。

  • 放弃 OData 操作并创建一个简单的端点来接受我喜欢的任何内容。我不想走第二条路线,因为我想专门使用 OData。

有什么想法或建议吗?

【问题讨论】:

    标签: odata asp.net-web-api2


    【解决方案1】:

    您可以使用批处理请求在单个请求中执行多个操作。这允许您使用现有的控制器来插入两个对象。

    https://aspnetwebstack.codeplex.com/wikipage?title=Web+API+Request+Batching

    【讨论】:

    • 感谢您的回复。是的,我已经在使用批处理。上面的示例是一个简单的示例,但要求是将业务逻辑封装在事务中,在 OData Web API 服务中。我将编辑问题以使其更清楚。
    【解决方案2】:

    您可以使用 ActionConfiguration.EntityParameter() 方法将实体作为参数绑定到您的 OData 操作方法。

    这是一个例子:

    ActionConfiguration validate = ModelBuilder.EntityType<TEntity>()
        .Collection.Action("Validate");
    validate.Namespace = "Importation";
    validate.EntityParameter<TEntity>(typeof(TEntity).Name);
    validate.CollectionParameter<string>("UniqueFields");
    validate.Returns<ValidationResult>();
    

    但是,请注意,ModelState 不会检查提供的实体的内容,并将任何缺少的属性设置为 null,并且超出模型中 StringLength(x) 注释的属性仍将通过。如果您希望之后验证实体本身,请在您的操作方法中使用以下代码:

    [HttpPost]
    public virtual IHttpActionResult Validate(ODataActionParameters parameters)
    {
    //First we check if the parameters are correct for the entire action method
        if (!ModelState.IsValid)
        {
             return BadRequest(ModelState);
        }
        else
        {
             //Then we cast our entity parameter in our entity object and validate
             //it through the controller's Validate<TEntity> method
             TEntity Entity = (TEntity)parameters[typeof(TEntity).Name];
             Validate(Entity, typeof(TEntity).Name);
             if (!ModelState.IsValid)
             {
                  return BadRequest(ModelState);
             }
             IEnumerable<string> uniqueFields = parameters["UniqueFields"] as IEnumerable<string>;
             bool result = Importer.Validate(Entity, uniqueFields);
             return Ok(result);
        }
    }
    

    至于您的 StockProductDTO,在我看来,这本身就是一个新的业务实体,应该这样对待。

    【讨论】:

      猜你喜欢
      • 2013-01-30
      • 1970-01-01
      • 2013-04-19
      • 1970-01-01
      • 1970-01-01
      • 2014-09-17
      • 2012-11-07
      • 2014-11-22
      • 1970-01-01
      相关资源
      最近更新 更多