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

C# Azure表存储返回400个错误请求,c#,azure,exception,azure-table-storage,C#,Azure,Exception,Azure Table Storage,我在调试模式下运行了它,并附加了一个包含异常详细信息的图像。我怎么知道出了什么问题?我试图在表格中插入数据。azure不能给我更多的细节吗 Obs:存储在Windows Azure上,而不是我的计算机上。表已创建,但在插入数据时出现此错误 // Retrieve the storage account from the connection string. Microsoft.WindowsAzure.Storage.CloudStorageAccount storageAccount = Mi

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

Obs:存储在Windows Azure上,而不是我的计算机上。表已创建,但在插入数据时出现此错误

// 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);
    }
}
公共静态无效设置状态(员工e,布尔值)
{
尝试
{
//从连接字符串中检索存储帐户。
Microsoft.WindowsAzure.Storage.CloudStorageAccount-storageAccount=Microsoft.WindowsAzure.Storage.CloudStorageAccount.Parse(“DefaultEndpointsProtocol=https;AccountName=###;AccountKey=####);
//创建表客户端。
CloudTableClient tableClient=storageAccount.CreateCloudTableClient();
//创建表示“人员”表的CloudTable对象。
CloudTable=tableClient.GetTableReference(“EmployeeOnlineHistory”);
//创建一个新的客户实体。
如果(值==true)
{
EmployeeOnlineHistory empHistory=新员工OnlineHistory(e.Id);
empHistory.IsOnline=true;
empHistory.OnlineTimestamp=DateTime.Now;
TableOperation insertOperation=TableOperation.Insert(empHistory);
表.Execute(插入操作);
}
其他的
{
TableQuery=新建TableQuery()
.Where(TableQuery.GenerateFilterCondition(“PartitionKey”,QueryComparisons.Equal,e.Id.ToString());
EmployeeOnlineHistory实体=table.ExecuteQuery.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(实体);
表。执行(更新操作);
}
其他的
{
EmployeeOnlineHistory empHistory=新员工OnlineHistory(e.Id);
empHistory.IsOnline=false;
empHistory.OfflineTimestamp=DateTime.Now;
TableOperation insertOperation=TableOperation.Insert(empHistory);
表.Execute(插入操作);
}
}
}
捕获(例外情况除外)
{
//var details=new System.IO.StreamReader(((Microsoft.WindowsAzure.Storage.StorageException)ex)…Response.GetResponseStream()).ReadToEnd();
LogFile.Error(“EmployeeOnlineHistory.setStatus”,ex);
}
}

400错误表示您的一个属性的值有问题。一种方法是通过Fiddler跟踪请求/响应,并查看发送到Windows Azure存储的实际数据

粗略猜测一下,我假设快速浏览一下您的代码,您的模型中有一些日期/时间类型属性(OfflineTimestamp、OnlineTimestamp),并观察到在某些场景中,其中一个属性是用默认值初始化的,默认值为“DateTime.MinValue”。请注意,在Windows Azure中,日期/时间类型属性允许的最小值为1601年1月1日(UTC)。请看看情况是否如此。如果是这种情况,那么您可以将它们设置为可为空的类型字段,这样它们就不会被默认值填充


看看Juha Palomäki下面的答案。。。有时在他建议的异常中有一条稍微有用的消息(RequestInformation.ExtendedErrorInformation.ErrorMessage)

在我的例子中,它是行键中的正斜杠

我还收到一个“OutOfRangeInput-其中一个请求输入超出范围”。尝试通过存储仿真程序手动添加时出错

关键字段中不允许使用的字符

值中不允许使用以下字符: 分区键行键属性:

  • 正斜杠(/)字符
  • 反斜杠(\)字符
  • 数字符号(#)字符
  • 问号()字符
  • 从U+0000到U+001F的控制字符,包括:
    • 水平制表符(\t)字符
    • 换行符(\n)字符
    • 回车符(\r)字符
    • 从U+007F到U+009F的控制字符

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

公共静态字符串ToAzureKeyString(此字符串str)
{
var sb=新的StringBuilder();
foreach(str中的var c)
.其中(c=>c!='/'
&&c!='\\'
&&c!='#'
&&c!='/'
&&c!=“?”
&&!char.IsControl(c)))
sb.附加(c);
使某人返回字符串();
}

StorageException还包含有关错误的更详细信息

签入调试器:StorageException.RequestInformation.ExtendedInformation


我也面临着同样的问题。在我的例子中,没有设置PartitionKey值,因此默认情况下PartitionKey值为null,这导致
对象引用未设置为对象的实例。
异常


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

有时这是因为您的
PartitionKey
RowKey
NULL


(对我来说也是如此)

我也面临同样的问题,但我的理由是因为尺寸。在深入研究其他异常属性之后(重新
CloudBlobContainer container = blobClient.GetContainerReference("SessionMaterials");
await container.CreateIfNotExistsAsync();
var blob = container.GetBlockBlobReference(filename);
blob.Metadata.Add("added-by", Environment.UserName);
//.. other metadata
blob.UploadFromStream(filestream);
public class TableRunLogMessage:TableEntity
{
      public string status { get; set; }
      public long logged { get; set; }


      public TableRunLogMessage() { }
}
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.
container = blobClient.GetContainerReference(containerNameKey) 
container = blobClient.GetContainerReference(ConfigurationManager.AppSettings(containerNameKey).ToString())