我正在实现API以将文件存储在Azure Blob存储中。
我正在使用Microsoft库来验证容器和blob名称。
NameValidator.ValidateContainerName(containerName);
NameValidator.ValidateBlobName(blobFullName);
但是,尽管their own docs知道它们不是有效的,但它仍返回一些有效名称,并且当我尝试保存它们时,blob存储正按预期返回400错误请求。因此,除了关于为什么MS验证库不完整的问题外,如何在C#中执行其余的验证?具体来说,我现在在
上失败了”一些ASCII或Unicode字符,例如控制字符(0x00至 0x1F,\ u0081等)“
我的文件名中带有\ u0081。剩余的无效字符是什么?他们指出我们是ietf docs,但是然后说不允许其中某些字符?哪个?只是所有控制字符?
为清楚起见,这是返回400的部分
CloudBlockBlob blob = documentContainer.GetBlockBlobReference(blobFullName);
await blob.UploadFromStreamAsync(fileStream, token).ConfigureAwait(false);
感谢您的帮助!
更新:我已添加此逻辑位以至少检查控制字符。如果我可以得到一些可靠的信息,我将针对Microsoft的验证码发布PR
if (blobFullName.ToCharArray().Any(c => Char.IsControl(c))) {
throw new HissyFitException(); // or do other stuff to fail validation
}
答案 0 :(得分:1)
“某些ASCII或Unicode字符,例如控制字符(0x00至0x1F,\ u0081等)”
该文档的单词“ some”不明确,您可以在azure doc网站上提出文档问题,并要求他们提供完整的文档列表以更新文档。
答案 1 :(得分:0)
我现在编写了自己的实现,用于检查存储帐户名,容器名和Blob名称的有效性。在我的实现中,整个名称必须以以下形式传递给方法: // Blob名称可能包含“ /”。
// Use like this:
public static bool IsBlobFilenameValid(string blobFilename)
{
// e. g. blobFilename = "mystorageaccount/containername/this/is_a/blob.jpg
string storageAccount = GetStorageAccount(blobFilename);
string container = GetContainer(blobFilename);
string blobName = GetBlobFilename(blobFilename);
if(string.IsNullOrWhiteSpace(storageAccount)
|| string.IsNullOrWhiteSpace(container)
|| string.IsNullOrWhiteSpace(blobName)
|| !IsAzureBlobFilenameValid(blobFilename))
{
return false;
}
return true;
}
private static bool IsAzureBlobFilenameValid(string filename)
{
if (filename.Count(c => c == '/') < 2)
{
return false;
}
var storageAccount = GetStorageAccount(filename);
var container = GetContainer(filename);
var blob = GetBlobFilename(filename);
string patternAccount = @"^[a-z0-9]{3,24}$";
string patternContainer = @"^[a-z0-9-]{3,63}$";
string patternBlob = @"^.{1,1024}$";
if (!Regex.IsMatch(container, patternContainer)
|| !Regex.IsMatch(storageAccount, patternAccount)
|| !Regex.IsMatch(blob, patternBlob))
{
return false;
}
return true;
}
private static string GetStorageAccount(string file)
{
int charLocation = file.IndexOf('/', StringComparison.Ordinal);
if (charLocation > 0)
{
return file.Substring(0, charLocation);
}
return string.Empty;
}
private static string GetContainer(string file)
{
int charLocation = IndexOfSecond(file, "/");
if (charLocation > 0)
{
return file.Substring(0, charLocation);
}
return string.Empty;
}
private static string GetBlobFilename(string file)
{
int charLocation = IndexOfSecond(file, "/");
if (charLocation > 0)
{
return file.Substring(charLocation + 1, file.Length - (charLocation + 1));
}
return string.Empty;
}
private static int IndexOfSecond(string theString, string toFind)
{
int first = theString.IndexOf(toFind);
if (first == -1) return -1;
// Find the "next" occurrence by starting just past the first
return theString.IndexOf(toFind, first + 1);
}