我不会涉及我尝试过的所有事情......
这正是我想要完成的事情。
public interface IClientDTO {
string FirstName { get; }
string LastName { get; }
}
public class DTO : IClientDTO {
public string FirstName { get; set; }
public string LastName { get; set; }
public string SSN { get; set; }
}
class Program {
static void Main(string[] args) {
DTO dto = new DTO() { FirstName = "John", LastName = "Doe", SSN = "111001111" };
IClientDTO clientDTO = dto;
string sDTO = JsonConvert.SerializeObject(dto);
string sClientDTO = JsonConvert.SerializeObject(clientDTO);
Debug.WriteLine(sDTO);
Debug.WriteLine(sClientDTO);
}
}
我希望我的输出看起来像这样......
{ “SSN”: “111001111”, “姓”: “约翰”, “名字”: “Doe的”}
{ “姓”: “约翰”, “名字”: “Doe的”}
我认为这不会那么困难,但由于Serializer总是将类型确定为DTO,因此即使在我不想要的情况下也总是得到SSN值。
这当然只是一个小小的考验。假设我有一个WebAPI应用程序模拟了这样的东西。
public class AdminController : ApiController {
public DTO Get() { return new Model().DTO); }
}
public class ClientController : ApiController {
public IClientDTO Get() { return new Model().DTO); }
}
我希望Serializer只序列化返回类型中定义的那些项目。
答案 0 :(得分:1)
您可以使用JsonIgnoreAttribute
始终不包含SSN。
public class DTO : IClientDTO {
public string FirstName { get; set; }
public string LastName { get; set; }
[JsonIgnore]
public string SSN { get; set; }
}
如果您想以编程方式确定天气是否包含它,您可以创建两个类 - 具有FirstName,LastName等的基础ClientDTO
。然后是ClientWithSSN
类型,继承自{{ 1}}并且只包含SSN。然后,当选择是否返回SSN时,转换为没有ssn的基本类型或返回实际的ClientDTO
类型。
答案 1 :(得分:1)
我喜欢通过返回的接口控制对象访问。很好,编译器控制访问和可见性。
然而,当涉及到序列化时,编译器不在那里进行裁判。所以我认为我的问题没有实际意义。一旦Json.net序列化器发出......
return base.Serializer._contractResolver.ResolveContract(value.GetType());
这几乎是一个完成的交易。 当然,你可以用东西来捅东西,但是如果你不能在全球范围内根据类型做到这一点,我就不会明白这一点。所以我会根据Cam的建议来做这样的事情。
public interface IClientDTO {
string FirstName { get; }
string LastName { get; }
}
public interface IAdminDTO {
string FirstName { get; }
string LastName { get; }
string SSN { get; }
}
class ClientDTO : IClientDTO {
public string FirstName { get; set; }
public string LastName { get; set; }
}
class AdminDTO : IAdminDTO {
public string FirstName { get; set; }
public string LastName { get; set; }
public string SSN { get; set; }
}
class Model {
class DTO {
public string FirstName { get; set; }
public string LastName { get; set; }
public string SSN { get; set; }
}
private DTO dto = new DTO() { FirstName = "John", LastName = "Doe", SSN = "111001111" };
public IClientDTO ClientDTO { get { return new ClientDTO() { FirstName = dto.FirstName, LastName = dto.LastName }; } }
public IAdminDTO AdminDTO { get { return new AdminDTO() { SSN = dto.SSN, FirstName = dto.FirstName, LastName = dto.LastName }; } }
}
class Program {
static void Main(string[] args) {
Model model = new Model();
string sClientDTO = JsonConvert.SerializeObject(model.ClientDTO);
string sAdminDTO = JsonConvert.SerializeObject(model.AdminDTO);
Debug.WriteLine(sClientDTO);
Debug.WriteLine(sAdminDTO);
}
}
当然它有点笨重和重复,但它仍然允许我通过接口维护访问,我可以让序列化器不受阻碍地做它的事情,我怀疑从长远来看它将更容易维护。
答案 2 :(得分:0)
您可以使用ContractResolver来处理此问题:
private class IgnoreSSNResolver : DefaultContractResolver
{
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
Debug.Write(type.Name);
var properties = base.CreateProperties(type, memberSerialization);
var props = properties.Where((x) => x.PropertyName != "SSN");
return props.ToList();
}
}
然后当你序列化时,你就这样做了:
JsonSerializerSettings sets = new JsonSerializerSettings();
sets.ContractResolver = new IgnoreSSNResolver();
string sClientDTO = JsonConvert.SerializeObject (clientDTO,sets);