I'm trying to deserialize a json like this
{
"geneslist": [
{
"seqid": "NC_045512.2",
"source": "RefSeq",
"type": "region",
"start": "1",
"end": "29903",
"score": ".",
"strand": "+",
"phase": ".",
"attributes": "ID=NC_045512.2:1..29903;Dbxref=taxon:2697049;collectiondate=Dec-2019;country=China;gbacronym=SARS-CoV2;gbkey=Src;genome=genomic;isolate=Wuhan-Hu-1;mol_type=genomic RNA;nathost=Homo sapiens;oldname=Wuhan seafood market pneumonia virus",
"ID": "NC_045512.2:1..29903",
"Note": null,
"Dbxref": "taxon:2697049",
"collectiondate": "Dec-2019",
"country": "China",
"gbacronym": "SARS-CoV2",
"gbkey": "Src",
"gene": null,
"inference": null,
"genome": "genomic",
"isolate": "Wuhan-Hu-1",
"locus_tag": null,
"gene_biotype": null,
"product": null,
"protein_id": null,
"mol_type": "genomic RNA",
"nathost": "Homo sapiens",
"oldname": "Wuhan seafood market pneumonia virus"
},
{
"seqid": "NC_045512.2",
"source": "RefSeq",
"type": "five_prime_UTR",
"start": "1",
"end": "265",
"score": ".",
"strand": "+",
"phase": ".",
"attributes": "ID=id-NC_045512.2:1..265;gbkey=5'UTR",
"ID": "id-NC_045512.2:1..265",
"Note": null,
"function": null,
"Dbxref": null,
"collectiondate": null,
"country;": null,
"gbkey": "5'UTR",
"Dbxrref": null,
"country": null,
"gbacronym": null,
"gene": null,
"inference": null,
"genome": null,
"isolate": null,
"locus_tag": null,
"gene_biotype": null,
"product": null,
"protein_id": null,
"mol_type": null,
"nathost": null,
"oldname": null
},{..} ]
}
where some data might be null or existing, I made two objects for this:
public class GenesList
{
private string seqid;
private string source;
private string type;
private int start;
private int end;
private string score;
private string strand;
private string phase;
private string attributes;
private string ID;
private string Note;
private string function;
private string Dbxref;
private string collectiondate;
private string country;
private string gbacronym;
private string gbkey;
private string gene;
private string inference;
private string genome;
private string isolate;
private string locus_tag;
private string gene_biotype;
private string product;
private string protein_id;
private string mol_type;
private string nathost;
private string oldname;
public string Seqid { get => seqid; set => seqid = value; }
public string Source {get => source; set => source = value; }
public string Type { get => type; set => type = value; }
public int Start { get => start; set => start = value; }
public int End { get => end; set => end = value; }
public string Score { get => score; set => score = value; }
public string Strand { get => strand; set => strand = value; }
public string Phase { get => phase; set => phase = value; }
public string Attributes { get => attributes; set => attributes = value; }
public string ID1 { get => ID; set => ID = value; }
public string Dbxref1 { get => Dbxref; set => Dbxref = value; }
public string Collectiondate { get => collectiondate; set => collectiondate = value; }
public string Country { get => country; set => country = value; }
public string Gbacronym { get => gbacronym; set => gbacronym = value; }
public string Gbkey { get => gbkey; set => gbkey = value; }
public string Genome { get => genome; set => genome = value; }
public string Isolate { get => isolate; set => isolate = value; }
public string Mol_type { get => mol_type; set => mol_type = value; }
public string Nathost { get => nathost; set => nathost = value; }
public string Oldname { get => oldname; set => oldname = value; }
public string Locus_tag { get => locus_tag; set => locus_tag = value; }
public string Gene_biotype { get => gene_biotype; set => gene_biotype = value; }
public string Function { get => function; set => function = value; }
public string Inference { get => inference; set => inference = value; }
public string Product { get => product; set => product = value; }
public string Protein_id { get => protein_id; set => protein_id = value; }
public string GetGene()
{
return gene;
}
public void SetGene(string value)
{
gene = value;
}
}
and
public class GenesWrapper
{
private List<GenesList> geneslist;
public List<GenesList> Genes { get => geneslist; set => geneslist = value; }
}
but when I'm trying to deserialize with
GenesWrapper genesList = new GenesWrapper();
genesList = JsonConvert.DeserializeObject<GenesWrapper>(file2);
I'm getting an ArgomentNullException because the object is null after deserializing, did I build a bad object? At first I tought it could have had some problems with the null values or maybe the order the json file has been made. I used NullValueHandling.Ignore but the values are still null, how can I solve?
Sorry for the wall of text, thank you
This cannot work. Your json is not suitable for creating C# classes. The property "country" occurs two times in your one (the second one) json object.
"country;": null,
"gbkey": "5'UTR",
"Dbxrref": null,
"country": null,
Moreover, visual studio can create the code for you to prevent human errors. Just create the C# code like this, and it will be fine.
you can do this instead :
public class GenesList
{
[JsonProperty("seqid")]
public string Seqid { get; set; }
[JsonProperty("source")]
public string Source { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("start")]
[JsonConverter(typeof(ParseStringConverter))]
public int Start { get; set; }
[JsonProperty("end")]
[JsonConverter(typeof(ParseStringConverter))]
public int End { get; set; }
[JsonProperty("score")]
public string Score { get; set; }
[JsonProperty("strand")]
public string Strand { get; set; }
[JsonProperty("phase")]
public string Phase { get; set; }
[JsonProperty("attributes")]
public string Attributes { get; set; }
[JsonProperty("ID")]
public string Id { get; set; }
[JsonProperty("Note")]
public string Note { get; set; }
[JsonProperty("Dbxref")]
public string Dbxref { get; set; }
[JsonProperty("collectiondate")]
public string Collectiondate { get; set; }
[JsonProperty("country")]
public string Country { get; set; }
[JsonProperty("gbacronym")]
public string Gbacronym { get; set; }
[JsonProperty("gbkey")]
public string Gbkey { get; set; }
[JsonProperty("gene")]
public string Gene { get; set; }
[JsonProperty("inference")]
public string Inference { get; set; }
[JsonProperty("genome")]
public string Genome { get; set; }
[JsonProperty("isolate")]
public string Isolate { get; set; }
[JsonProperty("locus_tag")]
public string LocusTag { get; set; }
[JsonProperty("gene_biotype")]
public string GeneBiotype { get; set; }
[JsonProperty("product")]
public string Product { get; set; }
[JsonProperty("protein_id")]
public string ProteinId { get; set; }
[JsonProperty("mol_type")]
public string MolType { get; set; }
[JsonProperty("nathost")]
public string Nathost { get; set; }
[JsonProperty("oldname")]
public string Oldname { get; set; }
}
Then use JObject to navigate to the geneslist, and then just get the string to deserilize it. Something like this :
var jObj = JObject.Parse(json);
var genes = jObj["geneslist"].ToString();
var genesList = JsonConvert.DeserializeObject<List<GenesList>>(genes);
That's if you need to only deserilize geneslist and ignore the rest of the json. If you want to deserilize the whole json keys, you'll need a wrapper class that would define each property in the json root. Something like this :
public class JsonWrapper
{
[JsonProperty("geneslist")]
public IEnumerable<GenesList> Genes { get; set; }
// ... other json keys..
}
Then, you can do this directly :
var genes = JsonConvert.DeserializeObject<JsonWrapper>(json);
Related
I've already made a similar application and these relationships worked - but I decided to make one change. Namely, the user can be both a dog walker and an owner. At this point the database does not want to update even though the migration is being created - (I'm using code first EF). This error pops up
Introducing FOREIGN KEY constraint 'FK_dbo.OwnerAdverts_dbo.Dogs_DogId' on table 'OwnerAdverts' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints. Could not create constraint or index. See previous errors.
This is how my classes look like - there are more of them, of course, but I present those that should have relations. The Dog should have a relationship with the User, as the** User** is its Owner (there can be no dog without an owner, but an owner without a dog). Then an advertisement(OwnerAdvert) is created, where the Dog is transferred to him. In addition, there is also an announcement of the walker(WalkerAdvert) to which the User is passed. -As I wrote, a user can be both a walker and an owner.
public class User:DOGModel
{
private int userId;
private string userName;
private string userSurname;
private EnumGender userGender;
private string userEmail;
private string userPassword;
private DateTime userDateOfBirth;
private string userPhone;
[Key]
public int UserId { get => userId; set => userId = value; }
public string UserName { get => userName; set => userName = value; }
public string UserSurname { get => userSurname; set => userSurname = value; }
public EnumGender UserGender { get => userGender; set => userGender = value; }
public string UserEmail { get => userEmail; set => userEmail = value; }
public string UserPassword { get => userPassword; set => userPassword = value; }
public DateTime UserDateOfBirth { get => userDateOfBirth; set => userDateOfBirth = value; }
public string UserPhone { get => userPhone; set => userPhone = value; }
public virtual List<WalkerAdvert> advert { get; set; }
public User()
{
UserId = 0;
UserId++;
}
public User(string userName, string userSurname, EnumGender userGender, string userEmail, string userPassword, string userDateOfBirth, string userPhone):this()
{
UserName = userName;
UserSurname = userSurname;
UserGender = userGender;
UserEmail = userEmail;
UserPassword = userPassword;
DateTime.TryParseExact(userDateOfBirth, new[] { "yyyy-MM-dd", "yyyy/MM/dd", "MM/dd/yy", "dd-MMM-yy" }, null, DateTimeStyles.None, out DateTime date);
UserDateOfBirth = date;
UserPhone = userPhone;
public class Dog
{
private int dogId;
private string dogName;
private string dogDescription;
private EnumSize dogSize;
private EnumActivityDemand dogActivityDemand;
private EnumDogGender dogGender;
private string dogBreed;
private DateTime dogDateOfBirth;
[Key]
public int DogId { get => dogId; set => dogId = value; }
public string DogName { get => dogName; set => dogName = value; }
public string DogDescription { get => dogDescription; set => dogDescription = value; }
public EnumSize DogSize { get => dogSize; set => dogSize = value; }
public EnumActivityDemand DogActivityDemand { get => dogActivityDemand; set => dogActivityDemand = value; }
public EnumDogGender DogGender { get => dogGender; set => dogGender = value; }
public string DogBreed { get => dogBreed; set => dogBreed = value; }
public DateTime DogDateOfBirth { get => dogDateOfBirth; set => dogDateOfBirth = value; }
[Required]
public virtual User DogOwner { get; set; }
[Required]
public int UserId { get; set; }
public virtual List<OwnerAdvert> advert { get; set; }
public Dog()
{
DogId= 0;
DogId++;
}
public Dog(string dogName, string dogDescription, EnumSize dogSize, EnumActivityDemand dogActivityDemand, EnumDogGender dogGender, string dogBreed, string dogDateOfBirth, User dogOwner):this()
{
DogName = dogName;
DogDescription = dogDescription;
DogSize = dogSize;
DogActivityDemand = dogActivityDemand;
DogGender = dogGender;
DogBreed = dogBreed;
DateTime.TryParseExact(dogDateOfBirth, new[] { "yyyy-MM-dd", "yyyy/MM/dd", "MM/dd/yy", "dd-MMM-yy" }, null, DateTimeStyles.None, out DateTime date);
DogDateOfBirth = date;
DogOwner = dogOwner;
}
public class OwnerAdvert:DOGModel
{
private int ownerAdvertId;
private string ownerAdvertCity;
private string ownerAdvertTitle;
private string ownerAdvertDescription;
private string ownerAdvertAmount;
private DateTime ownerAdvertDateAdded;
private DateTime ownerAdvertDateOfSerice;
private int ownerAdvertWalkingTime;
[Key]
public int OwnerAdvertId { get => ownerAdvertId; set => ownerAdvertId = value; }
public string OwnerAdvertCity { get => ownerAdvertCity; set => ownerAdvertCity = value; }
public string OwnerAdvertTitle { get => ownerAdvertTitle; set => ownerAdvertTitle = value; }
public string OwnerAdvertDescription { get => ownerAdvertDescription; set => ownerAdvertDescription = value; }
public string OwnerAdvertAmount { get => ownerAdvertAmount; set => ownerAdvertAmount = value; }
public DateTime OwnerAdvertDateAdded { get => ownerAdvertDateAdded; set => ownerAdvertDateAdded = value; }
public DateTime OwnerAdvertDateOfSerice { get => ownerAdvertDateOfSerice; set => ownerAdvertDateOfSerice = value; }
public int OwnerAdvertWalkingTime { get => ownerAdvertWalkingTime; set => ownerAdvertWalkingTime = value; }
public virtual Dog Dog { get; set; }
public int DogId { get; set; }
public OwnerAdvert()
{
OwnerAdvertId = 0;
OwnerAdvertId++;
}
public OwnerAdvert( Dog ownerAdvertDog, string ownerAdvertCity, string ownerAdvertTitle, string ownerAdvertDescription, string ownerAdvertAmount, DateTime ownerAdvertDateAdded, DateTime ownerAdvertDateOfSerice, int ownerAdvertWalkingTime):this()
{
Dog = ownerAdvertDog;
OwnerAdvertCity = ownerAdvertCity;
OwnerAdvertTitle = ownerAdvertTitle;
OwnerAdvertDescription = ownerAdvertDescription;
OwnerAdvertAmount = ownerAdvertAmount;
OwnerAdvertDateAdded = ownerAdvertDateAdded;
OwnerAdvertDateOfSerice = ownerAdvertDateOfSerice;
OwnerAdvertWalkingTime = ownerAdvertWalkingTime;
}
public class WalkerAdvert
{
private int walkerAdvertId;
private string walkerAdvertTitle;
private string walkerAdvertCity;
private decimal walkerAdvertAmount;
private string walkerAdvertDescription;
private DateTime walkerAdvertDateAdded;
public string WalkerAdvertTitle { get => walkerAdvertTitle; set => walkerAdvertTitle = value; }
public string WalkerAdvertCity { get => walkerAdvertCity; set => walkerAdvertCity = value; }
public decimal WalkerAdvertAmount { get => walkerAdvertAmount; set => walkerAdvertAmount = value; }
public string WalkerAdvertDescription { get => walkerAdvertDescription; set => walkerAdvertDescription = value; }
public DateTime WalkerAdvertDateAdded { get => walkerAdvertDateAdded; set => walkerAdvertDateAdded = value; }
[Key]
public int WalkerAdvertId { get => walkerAdvertId; set => walkerAdvertId = value; }
public virtual User Walker { get; set; }
public int UserId { get; set; }
public WalkerAdvert()
{
WalkerAdvertId = 0;
WalkerAdvertId++;
}
public WalkerAdvert(string walkerAdvertTitle, string walkerAdvertCity, decimal walkerAdvertAmount, string walkerAdvertDescription, DateTime walkerAdvertDateAdded, User walkerAdvertWalker) : this()
{
WalkerAdvertTitle = walkerAdvertTitle;
WalkerAdvertCity = walkerAdvertCity;
WalkerAdvertAmount = walkerAdvertAmount;
WalkerAdvertDescription = walkerAdvertDescription;
WalkerAdvertDateAdded = walkerAdvertDateAdded;
Walker = walkerAdvertWalker;
}
Similar questions have already happened, but I can't quite reproduce them on my example, I also attach what the DOGModel looks like
public class DOGModel : DbContext
{
// Your context has been configured to use a 'DOGModel' connection string from your application's
// configuration file (App.config or Web.config). By default, this connection string targets the
// 'DOGAppModern.DOGModel' database on your LocalDb instance.
//
// If you wish to target a different database and/or database provider, modify the 'DOGModel'
// connection string in the application configuration file.
public DOGModel()
: base("name=DOGModel")
{
}
public virtual DbSet<User> Users { get; set; }
public virtual DbSet<Dog> Dogs { get; set; }
public virtual DbSet<OwnerAdvert> OwnerAdverts { get; set; }
public virtual DbSet<WalkerAdvert> WalkerAdverts { get; set; }
}
when im trying to desrialize to abstract class list,The Genres property in Book class stay Null, While in Journal class its get the value from my json file.
string folderPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
using (FileStream streamFile = File.Open($"{folderPath}//products10.json", FileMode.OpenOrCreate))
{
using (StreamReader reader = new StreamReader(streamFile))
{
string fileContent = reader.ReadToEnd();
productsList = JsonConvert.DeserializeObject<List<ProductBase>>(fileContent,ProductBase.StrandartJsonConvert);
}
}
This is the JSON file:
[
{
"EditorName":"Me",
"Name":"DailyMail",
"IssueNumber":4,
"Genres":[1],
"Frequency":0,
"Id":"01c26581-3e3a-4bc2-bc97-dfbab0215f29",
"Description":"DailyMail",
"PublicationDate":"2022-01-19T12:44:32.57574+02:00",
"BasePrice":15.0,
"Type":"Journal"
},
{
"AuthorName":"Author",
"Title":"HarryPotter",
"Edition":3,
"Geners":[2,1],
"Synopsis":null,
"Id":"6674b82d-6d6d-49ac-9c92-7d84b0dd09b6",
"Description":"HarryPotter",
"PublicationDate":"2022-01-19T12:44:30.2413124+02:00",
"BasePrice":35.0,
"Type":"Book"
}
]
While in my journal class everything get in, in my book class - it isn't, it looks like the deserializtion ignores the Genres property.
public class Journal : ProductBase
{
public string EditorName { get; set; }
public string Name
{
get { return base.Description; }
set { base.Description = value; }
}
public int IssueNumber { get; set; }
public ICollection<JournalGenre> Genres { get; set; }
public JournalFrequency Frequency { get; set; }
public Journal(string editorName, string name, int issueNumber, DateTime publicationDate,
decimal basePrice, JournalFrequency frequency, params JournalGenre[] genres)
: base(name, publicationDate, basePrice)
{
this.EditorName = editorName;
this.IssueNumber = issueNumber;
this.Frequency = frequency;
this.Genres = genres.ToList();
}
}
here all the properties get the values.
public class Book : ProductBase
{
public string AuthorName { get; set; }
public string Title
{
get { return base.Description; }
set { base.Description = value; }
}
public int Edition { get; set; }
public ICollection<BookGenre> Geners { get; set; }
public string Synopsis { get; set; }
public Book(string authorName, string title, DateTime publicationDate, decimal basePrice, int edition = 1, params BookGenre[] genres)
:base(title, publicationDate, basePrice)
{
this.AuthorName = authorName;
this.Edition = edition;
this.Geners = genres.ToList();
}
}
but here the Genres stays null - the 'genres' in the const isnt get the value from the JSON file - only this prop. anything else get value.
Not sure why #JamesS deleted his answer, but he's right - the property in the JSON file is Geners for your Book, but the constructor parameter is genres.
Either correct the spelling of the property on the class and in the JSON file to Genres:
public class Book : ProductBase
{
...
public ICollection<BookGenre> Genres { get; set; }
{
"AuthorName":"Author",
"Title":"HarryPotter",
"Edition":3,
"Genres":[2,1],
"Synopsis":null,
"Id":"6674b82d-6d6d-49ac-9c92-7d84b0dd09b6",
"Description":"HarryPotter",
"PublicationDate":"2022-01-19T12:44:30.2413124+02:00",
"BasePrice":35.0,
"Type":"Book"
}
Or change the spelling of the constructor parameter to match the name used in the JSON file:
public Book(
string authorName,
string title,
DateTime publicationDate,
decimal basePrice,
int edition = 1,
params BookGenre[] geners)
I was doing mapping with wildcards. I get this error because the definition of the rule to be searched only comes from a table.
I do not know exactly how right I am doing this here, but as a result I have a mistake and I expect your help.
public class Ekstre
{
private readonly DataClasses1DataContext db = new DataClasses1DataContext();
private readonly KdrGnyClassesDataContext kg = new KdrGnyClassesDataContext();
public bool check { get; set; }
public int Id { get; set; }
public DateTime Tarih { get; set; }
public string Kodu { get; set; }
public string Açıklama { get; set; }
public decimal Tutar { get; set; }
public string bankaKod { get; set; }
private string kod = null;
public string muhKod {
get { return kod = kg.kuralTanimlari
.FirstOrDefault(a => Regex.IsMatch(Açıklama, WildCardToRegular(a.kural))).hesapKodu;
}
set { kod = value; }
}
private string hesap = null;
public string hesapAdi {
get {
hesap = !string.IsNullOrWhiteSpace(muhKod) ? db.MUHHESAP.First(p => p.MUHKOD == muhKod).MUHADI1 : null;
return hesap;
}
set => hesap = value;
}
public string kodTipi { get; set; }
}
public static string WildCardToRegular(string value)
{
return "^" + Regex.Escape(value).Replace("\\?", ".").Replace("\\*", ".*") + "$";
}
You can only use supported functions on dbcontext queries over IQuerable.
You have two options
1. Fire db query by doing ToList() or ToArray() and then .FirstOrDefault(.....)
This has a drawback that it will fetch all records from db and then apply your
function to results.
Convert your filtering function to a simple sql supported function. As far as i know Regex is not supported in entity framework
public string muhKod {
get
{
var firstOrDefault = kg.kuralTanimlari.ToList()
.FirstOrDefault(a => Regex.IsMatch(Açıklama, WildCardToRegular(a.kural)));
if (firstOrDefault != null)
kod = firstOrDefault.hesapKodu;
return kod;
}
set => kod = value;
}
It works so beautifully. Thank you.
I'm getting this exception:
Missing type map configuration or unsupported mapping.
Mapping types:
FollowUpActivityDTO -> Nullable1
LEST.Model.FollowUpActivityDTO -> System.Nullable1[[System.DateTime, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]
Destination path:
List`1[0]
Source value:
class FollowUpActivityDTO {
Id: 75e83860-65e4-11e5-9a90-382c4ab9e433
Timestamp: 28/09/2015 11:28:55
StartTimestamp: 28/09/2015 15:26:00
DueTimestamp: 28/09/2015 15:26:00
ClosingTimestamp: 28/09/2015 15:26:00
Matter: elasticsearch - copia - copia.jar
Comment: Archive
Status: open
BacklogStatus: unknown
}
{Trying to map FollowUpActivityDTO to Nullable`1.}
It raises when I perform:
return AutoMapper.Mapper.Map<List<LEST.Model.FollowUpActivityDTO>, List<Domain.FollowUpActivity>>(dtos);
This is destination class:
public class FollowUpActivity
{
private String id; // Generated on server
private DateTime? creationDate;
private DateTime? startDate;
private DateTime? dueDate;
private DateTime? closingDate;
private String matter;
private String comment;
private FollowUpActivityStatus status;
private FollowUpActivityBacklogStatus backlogStatus;
private List<MetaInfoValue> metainfos;
private List<MetaResource> resources;
And this is the source class:
public class FollowUpActivityDTO
{
public FollowUpActivityDTO();
public string BacklogStatus { get; set; }
public string ChannelId { get; set; }
public DateTime? ClosingTimestamp { get; set; }
public string Comment { get; set; }
public DateTime? DueTimestamp { get; set; }
public string Id { get; set; }
public string Matter { get; set; }
public DateTime? StartTimestamp { get; set; }
public string Status { get; set; }
public DateTime? Timestamp { get; set; }
And mapping profile:
AutoMapper.Mapper.CreateMap<LEST.Model.FollowUpActivityDTO, Domain.FollowUpActivity>()
.ForMember(dst => dst.CreationDate, opts => opts.Ignore()) //opts.MapFrom(s => s.Timestamp.HasValue ? s.Timestamp.Value : DateTime.MinValue))
.ForMember(dst => dst.StartDate, opts => opts.Ignore()) //opts.MapFrom(s => s.StartTimestamp.HasValue ? s.StartTimestamp.Value : DateTime.MinValue))
.ForMember(dst => dst.DueDate, opts => opts.Ignore()) //opts.MapFrom(s => s.DueTimestamp.HasValue ? s.DueTimestamp.Value : DateTime.MinValue))
.ForMember(dst => dst.ClosingDate, opts => opts.Ignore()) //opts.MapFrom(s => s.ClosingTimestamp.HasValue ? s.ClosingTimestamp.Value : DateTime.MinValue));
.ForMember(dst => dst.Status, opts => opts.UseValue<Domain.FollowUpActivityStatus>(Domain.FollowUpActivityStatus.Open))
.ForMember(dst => dst.BacklogStatus, opts => opts.UseValue<Domain.FollowUpActivityBacklogStatus>(Domain.FollowUpActivityBacklogStatus.Work));
I've created a Test for testing this mapping:
namespace Tests
{
[TestFixture]
public class Mapping
{
[SetUp]
public void initialize()
{
Core.Mappings.AutoMapperConfiguration.Configure();
}
[Test]
public void configutation()
{
AutoMapper.Mapper.AssertConfigurationIsValid<Core.Mappings.Profiles.FollowUpActivityProfile>();
}
[Test]
public void followUpActivityDTOToDOMAIN()
{
LEST.Model.FollowUpActivityDTO dto = new LEST.Model.FollowUpActivityDTO()
{
Id = new Guid().ToString(),
Timestamp = DateTime.UtcNow,
StartTimestamp = DateTime.UtcNow,
DueTimestamp = DateTime.UtcNow,
ClosingTimestamp = DateTime.UtcNow,
Matter = "Matter",
Comment = "Comment",
Status = "open",
BacklogStatus = "work",
Metainfos = new System.Collections.Generic.List<LEST.Model.MetaInfoValueDTO>()
};
Domain.FollowUpActivity domain = new Domain.FollowUpActivity();
AutoMapper.Mapper.Map<LEST.Model.FollowUpActivityDTO, Domain.FollowUpActivity>(dto, domain);
domain.Should().NotBeNull();
domain.Id.Should().Be(dto.Id);
}
}
}
Take a look on:
Domain.FollowUpActivity domain = new Domain.FollowUpActivity();
AutoMapper.Mapper.Map<LEST.Model.FollowUpActivityDTO, Domain.FollowUpActivity>(dto, domain);
Now I works. However, if I code as follow, it crashes:
Domain.FollowUpActivity domain = AutoMapper.Mapper.Map<LEST.Model.FollowUpActivityDTO, Domain.FollowUpActivity>(dto);
I'm figuring out the problem is over the constructors of my Destination class then:
namespace Domain
{
public enum FollowUpActivityStatus
{
Open,
Closed,
Delegated
}
public enum FollowUpActivityBacklogStatus
{
Work,
Sprint
}
public class FollowUpActivity
{
private String id; // Generated on server
private DateTime? creationDate;
private DateTime? startDate;
private DateTime? dueDate;
private DateTime? closingDate;
private String matter;
private String comment;
private FollowUpActivityStatus status;
private FollowUpActivityBacklogStatus backlogStatus;
private List<MetaInfoValue> metainfos;
private List<MetaResource> resources;
#region Properties
public String Id
{
get { return id; }
set { id = value; }
}
public DateTime? CreationDate
{
get { return creationDate; }
set { creationDate = value; }
}
public DateTime? StartDate
{
get { return startDate; }
set { startDate = value; }
}
public DateTime? DueDate
{
get { return dueDate; }
set { dueDate = value; }
}
public DateTime? ClosingDate
{
get { return closingDate; }
set { closingDate = value; }
}
public FollowUpActivityStatus Status
{
get { return status; }
set { status = value; }
}
public FollowUpActivityBacklogStatus BacklogStatus
{
get { return backlogStatus; }
set { backlogStatus = value; }
}
public String Matter
{
get { return matter; }
set { matter = value; }
}
public String Comment
{
get { return comment; }
set { comment = value; }
}
public List<MetaInfoValue> Metainfos
{
get { return metainfos; }
set { metainfos = value; }
}
public List<MetaResource> Resources
{
get { return resources; }
set { resources = value; }
}
#endregion
#region Constructors
public FollowUpActivity()
: this(null, null)
{
}
public FollowUpActivity(String matter, String comment = null, params Domain.MetaInfoValue[] metainfos)
: this(DateTime.Now, matter, comment, metainfos)
{
}
public FollowUpActivity(DateTime creationDate, String matter, String comment = null, params Domain.MetaInfoValue[] metainfos)
: this(creationDate, matter, new List<MetaResource>(), comment, metainfos)
{
}
public FollowUpActivity(DateTime creationDate, String matter, List<MetaResource> resources, String comment = null, params Domain.MetaInfoValue[] metainfos)
: this(creationDate, matter, FollowUpActivityBacklogStatus.Work, new List<MetaResource>(), comment, metainfos)
{
}
public FollowUpActivity(DateTime creationDate, String matter, FollowUpActivityBacklogStatus backlogStatus, List<MetaResource> resources, String comment = null, params Domain.MetaInfoValue[] metainfos)
: this(creationDate, null, null, null, matter, FollowUpActivityStatus.Open, backlogStatus, new List<MetaResource>(), comment, metainfos)
{
}
public FollowUpActivity(DateTime? creationDate, DateTime? startDate, DateTime? dueDate, DateTime? closingDate, String matter, FollowUpActivityStatus status, FollowUpActivityBacklogStatus backlogStatus, List<MetaResource> resources, String comment = null, params Domain.MetaInfoValue[] metainfos)
{
this.id = String.Empty;
this.creationDate = creationDate;
this.startDate = startDate;
this.dueDate = dueDate;
this.closingDate = closingDate;
this.matter = matter;
this.comment = comment;
this.status = status;
this.backlogStatus = backlogStatus;
this.metainfos = new List<MetaInfoValue>(metainfos);
this.resources = resources;
}
#endregion
}
}
However, I don't know why does it crashes using the second approach... Someone knows why?
Thanks for all.
Trying to get the result from a webservice call to return a Model. I eep getting the error:
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'CI.Models.Schedule' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
public Schedule getCourseSchedule()
{
var obj = new
{
States = new[] { new { State = "MX" } },
Zip = "",
Miles = "",
PaginationStart = 1,
PaginationLimit = 3
};
using (var client = new WebClient())
{
client.Headers[HttpRequestHeader.ContentType] = "apoplication/json";
var url = "http://192.168.1.198:15014/ShoppingCart2/CourseSchedule";
var json = JsonConvert.SerializeObject(obj);
byte[] data = Encoding.UTF8.GetBytes(json);
byte[] result = client.UploadData(url, data);
string returnjson = Encoding.UTF8.GetString(result);
Schedule sched = JsonConvert.DeserializeObject<Schedule>(returnjson);
return sched;
}
}
Schedule Model:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Globalization;
namespace CI.Models
{
public class Schedule
{
public IEnumerable<Course> Courses { get; set; }
}
public class Course
{
/*
JSON Data returned from web service:
{
"ProgramGroup":"MR",
"ProgramCode":"RM",
"EventCode":"20160901MXMR",
"FormalDate":"September 1-2, 2016",
"StartDate":"2016\/09\/01",
"Price":5,
"LocName":"WB Hotel",
"LocAddress":"Av. Speedy Gonzales 220",
"LocCity":"Monterrey",
"LocState":"MX",
"LocZipCode":null,
"LicenseeURL":null,
"AgendaURL":"NA",
"SeatsAreAvailable":"2",
"GeneralInfoHTML":"General Info goes here.",
"GateKeeperHTML":null,
"EventType":"SS",
"TotalCourses":3
}
*/
public string ProgramGroup { get; set; }
public string ProgramCode { get; set; }
public string EventCode { get; set; }
public string FormalDate { get { return FormalDate; } set { FormalDate = convertFormalDateToSpanish(value); } }
public string StartDate { get; set; }
public double Price { get; set; }
public string LocName { get; set; }
public string LocAddress { get; set; }
public string LocCity { get ; set; }
public string LocState { get; set; }
public string LocZipCode { get; set; }
public string LicenseeURL { get; set; }
public string AgendaURL { get { return AgendaURL; } set { AgendaURL = buildAgendaLink(value); } }
public string SeatsAreAvailable { get; set; }
public string GeneralInfoHTML { get; set; }
public string GateKeeperHTML { get; set; }
public string EventType { get; set; }
public int TotalCourses { get; set; }
public string convertFormalDateToSpanish(string val)
{
DateTime TheDate = DateTime.Parse(StartDate);
string[] FormalDate = val.Split(" ".ToCharArray());
CultureInfo ci = new CultureInfo("es-ES");
string _Date = FormalDate[1].Replace("-", " al ").Replace(",", "");
string _Month = ci.TextInfo.ToTitleCase(TheDate.ToString("MMMM", ci));
val = string.Concat(_Date, " ", _Month);
return val;
}
private string buildAgendaLink(string val)
{
if (val.Trim() != "")
{
val = string.Concat("Agenda");
}
else
{
val = "Agenda";
}
return val;
}
}
}
Your server returns an array. Just try
Course[] courses = JsonConvert.DeserializeObject<Course[]>(returnjson);
Note that this is not an answer to your original problem, but I added it like an answer in order to explain my comment above with some actual code.
First problem with your code is that FormalDate and AgendaUrl properties simply won't work. Accessing them will result in a StackOverflowException, because you basically defined them recursively.
A property is merely syntax sugar for two separate getter/setter methods, so by writing this:
public class Course
{
public string FormalDate
{
get { return FormalDate; }
}
}
You are basically writing this:
public class Course
{
public string GetFormalDate()
{
// recursive call, with no terminating condition,
// will infinitely call itself until there is no
// more stack to store context data (and CLR
// will then throw an exception)
return GetFormalDate();
}
}
To fix that, you need to add an actual backing field, e.g.:
public class Course
{
private string _formalDate; // <-- this is a backing field;
// and this property uses the backing field to read/store data
public string FormalDate
{
get { return _formalDate; }
set { _formalDate = convertFormalDateToSpanish(value); }
}
}
Additionally, it's unusual for a property getter to return a different value than the one set through a setter. In other words, I would never expect this from a class:
var course = new Course();
course.StartDate = "2016/09/01";
course.FormalDate = "September 1-2, 2016";
Console.WriteLine(course.FormalDate); // prints "1 al 2 Septiembre" ?
I would rather move this functionality into a different class, or at least create different properties which return these values:
public class CourseInfo
{
// this is now a "dumb" auto-implemented property
// (no need for a backing field anymore)
public string FormalDate { get; set; }
// this read-only property returns the converted value
public string LocalizedFormalDate
{
get
{
return convertFormalDateToSpanish(FormalDate);
}
}
}