Patch REST API to Partial Update MongoDB in .NET

前端 未结 4 1279
情书的邮戳
情书的邮戳 2021-02-11 02:22

I have an object

{
  \"_id\": \"testobject\",
  \"A\": \"First line\",
  \"B\": \"Second line\",
  \"C\": \"Third line\"
}

I want to send a RE

4条回答
  •  离开以前
    2021-02-11 02:29

    Not sure anyone is here >= June '20 however I did the following. I'm using NewtonSoft JObject/JArray and I wanted to create a mongo update parser/function that wouldn't know the incoming schema and would build out nested documents as well. Another thing I had to get used to (I'm new to Mongo) was the syntax of the keys in the Bson Update document i.e.

    { "key.full.path.into.nested.document" : "valueToSet" }
    

    So, after trying a few ways to manually/recursively account for the nesting/containing path of incoming JSON doc, I finally found and can just use JToken.Path property perfectly for this.

    Anyway, hopefully this is something someone will find useful. It's just an example and makes a few assumptions about the document structure but is pretty useful in its current form. And, like me, I think it might help a few people that are learning Mongo and their C# driver while also using JSON.Net to wrap the incoming REST requests.

        public BsonDocument ParseUpdateRequest(JObject req)
        {
            BsonDocument bson = new BsonDocument();
            Parse(req, ref bson);
    
            BsonDocument parsedBson = new BsonDocument();
            parsedBson["$set"] = bson;
            return parsedBson;            
        }
        private void Parse(JObject req, ref BsonDocument bson)
        {
            /**
             * Could use a parent key/node in each recursion call or just use the JToken path
             * string.IsNullOrEmpty(parentNode) ? field.Key : parentNode + "." + field.Key;
             **/ 
            string key;
            JToken val;
            foreach (var field in req)
            {
                key = field.Value.Path;                
                val = field.Value;                
                switch (val.Type)
                {
                    case JTokenType.String:
                        bson.Add(key, (string)val);
                        break;
                    case JTokenType.Integer:
                        bson.Add(key, (int)val);
                        break;
                    case JTokenType.Float:
                        bson.Add(key, (float)val);
                        break;
                    case JTokenType.Date:
                        DateTime dt = (DateTime)val;
                        bson.Add(key, dt.ToUniversalTime());                        
                        break;
                    case JTokenType.Array:
                        BsonArray bsonArray = ParseArray((JArray)val);
                        bson.Add(key, bsonArray);
                        break;
                    case JTokenType.Object:
                        Parse((JObject)val, ref bson);
                        break;
                }
            }
            return;
        }
    
        private BsonArray ParseArray(JArray source)
        {
            BsonArray bson = new BsonArray();            
            foreach (JToken field in source)
            {   
                switch (field.Type)
                {
                    case JTokenType.String:
                        bson.Add((string)field);
                        break;                    
                    case JTokenType.Date:
                        DateTime dt = (DateTime)field;
                        bson.Add(dt.ToUniversalTime());
                        break;
                    case JTokenType.Integer:
                        bson.Add((int)field);
                        break;
                    case JTokenType.Float:
                        bson.Add((float)field);
                        break;
                    case JTokenType.Object:
                        BsonDocument nestedDoc = new BsonDocument();
                        Parse((JObject)field, ref nestedDoc);
                        bson.Add(nestedDoc);
                        break;
                }
            }
            return bson;
        }
    

    And here's some simple test code I wrote:

                ModelUser user = new ModelUser();
            ControllerApp app = new ControllerApp();
            ControllerApp.Instance.User = user;
            JObject req = new JObject();
            req["first"] = "First";
            req["last"] = "Last";
            req["usertype"] = "parent";
            req["pw"] = "q345n3452345n2345";
            req["array"] = JArray.Parse("[ '1', '2', '3' ]");
            req["dateTest"] = DateTime.UtcNow;
            req["profile"] = new JObject();
            req["profile"]["name"] = new JObject();
            req["profile"]["name"]["first"] = "testUpdateFirst";
    
            BsonDocument bd;
            bd = user.ParseUpdateRequest(req);
            string s = bd.ToJson();
    

提交回复
热议问题