尝试创build资产时出现System.NotSupportedException

我正尝试在Azure托pipe的API Service中使用Azure MediaService APIAzure Storage API

用户将videostream作为HttpPost发送到服务,该服务将video作为Blob存储在我的存储帐户中,媒体服务对video进行编码,并且当video的链接准备就绪时,将其返回给用户。

但是,当我试图创build一个Asset System.NotSupportedException引发的消息:

抛出的exception:Microsoft.Data.Services.Client.dll中的“System.NotSupportedException”抛出exception:mscorlib.dll中的“System.NotSupportedException”iisexpress.exe错误:0:exception= System.NotSupportedException:此目标框架无法启用直接枚举数据服务查询。 这是因为枚举自动向数据服务发送同步请求。 由于此框架仅支持asynchronous操作,因此您必须调用BeginExecute和EndExecute方法来获取支持枚举的查询结果。

我正在使用以下版本的所需的依赖关系:

 Microsoft.Data.Services.Client - 5.6.2.0 Microsoft.WindowsAzure.MediaServices.Client - 3.0.0.8 Microsoft.WindowsAzure.Storage - 3.1.0.1 

这是我的代码:

 CloudMediaContext _context; IAsset asset; using (MemoryStream Ms = new MemoryStream(data.Data)) { _context = new CloudMediaContext("accountName", "accountKey"); asset = await _context.Assets.CreateAsync("blobContainerName", AssetCreationOptions.None,CancellationToken.None); ... ... } 

data.Data包含video的byte[]CreateAsync被调用时引发exception。 我试过_context.Assets.Create没有运气。

重要的编辑

我创build了一个新的控制台应用程序,使用了我在API服务中使用的代码,并成功执行了它。 所以问题在于API服务。

这是我的类和方法的定义

 public class UploadController : ApiController { [HttpPost] public async Task<string> PostUpload(VideoData data) { ... ... } 

任何替代可能吗?

我能够使用.NET 4.6.1和下面的nuget包创build一个工作演示:

 [HttpPost] public async Task<string> PostUpload() { var bytes = System.Text.Encoding.UTF8.GetBytes("Test"); var data = new VideoData { Data = bytes }; CloudMediaContext _context; using (MemoryStream ms = new MemoryStream(data.Data)) { var accountName = "accountName"; var accountKey = @"primaryaccessKey"; _context = new CloudMediaContext(accountName, accountKey); var asset = await _context.Assets.CreateAsync("myjblobassets", AssetCreationOptions.None, CancellationToken.None); //... do something with asset and ms ... } return "http://my-link"; } 

*注意:由于我们没有演示上传部分,因此任何字节都可以,因此我们确保创build媒体服务资产。

  1. 在索引视图中添加一个HTML form并提交button ,指向这个post操作,运行它并运行!

在这里输入图像说明

注意:在NAME中,input新帐户的名称。 媒体服务帐户名称全部为小写字母或不带空格的字母,长度为3至24个字符。 https://azure.microsoft.com/en-us/documentation/articles/media-services-dotnet-get-started/

我不能告诉你为什么它不能正常工作。 但是我认为这个问题比在Azure API中更容易发现你的函数的构造。

应该这样做:

  // Important is the return value of the function: public async Task<IAsset> CreateAssetBlobAsync(CancellationToken token) { var asset = await _context.Assets.CreateAsync("blobContainerName", AssetCreationOptions.None, CancellationToken.None); // or your 'token' return asset; } 

而这个asynchronous函数应该像这样调用:

 public static async Task ProcessNewBlobAsync() { // ... var asset = await CreateAssetBlobAsync(token); // ... } 

我认为这个问题将是你using声明

事实上, MemoryStreamRead/Write Async方法实际上并不提供任何一种真正的asynchronous实现。 这意味着他们总是会同步的。

(但是你没有调用其中的任何一个,我担心它可能是asynchronous方法的同步包装,所以它会调用API同步而不是asynchronous,这只是一个想法。

我build议避免使用async来防止死锁 。


你可以尝试打电话给方法吗?

 Task<IAsset> CreateAsync(string assetName, string storageAccountName, AssetCreationOptions options, CancellationToken cancellationToken) 

并传递与媒体服务关联的默认存储帐户名称。 在你的例子中,你正在调用查询默认存储帐户名称的方法。 查询存储帐户已经不是asynchronous的,这是一个错误。 此存储帐户查询发生一次每个上下文不生成服务器上的负载。 如果您可以在应用程序初始化过程中进行查询并在以后创build资产调用中使用它,那将会很好。

我希望“blobContainerName”是你发布这个问题时写的一个模拟吗? 大写字母和blob容器不要混合:)