I am using C# .NET 4.0 and Newtonsoft JSON 4.5.0.11
[JsonObject(MemberSerialization.OptIn)]
public interface IProduct
{
[JsonProperty(PropertyName = "ProductId")]
int Id { get; set; }
[JsonProperty]
string Name { get; set; }
}
public abstract class BaseEntity<T>
{
private object _id;
public T Id
{
get { return (T)_id; }
set { _id = value; }
}
}
public class Product : BaseEntity<int>, IProduct
{
public string Name { get; set; }
public int Quantity { get; set; }
}
I need to serialize part of object and I use interfaces with declared concrete properties to do this.
The serialization looks like:
Product product = new Product { Id = 1, Name = "My Product", Quantity = 5};
JsonConvert.SerializeObject(product);
Expected result is:
{"ProductId": 1, "Name": "My Product"}
But actual result is:
{"Name": "My Product"}
How can I serialize this object correctly?
UPD: Looked at the source code of json.net and came to the conclusion that this is a bug with grab information about object through ReflectionUtils.
Have you tried this?
public interface IProduct
{
int Id { get; set; }
string Name { get; set; }
}
[JsonObject(MemberSerialization.OptIn)]
public abstract class BaseEntity<T>
{
private object _id;
[JsonProperty]
public T Id
{
get { return (T)_id; }
set { _id = value; }
}
}
[JsonObject(MemberSerialization.OptIn)]
public class Product : BaseEntity<int>, IProduct
{
[JsonProperty]
public string Name { get; set; }
[JsonProperty]
public int Quantity { get; set; }
}
Related
Let's say you have these models:
public class Blog
{
[PrimaryKey]
[AutoIncrement]
public int Id { get; set; }
public string Url { get; set; }
public string PrivateField { get; set; }
[Reference]
public List<BlogToBlogCategory> BlogToBlogCategories { get; set; }
}
public class BlogResponse
{
public int Id { get; set; }
public string Url { get; set; }
public List<BlogToBlogCategory> BlogToBlogCategories { get; set; }
}
And this request:
public class BlogsLookUpRequest : QueryDb<Blog, BlogResponse>
{
}
The return value will have BlogToBlogCategories as null, but this request:
public class BlogsLookUpRequest : QueryDb<Blog>
{
}
Will have BlogToBlogCategories populated. I can manually create the query response like so with custom implementation:
var q = _autoQuery.CreateQuery(request, Request.GetRequestParams(), base.Request);
var results = _autoQuery.Execute(request,q, base.Request);
return new QueryResponse<ResponseBlog>()
{
Results = results.Results.ConvertTo<List<ResponseBlog>>(),
Offset = request.Skip,
Total = results.Total
};
Then it will have the nested results. If I decorate the collection with [Reference] then it is trying to find foreign key on non-existant BlogResponse table.
Why are referenced results removed when specifying a return model with AutoQuery? Is there a way to mark it up so it works?
The POCO Reference Types is used to populate Data Models not adhoc Response DTOs.
In this case it's trying to resolve references on a non-existent table, you can specify which table the DTO maps to with [Alias] attribute, e.g:
[Alias(nameof(Blog))]
public class BlogResponse
{
public int Id { get; set; }
public string Url { get; set; }
public List<BlogToBlogCategory> BlogToBlogCategories { get; set; }
}
Is there a way to change the default {PropertyReference}Id naming convention for references and foreign keys ?
For example, I want to do this :
public class Customer
{
[References(typeof(CustomerAddress))]
public int Id_PrimaryAddress { get; set; } // with a prefix
[Reference]
public CustomerAddress PrimaryAddress { get; set; }
}
instead of that :
public class Customer
{
[References(typeof(CustomerAddress))]
public int PrimaryAddressId { get; set; } // standard
[Reference]
public CustomerAddress PrimaryAddress { get; set; }
}
Thank you
You can't change the code convention of OrmLite's Reference Conventions globally, but you can use the [Alias("DbColumnName")] to map it to a different underlying RDBMS Table column.
Overriding Conventions with Attributes
You're also able to use the Foreign Key and References Attributes as your example does to override the conventions, e.g. you can play with this Live Example on Gistlyn:
public class CustomerAddress
{
[AutoIncrement]
public int Id { get; set; }
public string Address { get; set; }
public string Country { get; set; }
}
public class Customer
{
[AutoIncrement]
public int Id { get; set; }
public string Name { get; set; }
[References(typeof(CustomerAddress))]
public int Id_PrimaryAddress { get; set; } // with a prefix
[Reference]
public CustomerAddress PrimaryAddress { get; set; }
}
db.CreateTable<Customer>();
db.CreateTable<CustomerAddress>();
var customer = new Customer
{
Name = "The Customer",
PrimaryAddress = new CustomerAddress {
Address = "1 Home Street",
Country = "US"
},
};
db.Save(customer, references:true);
Where you can load it and its references and view it with:
var c = db.LoadSelect<Customer>(x => x.Name == "The Customer");
c.PrintDump();
Which will output:
[
{
Id: 1,
Name: The Customer,
Id_PrimaryAddress: 1,
PrimaryAddress:
{
Id: 1,
Address: 1 Home Street,
Country: US
}
}
]
Is it possible mapping two classes based on their similar property names:
class Source {
public int uId { get; set; }
public string PrefixRef { get; set; }
...
}
class Destination {
public int Id { get; set; }
public string Prefix { get; set; }
...
}
Thanks.
UPDATE:
-1, smart alek.
I'm totally new to AutoMapper.
Mapper.Initialize(cfg => {
cfg.RecognizePrefixes(new[] { "u" });
cfg.RecognizePostfixes(new[] { "Ref" });
cfg.CreateMap<Source, Destination>();
});
I have this Party class which contains an object data type coming from a service. It can contain two different member types for the Item property.
public class Party
{
public string DMVID {get; set;}
public object Item { get; set; }
}
and this DTO
public class PartyDTO
{
public string DMVID {get; set;}
public BusinessDTO BusinessItem { get; set; }
public IndividualDTO IndividualItem { get; set; }
}
How can I map the output of the Item to BusinessItem or IndividualItem.
I know this one would not work. Mapper.CreateMap<Party, PartyDTO>();
I don't know if conditional mapping can solve this or a resolver like this one.
Hey maybe this will help you out! I tested it, but i am using AutoMapper just for two days!
Allright here are your noted classes!!!
public class Party
{
public string DMVID { get; set; }
public object Item { get; set; }
}
public class PartyDTO
{
public string DMVID { get; set; }
public BuisnessDTO BusinessItem { get; set; }
public IndividualDTO IndividualItem { get; set; }
}
public class BuisnessDTO
{
public int Number
{
get;
set;
}
}
public class IndividualDTO
{
public string Message
{
get;
set;
}
}
and here your is the MapperConfiguration for this current scenario!
// Edit There was no need here for some conditions
AutoMapper.Mapper.CreateMap<Party, PartyDTO>()
.ForMember(dto => dto.BusinessItem, map =>
map.MapFrom(party => party.Item as BuisnessDTO);
)
.ForMember(dto => dto.IndividualItem, map =>
map.MapFrom(party => party.Item as IndividualDTO);
);
// And this is another way to achive the mapping in this scenario
AutoMapper.Mapper.CreateMap<PartyDTO, Party>()
.ForMember(party => party.Item, map => map.MapFrom( dto => (dto.BusinessItem != null) ? (dto.BusinessItem as object) : (dto.IndividualItem as object)));
And i created this sample for it!
Party firstParty = new Party()
{
DMVID = "something",
Item = new BuisnessDTO()
{
Number = 1
}
};
Party secondParty = new Party()
{
DMVID = "something",
Item = new IndividualDTO()
{
Message = "message"
}
};
PartyDTO dtoWithBuisness = AutoMapper.Mapper.Map<PartyDTO>(firstParty);
PartyDTO dtoWithIndividual = AutoMapper.Mapper.Map < PartyDTO>(secondParty);
Party afterParty = AutoMapper.Mapper.Map<Party>(dtoWithBuisness);
afterParty = AutoMapper.Mapper.Map < Party>(dtoWithIndividual);
Of course there are other possibility, but I think thats exactly what you wanted.
I'd like to be able to have the code below
[Route("/Incidents", "Get")]
public class GetViewConfig
{
public List<Filter> Filters { get; set; }
}
public class Filter
{
public string Property { get; set; }
public FilterType Type { get; set; }
public string Value { get; set; }
}
public enum FilterType
{
IsBetween,
Is,
IsNot
}
public class GetViewConfigResponse
{
public List<Filter> Filters { get; set; }
}
public class ViewConfigService : Service
{
public object Get(GetViewConfig request)
{
return null;
}
}
Show all the values for the FilterType on the metadata page. Is there a way to do this?
Not on the metadata pages, but you can view this using the Swagger API and the [ApiAllowableValues] attribute, e.g:
[Api("Service Description")]
[Route("/swagger/{Name}", "GET", Summary = #"GET Summary", Notes = "GET Notes")]
public class MyRequestDto
{
[ApiMember(Name="Name", Description = "Name Description",
ParameterType = "path", DataType = "string", IsRequired = true)]
[ApiAllowableValues("Name", typeof(Color))] //Enum
public string Name { get; set; }
}