我正在将项目中的大部分/所有 API 从“纯”WCF 转移到 Odata,并为此使用 OWIN 托管的 Odata enpoint。
我目前遇到的一个问题是文件。我有 2 个区域需要将 ZIP 文件上传到服务器进行处理。在一种情况下,它附加到一个实体(称为“存储库”)并包含未通过 Odata 公开的二进制内容(它只是上传)。另一方面,这是针对未绑定(bind)的操作,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 处的文档不赘述太多细节。它没有显示操作的参数配置允许的类型以及如何配置它以通过来自 Web 表单的 http post 接受文件(和客户端,因为我需要两者)。
请您参考如下方法:
这是一个有用的链接,其中包含有关 Web API 中 OData 的媒体资源支持的文档:https://blogs.msdn.microsoft.com/mrtechnocal/2013/10/31/media-resource-support-for-odata-in-web-api/
您可以稍微简化链接中建议的实现,但可以肯定的是,您需要:
- 创建一个 OData 媒体资源 Controller 。它可以比文档中提议的更简单。见下文。
- 创建自定义 EntityRoutingConvention 以正确路由到将返回 ZIP 文件的 Get 方法(如果您有这种用例,如果您只需要 POST 它们,则可能不需要自定义路由约定)。
因此,对于 Controller ,您可以:
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;
}
}
您将需要一个具有 Stream/byte[]/string 属性的实体 YourZIPObjectEntity,具体取决于您管理二进制文件的方式。 (在文档示例中,这是 Image 类)。对于该实体,您需要指定它在 ODataConfig 中有一个流(请参阅文档中的“设置 Web API 配置”部分)。
我想差不多就是这些了。</p>
然后,您可以通过代码将 ZIP 文件作为 StreamContent 发布:
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...
}
我希望这是您正在寻找的解决方案,或者至少是一种解决方法。
