2

Entity Framework 5 Code First データベースと Json のシリアル化に関して、この固有の問題があります。

次のユーザークラスを持つデータベースがあります

public class User
{
    [Key()]
    [HiddenInput(DisplayValue=false)]
    public int UserId { get; set; }

    [Required]
    public string Username { get; set; }

    [Required]
    public string DisplayName { get; set; }

    [Required]
    [DataType(DataType.Password)]
    public string Password { get; set; }

    [DataType(DataType.MultilineText)]
    public string Description { get; set; }

    [ScaffoldColumn(false)]
    public virtual Outfit ProfileOutfit { get; set; }

    [ScaffoldColumn(false)]
    public virtual PoseAnimation ProfilePose { get; set; }

    [ScaffoldColumn(false)]
    public virtual Mannequin ProfileMannequin { get; set; }

    [ScaffoldColumn(false)]
    public virtual ICollection<int> SubscribedTo { get; set; }

    [ScaffoldColumn(false)]
    public virtual ICollection<Fashionshow> Fashionshows { get; set; }

    [ScaffoldColumn(false)]
    public virtual ICollection<Outfit> Outfits { get; set; }

    [ScaffoldColumn(false)]
    public virtual ICollection<Snapshot> Snapshots { get; set; }

    [ScaffoldColumn(false)]
    public virtual ICollection<Achievement> Achievements { get; set; }
}

私はこれを私のDbContextに持っています:

public class SilkDbContext9 : DbContext
{
    public DbSet<User> Users { get; set; }
    public DbSet<News> News { get; set; }
    public DbSet<Outfit> Outfits { get; set; }
    public DbSet<Fashionshow> Fashionshows { get; set; }
    public DbSet<Entry> Entries { get; set; }
    public DbSet<Location> Locations { get; set; }
    public DbSet<Sound> Sounds { get; set; }
    public DbSet<Snapshot> Snapshots { get; set; }
    public DbSet<OutfitPart> OutfitParts { get; set; }
    public DbSet<Mannequin> Mannequins { get; set; }
    public DbSet<PoseAnimation> PoseAnimations { get; set; }
    public DbSet<WalkAnimation> WalkAnimations { get; set; }
    public DbSet<Achievement> Achievements { get; set; }

    public DbSet<ConstructOutfit> ConstructOutfits { get; set; }

    public DbSet<DesignOutfit> DesignOutfits { get; set; }
}

これで、ApiController を介してローカルホスト環境で (Visual Studio でのデバッグのように) ユーザー クラスを要求すると、それが機能し、ユーザーのリストが返されます。ただし、デプロイ先のサーバーでリクエストすると、次のオブジェクトが返されます。

{"$id":"1","Message":"An error has occurred."}

これを正しくする方法がわかりません。どこかに無限ループがある場合に備えて、他のオブジェクトから User クラスへのすべての参照を削除しようとしましたが、役に立ちませんでした。また、このコードをオフにしてからオンにしようとしました(どちらも役に立ちませんでした):

var json = config.Formatters.JsonFormatter;
        json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
        config.Formatters.Remove(config.Formatters.XmlFormatter);

エラーはgetメソッドでキャッチされないため、JSonへの変換からエラーが発生すると推測しています。

つまり、IIS サーバーではなく、localhost で Json にシリアル化するオブジェクトがあります。これを解決するには?

アップデート

API の get メソッドが機能しているように見えるため、ログに記録できません (私の知る限り、IIS に詳しくありません)。ここにあります:

public IEnumerable<object> GetUsers()
    {
        IEnumerable<User> users;

        try
        {
            users = db.Users.AsEnumerable();
        }
        catch
        {
            return new List<string>() { "Error getting the collection" };
        }

        try
        {
            return users;
        }
        catch
        {
            return new List<string>() { "Error returning the collection" };
        }
    }

どちらのエラー文字列も返されないため、実際のユーザーが返され、JSON へのシリアル化に問題があると推測しています。/api/users に移動してユーザーを取得します。

4

1 に答える 1

1

これが事実であるかどうかを知るのに十分なコードを投稿していないので、これは推測です: MVC ActionResults を介して EF エンティティをシリアル化するときに、次の問題が発生しました。

DbSet を破棄する前に、LINQ クエリを完全に具体化する (つまり、SQL を実行してエンティティに変換する) 必要があります。マテリアライズされていない IQueryable を ActionResult の一部として返すのは非常に簡単で、通常はアクション メソッドが戻る前に DbSet が破棄されます。これにより、シリアライザーが結果のコレクションを列挙しようとすると、return ステートメントの後にクエリが爆発し、LINQ クエリが実行されます。

これが問題である場合の解決策は、ToList() または ToArray() を呼び出して DbSet を破棄する前に、IQueryable が具体化されていることを確認することです。

于 2013-05-28T12:44:07.237 に答える