185

MVC 4 Web API と asp.net Web フォーム 4.0 を使用して残りの API を構築しています。それはうまくいっています:

[HttpGet]
public HttpResponseMessage Me(string hash)
{
    HttpResponseMessage httpResponseMessage;
    List<Something> somethings = ...

    httpResponseMessage = Request.CreateResponse(HttpStatusCode.OK, 
                                 new { result = true, somethings = somethings });

    return httpResponseMessage;
}

ここで、いくつかのプロパティがシリアル化されないようにする必要があります。リストに対していくつかの LINQ を使用して、必要なプロパティのみを取得できることはわかっています。一般的にはこれが適切なアプローチですが、現在のシナリオではsomethingオブジェクトが複雑すぎて、さまざまなメソッドでさまざまなプロパティ セットが必要になるため、実行時に、各プロパティを無視するようにマークしやすくします。

それを行う方法はありますか?

4

12 に答える 12

251

ASP.NET Web API はJson.Net既定のフォーマッタとして使用するため、アプリケーションがデータ形式として JSON のみを使用する場合は[JsonIgnore]、シリアル化のプロパティを無視するために使用できます。

public class Foo
{
    public int Id { get; set; }
    public string Name { get; set; }

    [JsonIgnore]
    public List<Something> Somethings { get; set; }
}

ただし、この方法は XML 形式をサポートしていません。したがって、アプリケーションXML 形式をさらにサポートする (または XML のみをサポートする) 必要がある場合は、 を使用する代わりに、JSON と XML の両方をサポートするものJson.Netを使用する必要があります。[DataContract]

[DataContract]
public class Foo
{
    [DataMember]
    public int Id { get; set; }
    [DataMember]
    public string Name { get; set; }

    //Ignore by default
    public List<Something> Somethings { get; set; }
}

詳細については、公式記事を参照してください。

于 2012-08-07T17:56:06.770 に答える
117

Web API ドキュメント ページJSON and XML Serialization in ASP.NET Web API[JsonIgnore]によると、Json シリアライザーまたは[IgnoreDataMember]既定の XMLシリアライザーのいずれかに使用できるプロパティのシリアル化を明示的に防止します。

ただし、テストでは[IgnoreDataMember]、XML 要求と Json 要求の両方のシリアル化が妨げられることに気付いたので、プロパティを複数の属性で装飾するのではなく、シリアル化を使用することをお勧めします。

于 2012-10-05T07:22:31.043 に答える
35

デフォルトですべてをシリアル化する代わりに、「オプトイン」アプローチを取ることができます。このシナリオでは、指定したプロパティのみをシリアル化できます。これは、System.Runtime.Serialization名前空間にあるDataContractAttributeandを使用して行います。DataMemberAttribute

DataContactAttributeがクラスに適用され、シリアル化する各メンバーにがDataMemberAttribute適用されます。

[DataContract]
public class MyClass {

  [DataMember]
  public int Id { get; set;} // Serialized

  [DataMember]
  public string Name { get; set; } // Serialized

  public string DontExposeMe { get; set; } // Will not be serialized
}

シリアライゼーションによって何が成功するか、または成功しないかについて明確な決定を下す必要があるため、これはより良いアプローチであるとあえて言います。また、別の場所でモデル クラスを JSON.net でシリアル化しているという理由だけで、JSON.net に依存することなく、モデル クラスをプロジェクト内に単独で配置することもできます。

于 2013-08-16T12:53:05.690 に答える
19

あなたが望むものを達成するための2つの方法を紹介します:

最初の方法: null の場合にそのフィールドのシリアル化をスキップするために、フィールドを JsonProperty 属性で装飾します。

public class Foo
{
    public int Id { get; set; }
    public string Name { get; set; }

    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public List<Something> Somethings { get; set; }
}

2 番目の方法: いくつかの複雑なシナリオで交渉している場合は、特定のロジックに応じてそのフィールドのシリアル化をスキップするために、Web Api 規則 ("ShouldSerialize") を使用できます。

public class Foo
{
    public int Id { get; set; }
    public string Name { get; set; }

    public List<Something> Somethings { get; set; }

    public bool ShouldSerializeSomethings() {
         var resultOfSomeLogic = false;
         return resultOfSomeLogic; 
    }
}

WebApi は JSON.Net を使用し、リフレクションをシリアル化に使用するため、(たとえば) ShouldSerializeFieldX() メソッドを検出すると、FieldX という名前のフィールドはシリアル化されません。

于 2015-09-22T22:06:01.237 に答える
17

私はゲームに遅れていますが、匿名オブジェクトがそのトリックを行います:

[HttpGet]
public HttpResponseMessage Me(string hash)
{
    HttpResponseMessage httpResponseMessage;
    List<Something> somethings = ...

    var returnObjects = somethings.Select(x => new {
        Id = x.Id,
        OtherField = x.OtherField
    });

    httpResponseMessage = Request.CreateResponse(HttpStatusCode.OK, 
                                 new { result = true, somethings = returnObjects });

    return httpResponseMessage;
}
于 2014-03-07T18:48:33.980 に答える
4

AutoMapperを使用して.Ignore()マッピングを使用してから、マップされたオブジェクトを送信できる場合があります

CreateMap<Foo, Foo>().ForMember(x => x.Bar, opt => opt.Ignore());
于 2012-08-07T17:42:01.867 に答える
0

何らかの理由[IgnoreDataMember]で、常にうまくいくとは限りませんStackOverflowException。代わりに (または追加で) 、APIにPOSTアクセスするときに次のようなパターンを使用し始めました。Objects

[Route("api/myroute")]
[AcceptVerbs("POST")]
public IHttpActionResult PostMyObject(JObject myObject)
{
    MyObject myObjectConverted = myObject.ToObject<MyObject>();

    //Do some stuff with the object

    return Ok(myObjectConverted);
}

したがって、基本的にJObjectは、オブジェクトの解析中に無限ループを引き起こす組み込みのシリアライザーが原因で発生する問題を回避するために、受け取った後に渡して変換します。

これが何らかの形で悪い考えである理由を誰かが知っている場合は、私に知らせてください.

問題を引き起こすのは、EntityFramework クラス プロパティの次のコードであることに注意してください (2 つのクラスが相互に参照している場合)。

[Serializable]
public partial class MyObject
{
   [IgnoreDataMember]
   public MyOtherObject MyOtherObject => MyOtherObject.GetById(MyOtherObjectId);
}

[Serializable]
public partial class MyOtherObject
{
   [IgnoreDataMember]
   public List<MyObject> MyObjects => MyObject.GetByMyOtherObjectId(Id);
}
于 2016-02-18T08:04:24.013 に答える