Windows Azure blob元数据中值的最大大小是多少?
我可以看到,网络服务器将施加大约4k的实际上限。
最大。根据此处的文档,元数据大小为8K:https://learn.microsoft.com/en-us/rest/api/storageservices/Setting-and-Retrieving-Properties-and-Metadata-for-Blob-Resources
- 元数据名称必须遵守C#标识符的命名规则
- 名称不区分大小写,但在设置或读取时不区分大小字母
- 如果为一个资源提交了两个或多个具有相同名称的元数据头,Blob服务将返回状态代码400(错误请求)
- 元数据由名称/值对组成
- 所有元数据对的总大小最多可达8KB
- 元数据名称/值对是有效的HTTP标头,因此它们遵守管理HTTP标头的所有限制
另外:
- 由于元数据名称必须是有效的C#标识符-尽管C#中的标识符没有正式的长度限制,但如果标识符的长度超过511个字符,Visual Studio 2015之前的Visual C#版本会抱怨
- HTTP标头名称和HTTP标头值的长度没有正式或定义的限制,尽管许多web服务器会阻止总标头大小超过16KB的请求,在某些情况下甚至超过8KB
- 每个blob元数据条目都由其单独的HTTP标头表示,该标头具有形式为
x-ms-meta-{yourMetadataName}
的名称前缀,因此为每个元数据名称添加了10个字符
以下是您可以使用的客户端验证检查:
static void ValidateMetadata( IEnumerable< KeyValuePair<String,String> > blobMetadata )
{
const int AZURE_MD_NAME_PREFIX_LENGTH = 10; // "x-ms-meta-"
Int32 totalLength = 0;
foreach( KeyValuePair<String,String> md in blobMetadata )
{
totalLength += AZURE_MD_NAME_PREFIX_LENGTH + md.Key.Length + m.Value.Length;
if( !IsValidMetadataName( md.Key ) )
{
throw new ArgumentException( message: "Metadata name "" + md.Key + "" is invalid." );
}
if( md.Value.Any( c => !IsValidHttpHeaderValueChar( c ) ) || md.Value.Contains("rn") )
{
throw new ArgumentException( message: "Metadata value "" + md.Value + "" is invalid." );
}
}
if( totalLength > 8192 )
{
throw new ArgumentException( message: "Total length of metadata names and values " + totalLength +" exceeds 8KiB limit." );
}
}
private static Boolean IsValidMetadataName( String name )
{
// https://stackoverflow.com/questions/47687379/what-characters-are-allowed-in-http-header-values
if( String.IsNullOrWhiteSpace( name ) ) return false;
// The intersection of valid HTTP Header Names and C# Identifiers means:
// * First character must be a letter.
// * All other characters must be ASCII letters or digits.
// * Underscores are technically legal, but many HTTP systems reject them: https://stackoverflow.com/questions/22856136/why-http-servers-forbid-underscores-in-http-header-names - this method disallows underscores to be safe, though in practice it will probably work fine.
if( !Char.IsLetter( name[0] ) ) return false;
foreach( Char c in name )
{
bool validChar = Char.IsLetterOrDigit( c ) && c < 127;
if( !validChar ) return false;
}
return true;
}
private static Boolean IsValidHttpHeaderChar( Char c )
{
// Technically a quoted-string can contain almost any character ("quoted-string" in the HTTP spec), but it's unclear if Azure Blob storage supports that or not.
bool isCtl = ( 0 <= c && c <= 31 ) || ( c == 127 );
if( isCtl ) return false;
return true; // This method checks individual chars, so it cannot check for rn.
}