Web API OData以实体作为参数的操作

时间:2014-07-23 13:40:06

标签: odata asp.net-web-api2

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

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

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

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

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

  • 放弃OData操作并创建一个简单的终点,接受我喜欢的任何内容。我并不热衷于沿着第二条路走下去,因为我想专门使用OData。

有任何想法或建议吗?

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

您可以使用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不会检查提供的Entity的内容,并将任何缺少的属性设置为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,在我看来,这本身就是一个新的业务实体,应该这样对待。