是否有简单的方法在.NET中使用JSON来确保密钥以小写形式发送?
目前我正在使用newtonsoft的Json.NET库并且只是使用
string loginRequest = JsonConvert.SerializeObject(auth);
Run Code Online (Sandbox Code Playgroud)
在这种情况下auth只是以下对象
public class Authority
{
public string Username { get; set; }
public string ApiToken { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
这导致了
{"Username":"Mark","ApiToken":"xyzABC1234"}
Run Code Online (Sandbox Code Playgroud)
有没有办法确保username和apitoken键以小写形式出现?
我不想简单地通过运行它String.ToLower(),当然,因为价值观username和apitoken是混合的情况.
我意识到我可以以编程方式执行此操作并手动创建JSON字符串,但我需要大约20个左右的JSON数据字符串,我看到我是否可以节省一些时间.我想知道是否有任何已经构建的库允许您强制使用小写来创建密钥.
我们在使用Microsoft JSON序列化程序和JSON.NET的MVC3项目中遇到了这种情况.
每个人都知道DateTime在Microsoft的序列化程序中基本上被打破了,所以我们切换到JSON.NET来避免这个问题.这很好用,除了我们尝试序列化的一些类是具有DataContract/DataMember属性的POCO.它们在多个位置引用的程序集中定义.此外,它们还具有一些其他显示属性,这些属性未标记为DataMembers以提高效率.例如,客户
[DataContract]
public class Customer
{
[DataMember]
public string FirstName { get; set;}
[DataMember]
public string LastName { get; set;}
public string FullName
{
get
{ return FirstName + " " + LastName; }
}
}
Run Code Online (Sandbox Code Playgroud)
当这个客户通过WCF传递时,客户端可以引用该程序集并使用FullName就好了,但是当使用JSON.NET序列化时,它会看到FullName不是a [DataMember]并且不会序列化它.是否可以选择传递给JSON.NET,告诉它忽略类已[DataContract]应用属性的事实?
注意: 在.NET中使用JavaScriptSerializer可以很好地处理FullName属性,但DateTimes会被破坏.我需要JSON.NET忽略这个类具有DataContract/DataMember属性的事实,并且只是执行标准的公共字段序列化,就像它们不在那里一样.
在Json.NET中,如何在反序列化时使所有属性成为必需?我知道我可以使用消息上的属性来执行此操作,但我不想这样做.主要是因为它需要我的消息库来承担外部依赖.
我尝试了MissingMemberHandling.Error设置,但它与我想要的完全相反.我对JSON有额外的属性没关系.我希望它在JSON中缺少任何目标对象属性时失败.
我实际上反序列化为F#记录,无论如何,属性通常不能为null.(它们不能通过代码中的常规方式赋值为null.)但是当数据丢失时,Json.NET很乐意将属性默认为null.
接受答案的F#版本
分解器
open System
open Newtonsoft.Json
open Newtonsoft.Json.Serialization
type RequireAllPropertiesContractResolver() =
inherit DefaultContractResolver()
override me.CreateObjectContract(objectType:Type) =
let contract = base.CreateObjectContract(objectType)
contract.ItemRequired <- new Nullable<Required>(Required.Always)
contract
Run Code Online (Sandbox Code Playgroud)
在设置中
let settings = new JsonSerializerSettings() // default settings
...
settings.ContractResolver <- new RequireAllPropertiesContractResolver()
Run Code Online (Sandbox Code Playgroud) 我有一个类定义如下的场景:
class MyObject
{
public DataDictionary MyObjectData { get; set; }
public bool ShouldSerializeMyObjectData() { return true; }
public bool ShouldDeserializeMyObjectData() { return false; }
}
Run Code Online (Sandbox Code Playgroud)
当我尝试使用JSON.net序列化/反序列化该类时,它会考虑ShouldSerialize,但不会考虑ShouldDeserialize.
根据文档,两者都应该像我猜的那样工作.有什么特别值得我知道的吗?更一般地说,我应该如何处理我想要序列化属性但不反序列化它的场景?
我正在使用,Json.NET 8.0如果这很重要.
谢谢你的帮助.
有没有办法告诉JSON.net当它尝试使用构造函数反序列化时(如果没有默认构造函数),它不应该为构造函数参数赋值默认值,并且它应该只调用构造函数,如果每个构造函数参数是用JSON字符串表示?同一个序列化程序在调用属性/字段设置器时应该使用默认值,规则只限于构造函数.这里的枚举值似乎都不合适:http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_DefaultValueHandling.htm
解决方案不应该依赖于对要反序列化的类型应用任何属性.
例如,通过将Dog的age设置为0(int的默认值),json字符串"{}"将反序列化为类型的对象Dog.我想要一个通用的,不基于属性的解决方案来防止这种情况发生.在这种情况下,{"age":4}将工作因为age在JSON字符串中指定并对应于构造函数参数.
public class Dog
{
public Dog(int age)
{
this.Age = age;
}
public int Age { get; }
}
Run Code Online (Sandbox Code Playgroud)
但是,如果Dog指定为这样,那么"{}" 应该反序列化为具有Age == 0的Dog,因为Dog不是使用构造函数创建的.
public class Dog
{
public int Age { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
并且要避免任何关于"你为什么要这样做"的问题......带有构造函数的对象通常在质量上与POCO不同,因为它与它们的属性有关.使用构造函数在POCO上存储属性值而不是可设置属性通常意味着您要验证/约束属性值.因此,在存在constuctor的情况下不允许使用默认值进行反序列化是合理的.
我有一个具有自定义的类,如下所示JsonConverter:
[JsonConverter(typeof(TheShapeSerializer))]
public class TheShape : IShape {
//....
}
Run Code Online (Sandbox Code Playgroud)
我不能改变班级。自定义序列化器的工作方式不适合我的需求。
有没有一种方法可以使用默认的序列化程序而不是TheShapeSerializer来序列化TheShape的实例?
同样,是否有一种方法可以让多个转换器根据给定条件在串行化时间选择?
我正在使用 Json.Net 来序列化一些应用程序数据。当然,应用规范略有变化,我们需要重构一些业务对象数据。将以前序列化的数据迁移到我们的新数据格式有哪些可行的策略?
例如,假设我们最初有一个业务对象,如:
public class Owner
{
public string Name {get;set;}
}
public class LeaseInstrument
{
public ObservableCollection<Owner> OriginalLessees {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
我们使用 Json.Net 将 LeaseInstrument 的一个实例序列化为一个文件。现在,我们将业务对象更改为如下所示:
public class Owner
{
public string Name {get;set;}
}
public class LeaseOwner
{
public Owner Owner { get;set;}
public string DocumentName {get;set;}
}
public class LeaseInstrument
{
public ObservableCollection<LeaseOwner> OriginalLessees {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
我曾考虑为 LeaseInstrument 编写自定义 JsonConverter,但从未命中 ReadJson 方法……而是在反序列化器到达该点之前抛出异常:
Additional information: Type specified in JSON
'System.Collections.ObjectModel.ObservableCollection`1[[BreakoutLib.BO.Owner,
BreakoutLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]],
System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' …Run Code Online (Sandbox Code Playgroud) 我遇到了一种奇怪的情况,我IgnoreDataMember没有做这项工作,但却JsonIgnore做了。
在本例中,我从具有属性的类继承public {get; set;},并且选择使用NotSupportedException. 我只希望序列化程序能够设置属性,而不是用户,但我希望用户能够获取它,所以我做了以下操作:
[DataContract]
public class BaseObject : BaseInterface
{
[DataMember]
public virtual double information { get; set; }
}
[DataContract]
public class ServerGeneratedObject : BaseObject
{
[IgnoreDataMember]
public override double information {
get { return server_set_information; }
set { throw new NotSupportedException("Server generated property"); }
}
[DataMember(Name="information")]
private double server_set_information { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,这会引发错误“‘ServerGenerateObject’上已存在名为‘information’的成员。请使用 JsonPropertyAttribute 指定另一个名称。”
但是,如果我使用 [JsonIgnore] 属性,则这将按预期工作。这似乎是由于数据契约解析器的这一部分造成的(代码当前位于此处):
bool flag2 = JsonTypeReflector.GetAttribute<JsonIgnoreAttribute>(attributeProvider) != null …Run Code Online (Sandbox Code Playgroud) 我正在尝试序列化/反序列化Dictionary<string, object>C#。对象可以是任何可序列化的对象。
Json.NET几乎可以工作,但是如果字典中的值是an enum,则反序列化是不正确的,因为它反序列化为a long。TypeNameHandling.All没有任何区别。
序列化库是否有其他快速解决方案。结果不必是JSON,而必须是文本。
我对传递到字典的数据也没有影响。我只需要对遇到的任何问题进行序列化和反序列化。
编辑:StringEnumConverter没有帮助。数据被转换回Dictionary<string, object>,因此解串器不知道序列化的值是enum。它像对待对象一样对待它,反序列化后StringEnumConverter它仍然是一个对象string。如果long没有转换器,它将反序列化。JSON.NET不会保留枚举。
我要提供的解决方案是现有接口的实现,该接口被注入到我无法更改的现有解决方案中。
EDIT2:这是我正在尝试做的一个例子
public enum Foo { A, B, C }
public enum Bar { A, B, C }
public class Misc { public Foo Foo { get; set; } }
var dict = new Dictionary<string, object>();
dict.Add("a", Foo.A);
dict.Add("b", Bar.B);
dict.Add("c", new Misc());
// serialize dict to a string s
// deserialize s …Run Code Online (Sandbox Code Playgroud) 假设我有一个这样的类:
public class Example {
public int TypedProperty { get; set; }
public object UntypedProperty { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
假设有人出现并写道:
var example = new Example
{
TypedProperty = 5,
UntypedProperty = Guid.NewGuid()
}
Run Code Online (Sandbox Code Playgroud)
如果我用 序列化它JsonConvert.SerializeObject(example),我得到
{
"TypedProperty": 5,
"UntypedProperty": "24bd733f-2ade-4374-9db6-3c9f3d97b12c"
}
Run Code Online (Sandbox Code Playgroud)
理想情况下,我想得到这样的东西:
{
"TypedProperty": 5,
"UntypedProperty":
{
"$type": "System.Guid,mscorlib",
"$value": "24bd733f-2ade-4374-9db6-3c9f3d97b12c"
}
}
Run Code Online (Sandbox Code Playgroud)
但TypeNameHandling在这种情况下不起作用。如何(反)序列化非类型化属性?
json.net ×9
c# ×8
json ×4
.net ×3
.net-4.5 ×1
datacontract ×1
datamember ×1
enums ×1
versioning ×1