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

以实体为参数的Web API OData操作,odata,asp.net-web-api2,Odata,Asp.net Web Api2,我需要在ODataWebAPI服务中封装事务中的业务逻辑片段。其中一些部件需要接受一个或多个实体 一个示例用例可能是StockProduct,它可能接受一个产品实体和一个位置实体。它将创建产品并更新该位置的库存记录 我采取的方法是创建一个接受这些实体的未绑定OData操作,以便在单个事务中对这两个实体进行操作。不幸的是,实体既不能用作ODataActionParameter,也不能作为类的一部分并用作复杂参数 我可以想出两种方法来解决这个问题: 创建不是实体的DTO类,该实体是我的每个镜像类的

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

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

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

我可以想出两种方法来解决这个问题:

  • 创建不是实体的DTO类,该实体是我的每个镜像类的镜像,并在我的操作中从DTO转换为模型。这里的问题是,我已经为每个模型(例如Product.cs和ProductDTO.cs)创建了一个DTO,并且不想创建第三个类。(目前,ProductDTO.cs用于发布、放置、修补和删除,Product.cs用于获取)

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


有什么想法或建议吗?

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


您可以使用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>();
ActionConfiguration验证=ModelBuilder.EntityType()
.收集。行动(“验证”);
validate.Namespace=“import”;
验证.EntityParameter(typeof(tenty).Name);
validate.CollectionParameter(“唯一字段”);
validate.Returns();
但是,请注意,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);
    }
}
[HttpPost]
公共虚拟IHttpActionResult验证(ODataActionParameters)
{
//首先,我们检查整个动作方法的参数是否正确
如果(!ModelState.IsValid)
{
返回请求(ModelState);
}
其他的
{
//然后我们在实体对象中强制转换实体参数并进行验证
//它通过控制器的验证方法进行验证
TEntity实体=(TEntity)参数[typeof(TEntity).Name];
验证(实体、类型、名称);
如果(!ModelState.IsValid)
{
返回请求(ModelState);
}
IEnumerable uniqueFields=参数[“uniqueFields”]为IEnumerable;
bool result=Importer.Validate(实体,唯一字段);
返回Ok(结果);
}
}

至于你们的库存产品,在我看来,这本身就是一个新的商业实体,应该这样对待。

谢谢你们的回复。是的,我已经在使用批处理了。上面的示例过于简单,但要求将业务逻辑封装在事务中,封装在ODataWebAPI服务中。我将对问题进行编辑,使其更清楚。