Search code examples
mongodbasp.net-coreurl-shortener

Overwrite data associated with a specific ObjectId?


I am attempting to to change the "OriginalUrl" that is already created and stored in the database under a random ObjectId like this:

{
    "_id" : ObjectId("5b1551d571231d26444d5c35"),
    "Title" : "Test5",
    "Code" : "n3b4nb_jxnm2",
    "OriginalUrl" : "https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-web-api-mac?view=aspnetcore-2.1",
    "Url" : null
}

I have a Post Get and Delete method working but my Put method is not doing what I understand to be the way to do this according to https://learn.microsoft.com/

[HttpPut("{id}")]
        public async Task<IActionResult> Update(string id, [FromBody] string su)
        {
            var gameFromDb = await _repo.GetAsync(id);
            if (gameFromDb == null)
            {
                return new NotFoundResult();
            }

            su = gameFromDb;
           // await _repo.Update(su);
            return new OkObjectResult(su);
        }

I am still learning so I sincerely apologize if this is an obvious answer that I have not yet discovered on this site or elsewhere.

Update:

        [HttpPut("{id}")]
        public async Task<IActionResult> Update(string id, [FromBody] string su)
        {
            return (await _repo.Update(ObjectId.Parse(id)))
                ? (IActionResult)Ok("Updated Successfully")
                : NotFound();
        }
    }
}

Repository:

public async Task<bool> Update(ObjectId id)
{
    var filter = new ShortUrl("_id", 10);
    var replacement = new BsonDocument { { "_id", 10 }, { "x", 2 } };

    var r = _db.Urls.ReplaceOne(filter, replacement);
    return r.IsAcknowledged

}

Update:

I realize there are similar articles to this such as:

https://stackoverflow.com/questions/41493327

And:

https://stackoverflow.com/questions/41483648

But neither helped. I don't want to hard code "First Name", "John" to "FirstName", "Jack". I need to be able to search the Id associated with "John" and change First Name to what ever the user passes. I was thinking something like this:

public async Task<bool> Update(ObjectId id)
        {
var filter = Builders<ShortUrl>.Filter.Eq(x => x.Id, id);
var r = await _db.UrlsFindOneAndUpdate(filter, update);
return r.IsAcknowledged;
}

but obviously this is incorrect. Any feedback would be greatly appreciated.


Solution

  • I found absolutely nothing useful in helping me solve this but I eventually got this to work:

    Controller class:

    public async Task<IActionResult> Update(string id, [FromBody]ShortUrl entity)
            {                 
                if (await _repo.Update(id, entity))
                {
                    return Ok();
                }
    
                return NotFound();
            }
        }
    

    Repository Class:

       public async Task<bool> Update(string Id, ShortUrl shortUrl)
        {
          var objId = ObjectId.Parse(Id);
    
            var ub = Builders<ShortUrl>.Update;
    
            var updates = new List<UpdateDefinition<ShortUrl>>();
    
            if (!string.IsNullOrWhiteSpace(shortUrl.Title))
            {
                updates.Add(
                    ub.Set(x => x.Title, shortUrl.Title));
            }
    
            if (!string.IsNullOrWhiteSpace(shortUrl.OriginalUrl))
            {
                updates.Add(
                    ub.Set(x=>x.OriginalUrl,shortUrl.OriginalUrl));
            }
    
            if (updates.Count == 0) return false;
    
           var result = await _db.Urls.UpdateOneAsync(
                x => x.Id == objId,
                ub.Combine(updates));
    
            return result.ModifiedCount > 0;