Azure 表存储返回400个错误请求

我在调试模式下运行它,并附加了一个带有异常详细信息的图像。我怎么知道哪里出了问题?我试图在表格中插入数据。蔚蓝能给我更多细节吗?

存储在 Windows Azure 上,而不是我的机器上。表已经创建,但是在插入数据时出现了这个错误

enter image description here

// Retrieve the storage account from the connection string.
Microsoft.WindowsAzure.Storage.CloudStorageAccount storageAccount = Microsoft.WindowsAzure.Storage.CloudStorageAccount.Parse("DefaultEndpointsProtocol=https;AccountName=***;AccountKey=***");


// Create the table client.
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();


// Create the table if it doesn't exist.
CloudTable table = tableClient.GetTableReference("EmployeeOnlineHistory");
table.CreateIfNotExists();

这里是插入代码:

public static void SetStatus(Employee e, bool value)
{
try
{
// Retrieve the storage account from the connection string.
Microsoft.WindowsAzure.Storage.CloudStorageAccount storageAccount = Microsoft.WindowsAzure.Storage.CloudStorageAccount.Parse("DefaultEndpointsProtocol=https;AccountName=###;AccountKey=###");


// Create the table client.
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();


// Create the CloudTable object that represents the "people" table.
CloudTable table = tableClient.GetTableReference("EmployeeOnlineHistory");


// Create a new customer entity.


if (value == true)
{
EmployeeOnlineHistory empHistory = new EmployeeOnlineHistory(e.Id);
empHistory.IsOnline = true;
empHistory.OnlineTimestamp = DateTime.Now;
TableOperation insertOperation = TableOperation.Insert(empHistory);
table.Execute(insertOperation);
}
else
{
TableQuery<EmployeeOnlineHistory> query = new TableQuery<EmployeeOnlineHistory>()
.Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, e.Id.ToString()));
EmployeeOnlineHistory entity = table.ExecuteQuery(query).Take(1).FirstOrDefault();


if ((entity!=null)&&(entity.IsOnline))
{
entity.IsOnline = false;
entity.OfflineTimestamp = DateTime.Now;
entity.OnlineTime = (entity.OfflineTimestamp - entity.OnlineTimestamp);
TableOperation updateOperation = TableOperation.Replace(entity);
table.Execute(updateOperation);
}
else
{
EmployeeOnlineHistory empHistory = new EmployeeOnlineHistory(e.Id);
empHistory.IsOnline = false;
empHistory.OfflineTimestamp = DateTime.Now;
TableOperation insertOperation = TableOperation.Insert(empHistory);
table.Execute(insertOperation);
}
}
}
catch (Exception ex)
{
//var details = new System.IO.StreamReader(((Microsoft.WindowsAzure.Storage.StorageException)ex)..Response.GetResponseStream()).ReadToEnd();
LogFile.Error("EmployeeOnlineHistory.setStatus",ex);
}
}
80034 次浏览

400错误意味着某个属性的值出了问题。找到答案的一种方法是通过 Fiddler 跟踪请求/响应,并查看发送到 Windows Azure Storage 的实际数据。

大胆猜测一下,我假设通过快速浏览你的代码,在你的模型中你有一些 Date/Time 类型的属性(OfflineTimestamp,OnlineTimestamp) ,并观察到在某些情况下,其中一个是用默认值“ 日期时间,最小值”初始化的。请注意,在 WindowsAzureHttp://msdn.microsoft.com/en-us/library/windowsazure/dd179338.aspx中的 Date/Time 类型属性允许的最小值为 Jan 1,1601(UTC)。看看是不是这样。如果是这种情况,那么您可以使它们成为可空类型字段,这样它们就不会被默认值填充。

也可以看看下面 Juha Palomäki 的回答... ... 有时候在他建议的异常中有一个稍微有用的消息(RequestInformation)。扩展错误信息。错误信息)

在我的例子中,它是 RowKey中的一个正斜杠。

我还收到了一个‘ OutOfRangeInput-其中一个请求输入超出范围。试图通过存储模拟器手动添加时出现错误。

关键字段中不允许的字符

