これをデバッグモードで実行し、例外の詳細を含む画像を添付します。何が間違っていたのかを知るにはどうすればよいですか?テーブルにデータを挿入しようとしていました。 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);
}
}
400エラーは、いずれかのプロパティの値に問題があることを意味します。見つける方法の1つは、Fiddlerを介して要求/応答をトレースし、Windows Azureストレージに送信される実際のデータを確認することです。
ワイルドな推測をして、コードをひと目見て、モデルに日付/時刻型のプロパティ(OfflineTimestamp、OnlineTimestamp)があり、特定のシナリオではそのうちの1つがデフォルト値で初期化されることに気づいたと思います「DateTime.MinValue」です。日付/時刻型の属性に許可される最小値は、Windows Azureでは1601年1月1日(UTC)であることに注意してください [http: //msdn.Microsoft.com/en-us/library/windowsazure/dd179338.aspx] 。そうでない場合はご覧ください。その場合、デフォルト値が入力されないように、null許容型フィールドにすることができます。
以下のJuhaPalomäkiの回答もご覧ください...例外の中に、彼が示唆するわずかに役立つメッセージがある場合があります(RequestInformation.ExtendedErrorInformation.ErrorMessage)
StorageExceptionには、エラーに関するもう少し詳細な情報も含まれています。
デバッガーでチェックイン:StorageException.RequestInformation.ExtendedInformation
私の場合、RowKeyのスラッシュでした。
また、「OutOfRangeInput-要求入力の1つが範囲外です」も受け取りました。ストレージエミュレータを介して手動で追加しようとするとエラーが発生します。
キーフィールドで許可されていない文字
次の文字は、PartitionKeyおよびRowKeyプロパティの値には使用できません:
- スラッシュ(/)文字
- バックスラッシュ(\)文字
- 番号記号(#)文字
- 疑問符(?)文字
- 以下を含むU + 0000からU + 001Fまでの制御文字:
- 水平タブ(\ t)文字
- 改行(\ n)文字
- キャリッジリターン(\ r)文字
- 制御文字U + 007FからU + 009F
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();
}
まあ、私の場合、私はこれをやろうとしていました:
CloudBlobContainer container = blobClient.GetContainerReference("SessionMaterials");
await container.CreateIfNotExistsAsync();
containerName SessionMaterials
(Pascal CaseとCamel Case:Dで書く習慣として)のために、400の悪いリクエストを引き起こしていました。だから、私はそれをsessionmaterials
にする必要があります。そしてそれは働いた。
これが何らかの助けになることを願っています。
PS:-例外HTTP応答を確認するか、フィドラーを使用して要求と応答をキャプチャします。
私は同じ問題に直面しましたが、私の場合の理由はサイズによるものでした。追加の例外プロパティ(RequestInformation.ExtendedErrorInformation)を掘り下げた後、理由が見つかりました。
ErrorCode:PropertyValueTooLarge ErrorMessage:プロパティ値が最大許容サイズ(64KB)を超えています。プロパティ値が文字列の場合、UTF-16でエンコードされ、最大文字数は32K以下である必要があります。
場合によっては、partitionKey
またはrowKey
がNULL
であることが原因です。
(私にとってはそうでした)
すべてのテーブルサービスエラーコードに関するMSからのドキュメントを見つけることができます here
私の場合、EntityクラスにPartitionKeyとRowkeyを追加しないでください。基本クラスからのものでなければなりません。以下はうまくいくでしょう。
public class TableRunLogMessage:TableEntity
{
public string status { get; set; }
public long logged { get; set; }
public TableRunLogMessage() { }
}
エンティティにプロパティDateTimeが設定されていない(= DateTime.MinValue)とき、(400)Bad Request、StatusMessage:Bad Request、ErrorCode:OutOfRangeInputを取得していました
私も同じような問題に直面しました。私の場合、PartitionKeyの値は設定されていなかったため、デフォルトではPartitionKeyの値はnullであり、Object reference not set to an instance of an object.
例外が発生しました。
PartitionKeyまたはRowKeyに適切な値を提供しているかどうかを確認すると、このような問題に直面する可能性があります。
ZRS(Zone Redundant Storage)を使用していたため、400 Bad Requestを受け取っていましたが、このタイプのストレージではAnalyticsを使用できません。アナリティクスを使用していることを知りませんでした。
ストレージコンテナを削除し、GRSとして再作成したところ、正常に動作するようになりました。
同じ問題がありました。関数はcontainerNameKey
を文字列として渡していました。以下はエラーを与えたコードです
container = blobClient.GetContainerReference(containerNameKey)
に変更しました
container = blobClient.GetContainerReference(ConfigurationManager.AppSettings(containerNameKey).ToString())
動いた
「TableBotDataStore」クラス(MSボットフレームワーク)の新しいインストールを作成する私の場合、「master-bot」のようなハイフンで「tableName」パラメーターを渡し、TableBotDataStoreは文字と数字のみでテーブル名を持つことができます
私の場合:タグ名にハイフンを含むblobメタデータを含めました。
var blob = container.GetBlockBlobReference(filename);
blob.Metadata.Add("added-by", Environment.UserName);
//.. other metadata
blob.UploadFromStream(filestream);
"added-by"
のダッシュが問題であり、後でRTFMから、タグ名はC#識別子の規則に準拠する必要があると言われました。
参照: https://docs.Microsoft.com/en-us/Azure/storage/blobs/storage-properties-metadata
アンダースコアは正常に機能します。
NodeJSを使用していて、この投稿を偶然見つけた場合は、エラーオブジェクトにそのような詳細な情報が含まれていないことがわかります。プロキシを使用してこれらの詳細を取得できます。ただし、ここでは誰がプロキシを使用するかについて言及していないためです。
NodeJSで最も簡単な方法は、2つの環境変数を設定することです。
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」と同等の操作を行う必要がある場合があります。
ケースを修正し、問題なく動作しました
私の場合: