Ich verwende eine MVC 4-Web-API und asp.net-Webformulare 4.0, um eine Rest-API zu erstellen. Es funktioniert großartig:
[HttpGet]
public HttpResponseMessage Me(string hash)
{
HttpResponseMessage httpResponseMessage;
List<Something> somethings = ...
httpResponseMessage = Request.CreateResponse(HttpStatusCode.OK,
new { result = true, somethings = somethings });
return httpResponseMessage;
}
Jetzt muss ich verhindern, dass einige Eigenschaften serialisiert werden. Ich weiß, dass ich etwas LINQ über die Liste verwenden und nur die Eigenschaften abrufen kann, die ich benötige. Im Allgemeinen ist dies ein guter Ansatz, aber im vorliegenden Szenario ist das something
Objekt zu komplex und ich benötige unterschiedliche Eigenschaften in unterschiedlichen Methoden Zur Laufzeit ist es einfacher, jede zu ignorierende Eigenschaft zu markieren.
Gibt es eine Möglichkeit, das zu tun?
c#
asp.net
asp.net-mvc
asp.net-web-api
user1330271
quelle
quelle
Antworten:
Die ASP.NET-Web-API wird
Json.Net
als Standardformatierer verwendet. Wenn Ihre Anwendung also nur JSON als Datenformat verwendet, können Sie[JsonIgnore]
die Eigenschaft für die Serialisierung ignorieren:Auf diese Weise wird das XML-Format jedoch nicht unterstützt. Wenn Ihre Anwendung das XML-Format mehr (oder nur XML) unterstützen muss, anstatt es zu verwenden
Json.Net
, sollten Sie das verwenden,[DataContract]
das sowohl JSON als auch XML unterstützt:Zum besseren Verständnis können Sie den offiziellen Artikel lesen .
quelle
Gemäß der Dokumentationsseite der Web-API JSON- und XML-Serialisierung in der ASP.NET-Web-API , um die Serialisierung für eine Eigenschaft, die Sie entweder verwenden können, explizit zu verhindern
[JsonIgnore]
für den Json-Serializer oder[IgnoreDataMember]
für den Standard-XML-Serializer verwenden können.Beim Testen ist mir jedoch aufgefallen, dass
[IgnoreDataMember]
die Serialisierung sowohl für XML- als auch für Json-Anforderungen verhindert wird. Daher würde ich empfehlen, diese zu verwenden, anstatt eine Eigenschaft mit mehreren Attributen zu dekorieren.quelle
[IgnoreDataMember]
scheint es nicht mit verzögert geladenen EF 6-Proxy-Objekten (virtuellen Eigenschaften) zu funktionieren.[DataContract]
und[DataMember]
tun es jedoch.Anstatt standardmäßig alles serialisieren zu lassen, können Sie den "Opt-In" -Ansatz verwenden. In diesem Szenario dürfen nur die von Ihnen angegebenen Eigenschaften serialisiert werden. Sie tun dies mit dem
DataContractAttribute
undDataMemberAttribute
, das im System.Runtime.Serialization- Namespace zu finden ist.Das
DataContactAttribute
wird auf die Klasse angewendet, und dasDataMemberAttribute
wird auf jedes Mitglied angewendet, das serialisiert werden soll:Ich wage zu sagen, dass dies ein besserer Ansatz ist, weil er Sie dazu zwingt, explizite Entscheidungen darüber zu treffen, was durch Serialisierung erreicht werden soll oder nicht. Außerdem können Ihre Modellklassen selbstständig in einem Projekt leben, ohne von JSON.net abhängig zu sein, nur weil Sie sie an einem anderen Ort zufällig mit JSON.net serialisieren.
quelle
Dies hat bei mir funktioniert: Erstellen Sie einen benutzerdefinierten Vertragsauflöser mit einer öffentlichen Eigenschaft namens AllowList vom Typ string array. Ändern Sie in Ihrer Aktion diese Eigenschaft abhängig davon, was die Aktion zurückgeben muss.
1. Erstellen Sie einen benutzerdefinierten Vertragsauflöser:
2. Verwenden Sie den benutzerdefinierten Vertragsauflöser in Aktion
Dieser Ansatz ermöglichte es mir, bestimmte Anforderungen zuzulassen / nicht zuzulassen, anstatt die Klassendefinition zu ändern. Wenn Sie keine XML-Serialisierung benötigen, vergessen Sie nicht, diese in Ihrer zu
App_Start\WebApiConfig.cs
deaktivieren. Andernfalls gibt Ihre API blockierte Eigenschaften zurück, wenn der Client XML anstelle von JSON anfordert.quelle
Ich werde Ihnen zwei Möglichkeiten zeigen, um das zu erreichen, was Sie wollen:
Erster Weg: Dekorieren Sie Ihr Feld mit dem JsonProperty-Attribut, um die Serialisierung dieses Felds zu überspringen, wenn es null ist.
Zweiter Weg: Wenn Sie mit einigen komplexen Szenarien verhandeln, können Sie die Web-API-Konvention ("ShouldSerialize") verwenden, um die Serialisierung dieses Felds abhängig von einer bestimmten Logik zu überspringen.
WebApi verwendet JSON.Net und verwendet Reflection für die Serialisierung. Wenn also beispielsweise die ShouldSerializeFieldX () -Methode erkannt wurde, wird das Feld mit dem Namen FieldX nicht serialisiert.
quelle
Ich bin zu spät zum Spiel, aber anonyme Objekte würden den Trick machen:
quelle
Versuchen Sie es mit der
IgnoreDataMember
Eigenschaftquelle
Fast wie die Antwort von greatbear302, aber ich erstelle ContractResolver pro Anfrage.
1) Erstellen Sie einen benutzerdefinierten ContractResolver
2) Verwenden Sie einen benutzerdefinierten Vertragsauflöser in Aktion
Bearbeiten:
Es hat nicht wie erwartet funktioniert (Resolver pro Anfrage isolieren). Ich werde anonyme Objekte verwenden.
quelle
Möglicherweise können Sie AutoMapper verwenden, die
.Ignore()
Zuordnung verwenden und dann das zugeordnete Objekt sendenquelle
Funktioniert gut, indem Sie einfach Folgendes hinzufügen: [IgnoreDataMember]
Über dem richtigen Typ, wie:
Dies funktioniert mit ApiController. Der Code:
quelle
Aus irgendeinem Grund
[IgnoreDataMember]
funktioniert das nicht immer bei mir und ich bekomme manchmalStackOverflowException
(oder ähnliches). Also habe ich stattdessen (oder zusätzlich) angefangen, ein Muster zu verwenden, das ungefähr so aussieht, wenn ichPOST
inObjects
meine API gehe:Im Grunde genommen übergebe ich ein
JObject
und konvertiere es, nachdem es empfangen wurde, in Aviod-Probleme, die durch den eingebauten Serializer verursacht werden und manchmal eine Endlosschleife verursachen, während die Objekte analysiert werden.Wenn jemand einen Grund kennt, warum dies in irgendeiner Weise eine schlechte Idee ist, lassen Sie es mich bitte wissen.
Es kann erwähnenswert sein, dass es der folgende Code für eine EntityFramework-Klasseneigenschaft ist, der das Problem verursacht (wenn zwei Klassen aufeinander verweisen):
quelle