public class Person { public string FirstName { get; set; } public string LastName { get; set; } public int Age { get; set; } public UserName UserName { get; set; } }
例如:
[Route("api/person")] [AcceptVerbs("POST")] public void UpdatePerson(Person person) { // etc. }
public class UserName { private readonly string value; public UserName(string value) { this.value = value; } public static implicit operator string (UserName d) { return d != null ? d.ToString() : null; } public static implicit operator UserName(string d) { return new UserName(d); } public override string ToString() { return value != null ? value.ToUpper().ToString() : null; } public static bool operator ==(UserName a, UserName b) { // If both are null, or both are same instance, return true. if (System.Object.ReferenceEquals(a, b)) return true; // If one is null, but not both, return false. if (((object)a == null) || ((object)b == null)) return false; return a.Equals(b); } public static bool operator !=(UserName a, UserName b) { return !(a == b); } public override bool Equals(object obj) { if ((obj as UserName) == null) return false; return string.Equals(this, (UserName)obj); } public override int GetHashCode() { string stringValue = this.ToString(); return stringValue != null ? stringValue.GetHashCode() : base.GetHashCode(); } }
// Global Json.Net config settings. JsonConvert.DefaultSettings = () => { var settings = new JsonSerializerSettings(); // replace UserNameConverter with whatever the name is for your converter below settings.Converters.Add(new UserNameConverter()); return settings; };
这是一个应该工作(未经测试)的快速和基本的实现。 几乎可以肯定的是:
public class UserNameConverter : JsonConverter { public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { var username = (UserName)value; writer.WriteStartObject(); writer.WritePropertyName("UserName"); serializer.Serialize(writer, username.ToString()); writer.WriteEndObject(); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { // Variables to be set along with sensing variables string username = null; var gotName = false; // Read the properties while (reader.Read()) { if (reader.TokenType != JsonToken.PropertyName) { break; } var propertyName = (string)reader.Value; if (!reader.Read()) { continue; } // Set the group if (propertyName.Equals("UserName", StringComparison.OrdinalIgnoreCase)) { username = serializer.Deserialize(reader); gotName = true; } } if (!gotName) { throw new InvalidDataException("A username must be present."); } return new UserName(username); } public override bool CanConvert(Type objectType) { return objectType == typeof(UserName); } }
namespace MyNamespace.MyProject { public class Person { public string FirstName { get; set; } public string LastName { get; set; } public int Age { get; set; } public UserName UserName { get; set; } } }
您的服务层对象:
namespace MyNamespace.MyProject.Service.Models { public class Person { public string FirstName { get; set; } public string LastName { get; set; } public int Age { get; set; } //The service contract expects username to be a string. public string UserName { get; set; } } }
[Route("api/person")] [HttpPost] public void UpdatePerson(Models.Person person) { var mappedPerson = Mapper.Map(person); personRepository.Update(mappedPerson); //I'd suggest returning some type of IHttpActionResult here, even if it's just a status code. }
//This gets called once somewhere when the application is starting. public static void Configure() { // Mapper.Create() //Additional mappings. .ForMember(dest => dest.Username, opt => opt.MapFrom(src => new UserName(src.UserName))) }
此外,您可能需要使用Singleton,Service Locator或Inversion of Control(IoC)容器(如Ninject)来获取对personRepository的引用。 我强烈建议使用IoC。 Ninject有一个包可以接管为WebAPI创建控制器,注入您已配置的依赖项。