2014-08-27 8 views
5

Próbuję napisać ogólnego kontrolera Web Api, który pozwoli mi zapisać dokument JSON do kolekcji BEZ określania typu C#. Starałem się skraplać kod w dół do minimum:MongoDB C# - jak zapisać dowolny dokument JSON jako typ dynamiczny?

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 
      }); 
     } 
} 

Próbuję napisać prosty dokument:

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

ale bez względu na to, co wysłać do sposobu, otrzymuję podobny do następującego: "Zapisz można używać tylko z dokumentami, które mają identyfikator".

Podjęliśmy próbę szeregu różnych właściwości dla Id (Id, id, _id), ale wszystkie prowadzą do podobnego problemu.

Wszelkie pomysły?

Dzięki

Odpowiedz

10

Z pomocą współpracownika, zorientowali się rozwiązanie:

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

Starałem się zaoszczędzić trochę dynamicznego obiektu związanego z ProcessID dynamiczny obiekt jest całkowicie " dynamiczny ", czasami może to być jedna właściwość z dowolnymi danymi i nazwą, czasami może to być 100 właściwości z całkowicie arbitralnymi nazwami dla każdej właściwości. W rzeczywistości jest to obiekt pochodzący z aplikacji Angular 5, która generuje dynamiczną formę z (niespodziewanego) obiektu JSON. Moja klasa „baza”, ten, który się wstawiony Mongo to tak:

public class MongoSave { 

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

} 

Na mojej pierwszej próbie własnością DynamicData został typ object metoda kontroler otrzymał wszystko ok, przypisać obiekt przychodzące do tej klasy, lecz podczas zapisywania obiektu do mongo wartości DynamicData zostały utracone. Otrzymywałem tylko nazwy nieruchomości. Próbowałem użyć adnotacji BsonSerialize w mojej klasie, ale bez powodzenia.

Badanie trochę odkryłem, że BsonDocument ma Parse metodę podobną do javascript że analizowania ciąg zawierający opis obiektu, więc ... pisał obiektu podobnego do mojego kontrolera:

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

A kilka rzeczy tutaj, wysyłam przez Insomnia (alternatywa Listonosza) ten JSON do API. W prawdziwym świecie będę wysyłał ten obiekt przez Angular, więc muszę się upewnić, że zastosowałem JSON.stringify(obj), aby upewnić się, że obiekt JSON jest w porządku (nie wiem na pewno, czy obiekty Kątowe HttpClient są obiektami JSON lub JS (będę testować to) Zmieniono moje działania kontrolera użyć metody Parse i DynamicData C# rodzajowe object ciąg tak:.

[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(); 
} 

MongoSaveDTO jest taka sama jak MongoSave bez właściwości BsonId i zamiast BsonDocument używam typ C# generic object i wszystko zapisuje jak urok.