C# 带下划线的案例问题
我注意到,当我序列化C#dictionary时,它的键为HTTP#u VERB,它在JSON结构中变成了HTTP#u VERB,而不是HTTP#u VERB或HTTP#VERB,我希望驼峰大小写会成功 这是我用来重现问题的代码:C# 带下划线的案例问题,c#,json.net,C#,Json.net,我注意到,当我序列化C#dictionary时,它的键为HTTP#u VERB,它在JSON结构中变成了HTTP#u VERB,而不是HTTP#u VERB或HTTP#VERB,我希望驼峰大小写会成功 这是我用来重现问题的代码: class Program { static void Main(string[] args) { var settings = new JsonSerializerSettings(); settings.ContractRes
class Program {
static void Main(string[] args) {
var settings = new JsonSerializerSettings();
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
settings.NullValueHandling = NullValueHandling.Ignore;
var headers = new Dictionary<string, string>();
headers["SessionID"] = "123456";
headers["HTTP_VERB"] = "POST";
headers["HTTPVERSION"] = "1";
var data = new
{
headers = headers
};
string serializedEvent = JsonConvert.SerializeObject(data, settings);
if (serializedEvent.Contains("httP_VERB")) {
Console.WriteLine("Something is wrong with this camel case");
}
else {
Console.WriteLine("Sucess");
}
}
}
类程序{
静态void Main(字符串[]参数){
var settings=new JsonSerializerSettings();
settings.ContractResolver=新的CamelCasePropertyNamesContractResolver();
settings.NullValueHandling=NullValueHandling.Ignore;
var headers=newdictionary();
标题[“SessionID”]=“123456”;
标题[“HTTP_动词”]=“POST”;
标题[“HTTPVERSION”]=“1”;
var数据=新
{
标题=标题
};
string serializedEvent=JsonConvert.SerializeObject(数据、设置);
if(serializedEvent.Contains(“httP\u动词”)){
WriteLine(“这个驼色盒子有点问题”);
}
否则{
Console.WriteLine(“成功”);
}
}
}
没有办法让CamelCasePropertyNamesContractResolver
以您想要的方式将字符串转换为CamelCase,但是您可以轻松编写自己的ContractResolver
我在我的项目中使用了PascalCase转换。经过一点调整后,结果如下:
public enum IdentifierCase
{
Camel,
Pascal,
}
public class CustomPropertyNamesContractResolver : DefaultContractResolver
{
private static readonly CultureInfo Culture = CultureInfo.InvariantCulture;
public CustomPropertyNamesContractResolver (bool shareCache = false)
: base(shareCache)
{
Case = IdentifierCase.Camel;
PreserveUnderscores = true;
}
public IdentifierCase Case { get; set; }
public bool PreserveUnderscores { get; set; }
protected override string ResolvePropertyName (string propertyName)
{
return ChangeCase(propertyName);
}
private string ChangeCase (string s)
{
var sb = new StringBuilder(s.Length);
bool isNextUpper = Case == IdentifierCase.Pascal, isPrevLower = false;
foreach (var c in s) {
if (c == '_') {
if (PreserveUnderscores)
sb.Append(c);
isNextUpper = true;
}
else {
sb.Append(isNextUpper ? char.ToUpper(c, Culture) : isPrevLower ? c : char.ToLower(c, Culture));
isNextUpper = false;
isPrevLower = char.IsLower(c);
}
}
return sb.ToString();
}
// Json.NET implementation for reference
private static string ToCamelCase (string s)
{
if (string.IsNullOrEmpty(s) || !char.IsUpper(s[0]))
return s;
var sb = new StringBuilder();
for (int i = 0; i < s.Length; ++i) {
if (i == 0 || i + 1 >= s.Length || char.IsUpper(s[i + 1]))
sb.Append(char.ToLower(s[i], Culture));
else {
sb.Append(s.Substring(i));
break;
}
}
return sb.ToString();
}
}
输出:
camelCase:
{
"sessionId": "123456",
"http_Verb": "POST",
"httpversion": "1"
}
Success
PascalCase:
{
"SessionId": "123456",
"HttpVerb": "POST",
"Httpversion": "1"
}
我需要以相反的顺序解析,即从JSON中的小写下划线属性转换为.NET中的Pascal大小写非下划线属性。Discord的解决方案帮助我做到了这一点:
public class PascalCasePropertyNamesContractResolver : DefaultContractResolver
{
private static readonly CultureInfo Culture = CultureInfo.InvariantCulture;
public PascalCasePropertyNamesContractResolver(bool shareCache = false)
: base(shareCache)
{
}
protected override string ResolvePropertyName(string s)
{
var sb = new StringBuilder(s.Length);
bool isNextUpper = false, isPrevLower = false;
for (var i = 0; i < s.Length; i++)
{
var c = s[i];
sb.Append(char.ToLower(c, Culture));
isNextUpper = i + 1 < s.Length && char.IsUpper(s[i + 1]);
if (isNextUpper && isPrevLower)
{
sb.Append("_");
}
isPrevLower = char.IsLower(c);
}
return sb.ToString();
}
}
公共类PascalCasePropertyNamesContractResolver:DefaultContractResolver
{
私有静态只读CultureInfo Culture=CultureInfo.InvariantCulture;
public PascalCasePropertyNamesContractResolver(bool shareCache=false)
:base(共享缓存)
{
}
受保护的重写字符串ResolvePropertyName(字符串s)
{
var sb=新的StringBuilder(s.长度);
bool isNextUpper=false,isPrevLower=false;
对于(变量i=0;i
这对我很有帮助
var contractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver();
contractResolver.NamingStrategy = new Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy();
settings.ContractResolver = contractResolver;
dynamic deserializedObject = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(requestResult.Content, settings);
var-contractResolver=new-Newtonsoft.Json.Serialization.DefaultContractResolver();
contractResolver.NamingStrategy=new Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy();
settings.ContractResolver=ContractResolver;
dynamic deserializedObject=Newtonsoft.Json.JsonConvert.DeserializeObject(requestResult.Content,settings);
你也可以试试
CamelCaseNamingStrategy()代替SnakeCaseNamingStrategy() 谢谢,你能解释一下为什么HTTP\u动词会导致HTTP\u动词吗?为什么只有前三个字母变成小写?原因是什么?这是由詹姆斯选择的奇怪算法造成的(你可以在答案中看到)。如果下一个字符是大写,它会降低字符。一旦遇到小写字符,就复制字符串的其余部分。如果下划线将被视为大写,它将正常工作。这给了我一个想法,不幸的是,我使用了这个,当我反序列化它时,它对我不起作用。我遇到了这个解决方案(蛇案)。这对我有用,干得好。但是,稍微有点奇怪:您实际上不需要创建(另一个)对静态属性CultureInfo.InvariantCulture的静态引用。如果要阻止循环中对CultureInfo.(get_)InvariantCulture的(属性)函数调用,请使用局部变量:
var Culture=System.Globalization.CultureInfo.InvariantCulture
var contractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver();
contractResolver.NamingStrategy = new Newtonsoft.Json.Serialization.SnakeCaseNamingStrategy();
settings.ContractResolver = contractResolver;
dynamic deserializedObject = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(requestResult.Content, settings);