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

时间:2015-05-31 02:53:13

标签: c# azure async-await azure-storage-blobs azure-media-services

我尝试在Azure MediaService API中托管的Azure Storage API中使用API ServiceAzure

用户将视频流作为HttpPost发送到服务,服务将视频保存为我的存储帐户中的blob,媒体服务对视频进行编码,当视频链接准备就绪时,返回给用户。

但是当我尝试创建Asset时,System.NotSupportedException会抛出一条消息:

  

抛出异常:Microsoft.Data.Services.Client.dll中的'System.NotSupportedException'   抛出异常:mscorlib.dll中的“System.NotSupportedException”   iisexpress.exe错误:0:异常= System.NotSupportedException:这个   目标框架不允许您直接枚举数据   服务查询。这是因为枚举自动发送一个   对数据服务的同步请求。因为这个框架而已   支持异步操作,您必须调用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包含视频的byte[]。调用CreateAsync时抛出异常。我试了_context.Assets.Create没有运气。

重要编辑

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

这是我的类和方法定义

public class UploadController : ApiController
{

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

可能有其他选择吗?

4 个答案:

答案 0 :(得分:1)

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

[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";
}

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

  1. 在指向此帖子操作的索引视图中添加HTML form并提交button,运行并运行!!!
  2. enter image description here

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

答案 1 :(得分:0)

我无法告诉你为什么它不能完全正常工作。 但我认为在构建函数时,问题比在Azure API中更容易找到。

应该这样做:

Actions actions = new Actions(webDriver);
actions.doubleClick(element).perform();

这个异步函数应该像这样调用:

    // 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;
    }

我认为问题将是你的public static async Task ProcessNewBlobAsync() { // ... var asset = await CreateAssetBlobAsync(token); // ... } 声明

事实是using Read/Write Async方法实际上并未提供任何类型的真正异步实现。这意味着他们总是会同步的。

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

我建议避免在preventing a deadlock上使用MemoryStream的语句。

答案 2 :(得分:0)

您可以尝试调用方法

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

并传递与媒体服务关联的默认存储帐户名称。在您的示例中,您正在调用查询默认存储帐户名称的方法。存储帐户的查询不是异步进行的,而是一个错误。此存储帐户查询每个上下文发生一次,不会在服务器上生成负载。如果您可以在应用初始化期间进行查询并在以后的创建资产调用中使用它,那将是一件好事。

答案 3 :(得分:-1)

我希望“blobContainerName”是你在发帖时写的一个模拟?大写字母和blob容器不混合:)

相关问题