1

Json.NET を使用して MVC ビュー モデルを json にpublic object Result { get; set;}シリアル化すると、実際の json オブジェクトではなく、キーと値のペアにシリアル化されるビュー モデル ( ) に汎用オブジェクト プロパティがあります。強制的にシリアル化するために使用できるコンバーターはありますか?

これは、Json.NET によって現在出力されているものです。

"result": [
    {
      "key": "AssetId",
      "value": "b8d8fb71-2553-485b-91bf-14c6c563d78b"
    },
    {
      "key": "SearchResultType",
      "value": "Assets"
    },
    {
      "key": "Name",
      "value": "abstract-q-c-1920-1920-8"
    }
  ]

代わりに、これを出力したいと思います:

"result": {
    "AssetId": "b8d8fb71-2553-485b-91bf-14c6c563d78b",
    "SearchResultType": "Assets",
    "Name": "abstract-q-c-1920-1920-8"
  }

編集:そのプロパティがどのように設定されているかという質問に答えるには、RavenDB インデックスを使用します。

public class SiteSearchIndexTask : AbstractMultiMapIndexCreationTask<SiteSearchResult>
{
    public class Result
    {
        public object[] Content { get; set; }
    }

    public override string IndexName
    {
        get
        {
            return "SiteSearch/All";
        }
    }
    public SiteSearchIndexTask()
    {
        AddMap<Asset>(items => from item in items
                                where item.IsDeleted == false
                               select new 
                                          {
                                              Id = item.Id.ToString(),
                                              ObjectId = item.Id,
                                              ResultType = SearchResultType.Assets,
                                              Title = item.Name.Boost(3),
                                              Tags = item.Tags.Select(x => x.Name).Boost(2),
                                              Result = (object)item,
                                              Query = string.Join(" ", item.Description)
                                          });
        AddMap<User>(items => from item in items
                              where item.IsDeleted == false
                              select new 
                                         {
                                             Id = item.Id,
                                             ObjectId = item.UserId,
                                             ResultType = SearchResultType.Users,
                                             Title = item.Username.Boost(3),
                                             Tags = (BoostedValue) null,
                                             Result = (object)item,
                                             Query = string.Join(" ", item.FullName, item.Email)
                                         });
        Store(x => x.ObjectId, FieldStorage.Yes);
        Store(x => x.ResultType, FieldStorage.Yes);
        Store(x => x.Title, FieldStorage.Yes);
        Store(x => x.Tags, FieldStorage.Yes);
        Store(x => x.Result, FieldStorage.Yes);
        Store(x => x.Query, FieldStorage.Yes);
    }
}

編集 2 ここに Asset および User モデルがあります (自動プロパティの集まりであるため、簡潔にするために省略されています)

public class Asset : IHasId
{
    public string Id { get; set; }
    public Guid AssetId
    {
        get
        {
            Guid assetId;
            Guid.TryParse((Id ?? string.Empty).Replace("assets/", ""), out assetId);
            return assetId;
        }
        set { Id = "assets/" + value; }
    }

    public string Name { get; set; }
    public string Description { get; set; }
}

public class User : IHasId
{
    public User()
    {
        Status = UserStatus.Active;
    }

    public string Id { get; set; }
    public int UserId
    {
        get
        {
            int userId;
            int.TryParse((Id ?? string.Empty).Replace("users/", ""), out userId);
            return userId;
        }
        set { Id = "users/" + value; }
    }

    public string Username { get; set; }
    public string Password { get; set; }
    public string Email { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public UserStatus Status { get; set; }
}

編集 3 結局のところ、コードをステップ実行すると、そのオブジェクトは実際には Raven.Abstractions.Linq.DynamicJsonObject 型であり、キーと値のペアの配列が含まれています。したがって、この質問は Json.NET よりも Raven に関連している可能性が高いと思います。もちろん、キーと値のペアからjsonオブジェクトに変換するコンバーターがない限り。

4

1 に答える 1

1

正確にどのようにクエリを行っているかを確認するのに役立ちますが、RavenDB サイトのマルチマップ インデックスを使用したドキュメントとは異なるクエリの例を確認する必要があります。

あなたのインデックスを見ると、フィールド ストレージと結果のカプセル化に関してやりすぎているように見えます。把握するのが難しい場合もありますが、インデックスで行われるマッピングは、結果が返される方法を定義することではなく、インデックスがどのように構築されるかを定義することです。Reduce または TransformResults ステップを実行していない限り、元のドキュメントを返すことになります。

したがって、ドキュメントをそのままカプセル化するのResult = (object)itemはやり過ぎです。ResultType 列挙型も同様です。一致したドキュメントのタイプを知る必要がある場合は.GetType()、オブジェクトで を使用するだけで、それがユーザーかアセットかをすぐに確認できます。

検索インデックスを定義する方法を次に示します。提供したモデルにはないプロパティがインデックスに表示されたため、いくつかの違いがあることに注意してください。(フロントエンドのモデルとは別のエンティティがバックエンドにあると想定していますが、必要に応じて調整してください。)

public class SearchIndex : AbstractMultiMapIndexCreationTask<SearchIndex.Result>
{
  public class Result
  {
      public object[] Content { get; set; }
      public string ResultType { get; set; }
  }

  public SearchIndex()
  {
      AddMap<Asset>(items => from item in items
                             select new Result
                             {
                               Content = new object[] {item.Name, item.Description},
                               ResultType = MetadataFor(item)["Raven-Entity-Name"].ToString()
                             });

      AddMap<User>(items => from item in items
                            select new Result
                            {
                              Content = new object[] { item.Username, item.FirstName, item.LastName, item.Email },
                              ResultType = MetadataFor(item)["Raven-Entity-Name"].ToString()
                            });

      Index(x => x.Content, FieldIndexing.Analyzed);
    }
}

そして、次のようにクエリします。

var results = session.Advanced
                     .LuceneQuery<object, SearchIndex>()
                     .Where("ResultType:" + resultTypeName)
                     .AndAlso()
                     .Search("Content", searchTerm);

次に、単に結果を調べて、 as としてキャストしている間object、実際にresult.GetType()そのオブジェクトがどのように構築されているかを確認できることを確認できます。IAmSearchable必要に応じて、Raven の例に示すように、オブジェクトの代わりにキャストするエンティティに共通のインターフェイスを配置することもできます。

最終的に結果を MVC 経由で返すときは、Raven の DynamicJsonObject ではなく実際のオブジェクトから取得されるため、適切にシリアル化する必要があります。

于 2012-10-08T16:19:56.633 に答える