You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用.NET库创建Azure Media Services定位器失败问题排查

问题描述

此前正常运行的旧版V2 Azure Media Services账号,使用.NET代码创建Streaming Locator时抛出无额外详情的BadRequest异常。代码如下:

var contentKeys = new List<StreamingLocatorContentKey>
{
    new StreamingLocatorContentKey(
        contentKeyId,
        StreamingLocatorContentKeyType.CommonEncryptionCenc,
        "cencKeyDefault",
        Convert.ToBase64String(contentKeyValue))
};

return await mClient.StreamingLocators.CreateAsync(
    mResourceGroupName, mAccountName,
    locatorName,
    new StreamingLocator(assetName, PredefinedStreamingPolicy.MultiDrmCencStreaming,
                         defaultContentKeyPolicyName: "KeyPolicy",
                         contentKeys: contentKeys));

其中locatorName为$"Locator-{contentKeyId:N}"。

经测试:

  • 新建V2或V3账号均出现相同问题;
  • 移除contentKeys: contentKeys参数后代码可正常运行,但业务需要传递密钥值,因此该方案不可行,说明问题出在密钥相关请求部分;
  • 使用如下POST请求可成功创建:
POST https://management.azure.com/subscriptions/{{subscriptionId}}/resourceGroups/{{resourceGroup}}/providers/Microsoft.Media/mediaServices/{{msName}}/streamingLocators/Locator-A1?api-version=2021-11-01

{
    "properties": {
        "assetName": "Video-A1",
        "streamingPolicyName": "Predefined_MultiDrmCencStreaming",
        "defaultContentKeyPolicyName": "KeyPolicy",
        "contentKeys": [
        {
            "labelReferenceInStreamingPolicy": "cencKeyDefault",
            "id": "60000000-0000-0000-0000-000000000001",
            "value": "1UqLohAfWsEGkULYxHjYZg=="
        }]
    }
}

环境信息:

  • 项目:.NET 6
  • Microsoft.Azure.Common: 2.2.1
  • Microsoft.Azure.Management.Media: 6.0.0
  • Microsoft.Azure.Storage.Blob: 11.2.3
  • Microsoft.Rest.ClientRuntime.Azure.Authentication: 2.4.1

需解决两个问题:

  1. 代码中存在什么问题?
  2. 如何调试Azure调用以获取详细错误信息,而非仅BadRequest状态码?

附:官方文档中错误提及cencDefaultKey,实际需使用cencKeyDefault才能正常运行。


问题解答

一、代码中的核心问题

对比成功的POST请求与.NET代码的差异,问题出在StreamingLocatorContentKey的参数赋值逻辑上:

.NET SDK的StreamingLocatorContentKey构造函数中,第三个参数对应**Label**属性,但Azure服务实际需要的是将"cencKeyDefault"赋值给LabelReferenceInStreamingPolicy属性。你当前的代码把值传给了Label字段,导致请求体中的字段与服务端期望不匹配,触发BadRequest。

修改后的正确代码如下:

var contentKeys = new List<StreamingLocatorContentKey>
{
    new StreamingLocatorContentKey
    {
        Id = contentKeyId,
        Type = StreamingLocatorContentKeyType.CommonEncryptionCenc,
        LabelReferenceInStreamingPolicy = "cencKeyDefault",
        Value = Convert.ToBase64String(contentKeyValue)
    }
};

return await mClient.StreamingLocators.CreateAsync(
    mResourceGroupName, mAccountName,
    locatorName,
    new StreamingLocator(assetName, PredefinedStreamingPolicy.MultiDrmCencStreaming,
                         defaultContentKeyPolicyName: "KeyPolicy",
                         contentKeys: contentKeys));

二、获取详细错误信息的调试方法

1. 捕获CloudException解析详细错误

Azure SDK抛出的CloudException包含服务返回的完整错误细节,通过try-catch捕获并输出:

try
{
    return await mClient.StreamingLocators.CreateAsync(...);
}
catch (CloudException ex)
{
    Console.WriteLine($"错误代码: {ex.Error.Code}");
    Console.WriteLine($"错误消息: {ex.Error.Message}");
    Console.WriteLine($"响应内容: {ex.Response.Content}");
    throw;
}

2. 启用HTTP请求日志记录

通过自定义日志处理器,查看SDK实际发送的请求体和响应内容,对比手动成功的POST请求定位差异:

// 自定义日志处理器
public class LoggingHandler : DelegatingHandler
{
    private readonly ILogger _logger;

    public LoggingHandler(HttpMessageHandler innerHandler, ILogger logger) : base(innerHandler)
    {
        _logger = logger;
    }

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        // 记录请求信息
        _logger.LogInformation($"请求方法: {request.Method}, URL: {request.RequestUri}");
        if (request.Content != null)
        {
            var content = await request.Content.ReadAsStringAsync(cancellationToken);
            _logger.LogInformation($"请求体: {content}");
        }

        var response = await base.SendAsync(request, cancellationToken);

        // 记录响应信息
        _logger.LogInformation($"响应状态码: {response.StatusCode}");
        if (response.Content != null)
        {
            var content = await response.Content.ReadAsStringAsync(cancellationToken);
            _logger.LogInformation($"响应体: {content}");
        }

        return response;
    }
}

// 实现简单的控制台日志
public interface ILogger
{
    void LogInformation(string message);
}

public class ConsoleLogger : ILogger
{
    public void LogInformation(string message)
    {
        Console.WriteLine(message);
    }
}

初始化客户端时使用该处理器:

var handler = new HttpClientHandler();
var logger = new ConsoleLogger();
var httpClient = new HttpClient(new LoggingHandler(handler, logger));

var credentials = await GetCredentialsAsync(); // 替换为你的认证逻辑
mClient = new AzureMediaServicesClient(httpClient, credentials)
{
    SubscriptionId = subscriptionId
};

3. 查看Azure Monitor服务端日志

在Azure门户进入你的Media Services账号,依次点击监控 > 日志,查询操作日志即可看到服务端返回的完整错误详情。


内容的提问来源于stack exchange,提问作者Mike

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 01:15:38