2014-08-27 4 views
5

Ich versuche, einen universellen Web-API-Controller zu schreiben, mit dem ich ein JSON-Dokument ohne Angabe eines C# -Typs in einer Sammlung speichern kann. Ich habe versucht, den Code auf das Wesentliche zu verdichten:MongoDB C# - Wie speichere ich ein beliebiges JSON-Dokument als dynamischen Typ?

public class PassThroughController : ApiController 
{ 
    [Route("api/mongodb/{collection}")] 
    public void Post(string collection, dynamic document) 
    { 
     const string connectionString = "mongodb://localhost"; 

     var client = new MongoClient(connectionString); 
     var db = client.GetServer().GetDatabase("SampleDb"); 
     var mongoCollection = db.GetCollection(collection); 

     mongoCollection.Save(document, 
      new MongoInsertOptions 
      { 
       WriteConcern = WriteConcern.Acknowledged 
      }); 
     } 
} 

Ich versuche, ein einfaches Dokument zu schreiben:

{ id: "2112", name: "Rush" } 

Aber egal, was ich zu dem Verfahren senden, erhalte ich eine Fehler ähnlich dem: "Speichern kann nur mit Dokumenten verwendet werden, die eine ID haben."

Wir haben versucht, eine Reihe von verschiedenen Eigenschaften für ID (ID, ID, _ID), aber sie alle führen zu einem ähnlichen Problem.

Irgendwelche Ideen?

Dank

Antwort

10

Mit Hilfe von einem Mitarbeiter, dachte ich, eine Lösung aus:

public class PassThroughController : ApiController 
{ 
    [Route("api/mongodb/{collection}")] 
    public void Post(string collection, HttpRequestMessage message) 
    { 
     const string connectionString = "mongodb://localhost"; 

     var client = new MongoClient(connectionString); 
     var db = client.GetServer().GetDatabase("SampleDb"); 
     var mongoCollection = db.GetCollection(collection); 

     var json = message.Content.ReadAsStringAsync().Result; 
     var document = BsonSerializer.Deserialize<BsonDocument>(json); 

     mongoCollection.Save(document, 
      new MongoInsertOptions 
      { 
       WriteConcern = WriteConcern.Acknowledged 
      }); 
     } 
} 
0

Ich habe versucht, zu einem ProcessID assoziierte einiges dynamisches Objekt zu speichern, ist es das dynamische Objekt ist total " dynamisch ", manchmal kann es eine Eigenschaft mit beliebigen Daten und Namen sein, manchmal kann es eine 100 Eigenschaften mit völlig beliebigen Namen für jede Eigenschaft sein. Tatsächlich ist es ein Objekt, das von einer Angular 5-App kommt, die ein dynamisches Formular von (Überraschung) einem JSON-Objekt erzeugt. Meine „Basis“ Klasse, die eine, die in Mongo eingefügt bekommen es so ist:

public class MongoSave { 

    [BsonId(IdGenerator = typeof(StringObjectIdGenerator))] 
    public string Id { get; set; }   
    public int ProcessID { get; set; } 
    public BsonDocument DynamicData { get; set; } 

} 

Bei meinem ersten Versuch, die DynamicData Eigenschaft wurde Typ object, die Controller-Methode alles in Ordnung empfangen werden, weisen Sie das eingehende Objekt der Klasse, aber Beim Speichern des Objekts in Mongo gingen die Werte für DynamicData verloren. Ich bekam nur die Eigentumsnamen. Versucht, die BsonSerialize Annotation in meiner Klasse zu verwenden, aber ohne Erfolg.

ein wenig Researching ich entdeckt, dass BsonDocument ein Parse Verfahren ähnlich wie Javascript hat, die eine Zeichenfolge enthält eine Objektbeschreibung analysieren, so ... Ich veröffentlichte ein Objekt wie folgt zu meinem Controller:

{ 
    "ProcessID": 987, 
    "DynamicData": { 
     "name": "Daniel", 
     "lastName": "Díaz", 
     "employeeID": 654 
    } 
{ 

A einige Dinge hier, ich sende via Insomnia (eine Postman-Alternative) diesen JSON an die API. In der realen Welt werde ich dieses Objekt über Angular senden, so muss ich sicher sein, JSON.stringify(obj) anzuwenden, um sicher zu sein, dass das JSON-Objekt in Ordnung ist (nicht sicher, ob die Angular HttpClient Objekte als JSON-Objekte oder als JS-Objekte posten) (ich werde testen, dass) geändert meine Controller-Aktion die Parse Methode und die DynamicData C# generische object zu Zeichenfolge wie folgt zu verwenden:.

[HttpPost("~/api/mongotest/save")] 
public async Task<IActionResult> PostObjectToMongo (MongoSaveDTO document) { 

    MongoSave mongoItem = new MongoSave() { 
     ProcessID = document.ProcessID, 
     DynamicData = BsonDocument.Parse(document.DynamicData.ToString()) 
    }; 

    await _mongoRepo.AddMongoSave(mongoItem); 

    return Ok(); 
} 

die MongoSaveDTO es ist die gleiche wie MongoSave ohne BsonId Eigenschaft und statt BsonDocument Ich benutze C# generische object Art und alles speichert wie ein Charme.