属性的值中不允许使用下列字符 PartitionKey RowKey属性:

  • 正斜杠(/)字符
  • 反斜杠(\)字符
  • 数字符号(#)字符
  • 问号()字符
  • U + 0000至 U + 001 F中的控制字符,包括:
    • 水平选项卡(T)字符
    • Linefeed (N)字符
    • 回车符(R)字符
    • 来自 U + 007 F 至 U + 009 F的控制字符

Http://msdn.microsoft.com/en-us/library/dd179338.aspx

我写了一个扩展方法来处理这个问题。

public static string ToAzureKeyString(this string str)
{
var sb = new StringBuilder();
foreach (var c in str
.Where(c => c != '/'
&& c != '\\'
&& c != '#'
&& c != '/'
&& c != '?'
&& !char.IsControl(c)))
sb.Append(c);
return sb.ToString();
}

StorageException 还包含一些关于错误的更详细的信息。

签入调试器: StorageException

enter image description here

我也面临着同样的问题。在我的例子中,PartitionKey 值没有设置,因此默认情况下 PartitionKey 值为 null,这导致 Object reference not set to an instance of an object.异常

检查是否为 PartitionKey 或 RowKey 提供了适当的值,您可能会面临这样的问题。

有时这是因为你的 partitionKeyrowKeyNULL

(对我来说就是这样)

我也面临着同样的问题,但是原因在于我的尺寸。在深入研究其他异常属性之后(RequestInformation。ExtendedErrorInformation) ,找到了原因:

错误代码: PropertyValueTooLarge ErrorMessage: 属性值超过允许的最大大小(64KB)。如果属性值是字符串,则为 UTF-16编码,最大字符数应为32K 或更少。

我解决了我的案子,效果很好

我的案子:

  1. 行键的格式不正确(400)。
  2. 分区键和 rowkey 的组合并不是唯一的(409)。

我收到了一个400个错误请求,因为我使用的是 ZRS (区域冗余存储) ,而 Analytics 不能用于这种类型的存储。我不知道我用的是分析软件。

我删除了存储容器并重新创建为 GRS,现在它工作正常。

从 MS 关于所有表服务错误代码的文档可以找到 给你

就我而言: 容器名称是大写字母。使用字符有限制。 enter image description here

我收到了一个(400) Bad Request,StatusMessage: Bad Request,ErrorCode: OutOfRangeInput,而实体的属性 DateTime 没有设置(= DateTime)。MinValue)

对我来说,我试图这样做:

CloudBlobContainer container = blobClient.GetContainerReference("SessionMaterials");
await container.CreateIfNotExistsAsync();

因为 ContainerName SessionMaterials(用 Pascal Case 和 Camel Case: D 写作的习惯)导致了400个坏请求。那么, 我只要把它变成 sessionmaterials就行了。 成功了。

希望这对某人有帮助。

PS:-只需检查异常 http 响应或使用 fiddler 捕获请求和响应。

我有相同的 BadRequest (400)错误,最后我手动填写:

enter image description here

而且对我很有效,希望这能有帮助!

在我的例子中: 我使用包含连字符的标记名称包含 blob 元数据。

var blob = container.GetBlockBlobReference(filename);
blob.Metadata.Add("added-by", Environment.UserName);
//.. other metadata
blob.UploadFromStream(filestream);

"added-by"中的破折号是个问题,后来 RTFM 告诉我标记名必须符合 C # 标识符约定。

档号: https://learn.microsoft.com/en-us/azure/storage/blobs/storage-properties-metadata

下划线工作正常。

在我的例子中,我不应该在实体类中添加 PartitionKey 和 Rowkey。它应该来自基类。下面就行了。

public class TableRunLogMessage:TableEntity
{
public string status { get; set; }
public long logged { get; set; }




public TableRunLogMessage() { }
}

如果您正在使用 NodeJS 并偶然发现这篇文章,只是发现您没有在错误对象中获得那些可爱的详细信息; 您可以使用代理来获得那些详细信息。但是,由于这里没有人提到如何使用代理。

使用 NodeJS 最简单的方法是设置两个环境变量:

NODE_TLS_REJECT_UNAUTHORIZED=0
This disables SSL checks so you can intercept your own SSL requests. This leaves you open to Man-in-The-Middle attacks and should NEVER make it to production, and I wouldn't even leave it in development for long. However, it will allow you to intercept the HTTP Requests.


HTTP_PROXY=http://127.0.0.1:8888
This sets node to utilize a proxy listening on your localhost at port 8888. Port 8888 is the default for Fiddler. Many other proxies default to 8080.

如果您实际上使用 C # ,就像本文作者所做的那样; 您可以简单地安装 Fiddler 并将其设置为拦截。默认情况下,它应该拦截请求。您可能还需要信任 Fiddler 的证书,或者执行相当于 NODE 的“ NODE _ TLS _ REJECT _ UNAUTHORIZED = 0”的操作。

我收到了来自 Azure 存储帐户表 API 的400-BadRequest 响应。异常信息显示“被访问的帐户不支持 http”.我认为如下图所示,在存储帐户配置中启用“安全传输要求”时,必须在连接字符串中使用 https。enter image description here

在我创建“ TableBotDataStore”类(MS bot 框架)的新实例中,我们传递带有连字符的“ tableName”参数,比如“ master-bot”,并且 TableBotDataStore 只能有带字母和数字的表名

我遇到了同样的问题,函数将 containerNameKey作为字符串传递

container = blobClient.GetContainerReference(containerNameKey)

我改成了

container = blobClient.GetContainerReference(ConfigurationManager.AppSettings(containerNameKey).ToString())

成功了

当我试图给字符串字段赋予太长的值时,得到了400-BadRequest 响应。

”UTF-16编码的值。字符串值的大小可能高达64KiB。请注意,支持的最大字符数约为32K 或更少。”

Https://learn.microsoft.com/en-us/rest/api/storageservices/understanding-the-table-service-data-model

对我来说,我使用带破折号示例的表名: tablename: “ table-1234”,但是没有破折号的表名: “ table1234”就可以了。

对于我来说,我尝试在 Azure 存储表中插入一个包含“ #”字符的 PartitionKey/RowKey 实体。令人烦恼的是,这是不允许的,因为在单表设计中常常使用“ #”作为分隔符。