代码之家  ›  专栏  ›  技术社区  ›  TomTom

WebApi&Odata-适合文件管理吗?

  •  5
  • TomTom  · 技术社区  · 8 年前

    我正在将一个项目中的大部分/全部API从“纯”WCF转移到Odata,并使用OWIN托管的Odata enpoint。

    目前,我坚持的一个要素是文件。我有两个区域需要将ZIP文件上传到服务器进行处理。在一种情况下,它连接到一个实体(称为“存储库”),并包含未通过Odata公开的二进制内容(它只是上传的)。另一方面,这是一个未绑定的操作,ZIP文件包含配置文件,这些配置文件将装箱/更改多个实体。

    这对于OData是可行的吗?还是我应该忽略OData而使用“手动配置”的标准端点?由于公开的元数据,我真的很想将其保存在Odata中。

    在任何人评论之前,我一直在尝试通过谷歌查找文档,但一直没有得到相关的答案。我得到的答案表明这是可能的,但所有的代码示例都指向旧的WCF级API,而我使用WebApi。文档位于 http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/create-an-odata-v4-endpoint 没有太多细节。它没有显示操作的参数配置允许的类型,以及如何配置它以通过http post从web表单接受文件(以及客户端,因为我需要这两者)。

    2 回复  |  直到 8 年前
        1
  •  7
  •   elbecita    8 年前

    以下是有关Web API中OData的媒体资源支持文档的有用链接: https://blogs.msdn.microsoft.com/mrtechnocal/2013/10/31/media-resource-support-for-odata-in-web-api/

    您可以稍微简化链接中建议的实现,但可以肯定的是,您需要:

    • 创建OData媒体资源控制器。它可以比文件中建议的更简单。见下文。
    • 创建一个自定义EntityRoutingConvention以正确地路由到将返回ZIP文件的Get方法(如果您有这个用例,如果您只需要POST它们,您可能不需要自定义路由约定)。

    因此,对于控制器,您可以:

    public abstract class YourMediaResourceODataController<TEntity, TKey>
        : ODataController where TEntity : class
    {
    }
    

    然后,真正的控制器:

    public class YourController : YourMediaResourceODataController<YourZIPObjectEntity, string>
    {
        // This would be the post
        public async Task<IHttpActionResult> Post()
        {
            var stream = await Request.Content.ReadAsStreamAsync();
            // Manage the stream
        }
    
        // The get (if you want it, you will need to code the custom EntityRoutingConvention).
        [HttpGet]
        public HttpResponseMessage GetMediaResource(string key)
        {
            HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
    
            var theZIPFile = yourZIPFileService.GetZIPFileByKey(key);
            StreamContent contentResult;
            using(var ms = new MemoryStream(theZIPFile.theByteArray)
            {
                contentResult = new StreamContent(ms);
            }
    
            result.Content = contentResult;
            return result;
        }
    }
    

    你需要有一个实体 YourZIPObjectEntity 使用Stream/byte[]/string属性,具体取决于您如何管理二进制文件。(在文档示例中,这是 Image 类别)。对于该实体,您需要指定它在ODataConfig中有一个流(请参阅文档中的“设置Web API配置”部分)。

    我想这差不多就是全部。

    然后,您可以通过代码将ZIP文件作为StreamContent进行POST:

    using(var requestContent = new MemoryStream(yourByteArray))
    using(var request = new HttpRequestMessage(HttpMethod.POST, yourPOSTUri)
    {
        request.Content = new StreamContent(requestContent);
        // Set headers and send the request...
    }
    

    我希望这是您正在寻找的解决方案,或者至少是一种解决方案。

        2
  •  -2
  •   Nikolai    8 年前

    对于包含简单二进制内容的文件,可以使用WebApi而不是OData。除非有一个文件存储库,你想为消费者服务。

    如果您必须上传zip文件并手动处理它们以修改实体,那么您也不需要使用OData。然而,WebApiOData确实提供了批处理事务支持。您可以遵循本教程: https://blogs.msdn.microsoft.com/webdev/2013/11/01/introducing-batch-support-in-web-api-and-web-api-odata/

    同样,如果您有大批量而不是发送zip文件,请使用gZip压缩。下面是一篇关于WebApi gZip支持的文章: https://damienbod.com/2014/07/16/web-api-using-gzip-compression/