2014-01-14 2 views
3

У меня проблема с Json.NET и omdbapi. Я пытаюсь получить информацию из omdbapi, и некоторые свойства дают мне головные боли, особенно «imdbVotes», поскольку он написан, например, как «321,364», поэтому я не могу получить от него целое число.Json.NET - Custom Converter - String To Int

Я уверен, что мне нужен пользовательский конвертер, но я боюсь, что на данный момент я действительно не понимаю, как создать его для моей конкретной проблемы.

Все остальные свойства работают хорошо (я не использую их все в данный момент).

Это ответ на, позволяет сказать Snatch: http://www.omdbapi.com/?i=&t=snatch

Это мой класс:

public class MovieJSON 
{ 
    [JsonProperty(PropertyName = "Title")] 
    public String Title { get; set; } 

    [JsonProperty(PropertyName = "Year")] 
    public int Year { get; set; } 

    [JsonProperty(PropertyName = "Genre")] 
    public String Genre { get; set; } 

    [JsonProperty(PropertyName = "Director")] 
    public String Director { get; set; } 

    [JsonProperty(PropertyName = "Actors")] 
    public String Actors { get; set; } 

    [JsonProperty(PropertyName = "Plot")] 
    public String Plot { get; set; } 

    [JsonProperty(PropertyName = "Poster")] 
    public String Poster { get; set; } 

    [JsonProperty(PropertyName = "Metascore")] 
    public int Metascore { get; set; } 

    [JsonProperty(PropertyName = "imdbRating")] 
    public decimal ImdbRating { get; set; } 

    [JsonProperty(PropertyName = "imdbVotes")] 
    public int ImdbVotes { get; set; } 
} 

UPDATE # 1:

Как я могу справиться ответ, когда свойство имеет значение «N/A» ?. Это происходит для некоторых фильмов (т. Е. http://www.omdbapi.com/?i=&t=four+rooms имеет значение Metascore для N/A).

UPDATE # 2:

Другой связанный запрос. Я использую EF6 с MySQL, и идея состоит в том, чтобы заполнить базу данных фильмами, созданными с помощью разбора JSON.

Это мой фильм класс:

[JsonObject(MemberSerialization.OptIn)] 
[Table("movies")] 
public class MovieJSON 
{ 
    [Key] 
    public int Id { get; set; } 

    [JsonProperty(PropertyName = "Title")] 
    [Column("title")] 
    public String Title { get; set; } 

    [JsonProperty(PropertyName = "Year")] 
    [Column("year")] 
    public int Year { get; set; } 

    [JsonProperty(PropertyName = "Genre")] 
    [Column("genre")] 
    public String Genre { get; set; } 

    [JsonProperty(PropertyName = "Director")] 
    [Column("director")] 
    public String Director { get; set; } 

    [JsonProperty(PropertyName = "Actors")] 
    [Column("actors")] 
    public String Actors { get; set; } 

    [JsonProperty(PropertyName = "Plot")] 
    [Column("plot")] 
    public String Plot { get; set; } 

    [JsonProperty(PropertyName = "Poster")] 
    [Column("poster")] 
    public String Poster { get; set; } 

    [JsonProperty(PropertyName = "Metascore")] 
    public String Metascore { get; set; } 

    [Column("metascore")] 
    public int MetascoreInt 
    { 
     get 
     { 
      int result; 
      if (int.TryParse(Metascore, NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out result)) 
       return result; 
      return 0; 
     } 
    } 

    [JsonProperty(PropertyName = "imdbRating")] 
    public String ImdbRating { get; set; } 

    [Column("imdb_rating")] 
    public Decimal ImdbRatingDecimal 
    { 
     get 
     { 
      Decimal result; 
      if (Decimal.TryParse(ImdbRating, out result)) 
       return result; 
      return 0; 
     } 
    } 

    [JsonProperty(PropertyName = "imdbVotes")] 
    public String ImdbVotes { get; set; } 

    [Column("imdb_votes")] 
    public long ImdbVotesLong 
    { 
     get 
     { 
      long result; 
      String stringToParse = ImdbVotes.Remove(ImdbVotes.IndexOf(','), 1); 

      if (long.TryParse(stringToParse, out result)) 
       return result; 
      return 0; 
     } 
    } 

    [JsonProperty(PropertyName = "imdbID")] 
    [Column("imdb_id")] 
    public String ImdbID { get; set; } 

    [JsonProperty(PropertyName = "type")] 
    [Column("type")] 
    public String Type { get; set; } 

    public override string ToString() 
    { 
     String[] propertiesToIgnore = {"MetascoreInt", "ImdbRatingDecimal", "ImdbVotesLong"}; 
     var sb = new StringBuilder(); 

     PropertyInfo[] properties = GetType().GetProperties(); 

     foreach (PropertyInfo propertyInfo in properties) 
     { 
      if (propertiesToIgnore.Contains(propertyInfo.Name)) 
       continue; 

      sb.AppendLine(String.Format("{0} : {1} ", 
       propertyInfo.Name, propertyInfo.GetValue(this, null))); 
     } 

     return sb.ToString(); 
    } 
} 

Это моя EF6 конфигурации-контекст класс (я игнорирую поле String, и вместо того, чтобы, используя Helper те, так как база данных настроено принимать Int для Metascore и так далее):

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<MovieJSON>().Ignore(e => e.Metascore).Ignore(e => e.ImdbRating).Ignore(e => e.ImdbVotes); 
     base.OnModelCreating(modelBuilder); 
    } 

Дополнительная информация изображения:

значения объекта до ввода в базу данных (все значения заданы правильно)

Valid XHTML http://imagizer.imageshack.us/v2/800x600q90/689/8x5m.png

Значения в базе данных:

Valid XHTML http://imagizer.imageshack.us/v2/800x600q90/844/nvc5.png

Вспомогательные поля (MetascoreInt, ImdbRatingDecimal, ImdbVotesLong) возвращаются к нулю, я не могу понять, почему.

Любая помощь была бы оценена по достоинству! :)

Все лучшее

+0

Один из способов сделать это - принять 'ImdbVotes' как строку, а затем проанализировать его позже. Удаление ненужных символов из строки [достаточно просто] (http://msdn.microsoft.com/en-us/library/844skk0h (v = vs.110) .aspx). –

+0

Спасибо за предложение, я ответил на нижний комментарий, предлагаемое решение такое же :). – D6mi

+0

@ D6mi 'N/A' - это просто строка, вы можете сделать то же самое;) – Jim

ответ

3

Вы можете иметь два свойства: один будет свойство строки, как это происходит от IMDB, а другой бы быть ИНТ свойство, которое преобразует строку один. Для преобразования вы можете использовать флаг nifty NumberStyles.AllowThousands. Таким образом, у вас было бы

[JsonProperty(PropertyName = "imdbVotes")] 
public string ImdbVotes { get; set; } 

public int ImdbVotesInt 
{ 
    get 
    { 
     int result; 
     if (int.TryParse(ImdbVotes, 
       NumberStyles.AllowThousands, 
       CultureInfo.InvariantCulture, 
       out result))      
      return result; // parse is successful, use 'result' 
     else 
      return 0;  // parse is unsuccessful, return whatever default value works for you  
    } 
} 
+0

Спасибо за нереалистичный быстрый ответ :). Я понимаю, что вы имеете в виду, я попытался пойти на это решение, но я подумал, что лучше подойти с помощью Custom Converters. Я обновил свой вопрос, поэтому, полагаю, вы предлагаете мне сделать то же самое для других, предательских свойств? – D6mi

+0

@ D6mi - Я не знаю об этом, кажется излишне сложным. Опять же, я не знаю потребности вашего проекта. –