json response through MongoDb - c#

When the below API method is called through the API
public IActionResult FirstStudent()
{
var collection = this.database.GetCollection<BsonDocument>("students");
var filter = Builders<BsonDocument>.Filter.Eq("RollNo", "1");
var document = collection.Find(filter).First();
var firstStudent= document.ToJson();
return Ok(firstStudent);
}
the response has Content-Type as text/plain.
I need the Content-Type as application/json.
Any suggestions?

the easiest thing to do would be to create a student model and simply return an ok result with the student model like this:
public class Student
{
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public int RollNo { get; set; }
public string Name { get; set; }
}
public IActionResult FirstStudent()
{
var collection = this.database.GetCollection<Student>("Student");
var filter = Builders<Student>.Filter.Where(s => s.RollNo == 1);
var document = collection.Find(filter).First();
return Ok(document);
}

Related

Problems passing parameter to an action

I'm trying to pass data to an action inside the same controller. I'm using RedirectToAction, but I'm not succeeding.
The action is called but the data I'm trying to pass to it has its values ​​null.
My Model:
public class PlaylistModel
{
public Guid PlayListID { get; set; }
[Display(Name = "Nome da Playlist")]
public string NomePlayList { get; set; }
[Display(Name = "Descrição")]
public string Descricao { get; set; }
[Display(Name = "Código")]
public string CodigoPlayList { get; set; }
public string Estado { get; set; }
public string EmailUser { get; set; }
public List<VideoThumbnails> VideosIdsYoutube { get; set; }
[Display(Name = "Categorias")]
public List<string> Categorias { get; set; }
}
This action receives the data, does the processing and calls the other action
[HttpPost]
public ActionResult CreatePlaylist(string Categorias, string NomePlayList)
{
PlaylistModel playListModel = new PlaylistModel();
playListModel.VideosIdsYoutube = AppCache.Instance.VideoParaAPI.VideoThumbnails.ToList();
playListModel.Categorias = Categorias.Split(',').ToList();
playListModel.NomePlayList = NomePlayList;
playListModel.Estado = EnumEstadoDaPlayList.Nova.ToString();
playListModel.EmailUser = AppUser.User.Email;
var api = new AccessAPI.Playlist.AccessAPIPlaylist();
var playlist = api.CriarNova(playListModel);
if(playlist != null)
{
return RedirectToAction("ExibirPlaylist", new RouteValueDictionary(new { controller = "Playlist", action = "ExibirPlaylist", pPlayList = playlist }));
}
else
{
return Problem("Não foi possível criar a playlist!");
}
}
This other action is called by the previous one, but the model arrives with null values
[HttpGet]
public ActionResult ExibirPlaylist(PlaylistModel pPlayList)
{
var apiVideo = new AccessAPI.Video.AccessAPIVideo();
var videos = apiVideo.ConsultarPorPlayListId(pPlayList.PlayListID).ToList();
if(videos.Count > 0)
{
videos.ForEach(v =>
{
pPlayList.VideosIdsYoutube.Add(new Dommain.Cache.VideoThumbnails() { CanalID = v.CanalID, DataDePublicacao = v.DataDePublicacao, NomeDoCanal = v.NomeDoCanal, NomeDoVideo = v.NomeDoVideo, Thumbnail = v.Thumbnail, VideoId = v.VideoIdYoutube});
});
}
return View();
}
The RouteValueDictionary in RedirectToAction() pass only simple types, like string, int etc. The RedirectToAction() doesn't serialize the complex data types. Therefore, may be the easiest way to use the TempData.
In the CreatePlaylist(string Categorias, string NomePlayList):
TempData["playListModel"] = playlist;
return RedirectToAction("ExibirPlaylist");
And then:
[HttpGet]
public ActionResult ExibirPlaylist()
{
if (TempData["playListModel"] is PlaylistModel pPlayList)
{
// Your code using `pPlayList`
}
return View("Index");
}
The MVC uses the binary serialization, by default. And in some cases the binary serialization can fail: Storing objects (non-string things) in TempDataDictionary does not round trip correctly. Therefore, it is preferably to serialize the specified object to a JSON string by JsonConvert.SerializeObject().

How to convert data from mongodb document to List

I Create a web-site and I have a problem. When I'm tring to get datas from mongodb and convert it to list, I have an error "Cannot apply indexing with [] to an expression of type 'CategoryModel'"
this is classes
public class CategoryModel
{
[BsonId]
public ObjectId id { get; set; }
[BsonElement("title")]
[JsonProperty("title")]
public string Name { get; set; }
[BsonElement("slug")]
public string slug { get; set; }
[BsonElement("__v")]
public int __v { get; set; }
}
public class ProductsModel
{
[BsonId]
public ObjectId id { get; set; }
[BsonElement("title")]
public string Name { get; set; }
[BsonElement("desc")]
public string Desc { get; set; }
[BsonElement("price")]
public int price { get; set; }
[BsonElement("category")]
public CategoryModel category { get; set; }
[BsonElement("image")]
public string ImageURL { get; set; }
}
this is my conntroller
public class ProductsController:Controller
{
private readonly IConfiguration _configuration;
List<CategoryModel> categoriesList = new List<CategoryModel>();
List<ProductsModel> productsList = new List<ProductsModel>();
[HttpGet("products")]
public async Task<IActionResult> Product()
{
var client = new MongoClient("mongodb://localhost:27017/");
var database = client.GetDatabase("cmscart");
var collection = database.GetCollection<CategoryModel>("categories");
var result = await collection.Find(new BsonDocument()).ToListAsync();
foreach (var item in result)
{
categoriesList.Add(new CategoryModel() { Name = (string)item["[title]"] }); //here I have an error
}
//products
var client2 = new MongoClient("mongodb://localhost:27017");
var database2 = client2.GetDatabase("cmscart");
var collection2 = database2.GetCollection<ProductsModel>("products");
var result2 = await collection2.Find(new BsonDocument()).ToListAsync();
foreach (var item2 in result2)
{
productsList.Add(new ProductsModel() { Name = (string)item2["title"], Desc = (string)item2["desc"], price = (int)item2["price"], ImageURL = (string)item2["image"] }); // and here I have an error
}
return View(categoryProduct);
}
}
I found a lot of solutions but I don't understand why this error is appear, because if this trick do with SQL then I don't have this error
You should be able to use the deserialized object directly:
var client = new MongoClient("mongodb://localhost:27017/");
var database = client.GetDatabase("cmscart");
var collection = database.GetCollection<CategoryModel>("categories");
List<CategoryModel> categoriesList = await collection.Find(new BsonDocument()).ToListAsync();
//products
var collection2 = database2.GetCollection<ProductsModel>("products");
List<ProductsModel> products = await collection2.Find(new BsonDocument()).ToListAsync();
Also, don't use class properties for local variables, declare everything in the innermost scope possible (in general). Ideally the MongoClient or Database would be injected into the class constructor too. You don't want to be instantiating them in an action method and you definitely don't want configuration values in there.

Customize returning JSON from ASP.NET Core API , Values with Statuscode

I'm trying to return back JSON with customization , anyone can help to return the result like this :
{
status: 200,
message: "success",
data: {
var1: {
},
var2: {
}
}
}
with this code :
return Ok(new
{
var1,
var2
});
Why do you need to use the OkResult object?
A simple way of returning what you'd like is to use dynamic objets, or a class with properties matching the Json you'd like to get, and a JsonResult object.
dynamic json = new ExpandoObject();
json.Result = 200;
json.Message = "success";
json.Data.var1 = "whatever";
json.Data.var2 = "something else";
Response.StatusCode = json.Result; //matches the HTTP Status Code with the one from your json
return new JsonResult(json);
I used this for taking profile information from google id token , and then generate JWT token from my backend server and retuen back JWT and Profile info for client apps so this is the solution :
var profile = (new RetrnedUserProfile
{
Email = payload.Email,
FirstName = payload.GivenName,
FamilyName = payload.FamilyName,
PictureUrl = payload.Picture
});
return Ok(new ResponseModel
{
StatusCode = HttpStatusCode.OK,
Message = "success",
Data = new
{
profile,
accessToken
}
});
public class RetrnedUserProfile
{
public string FirstName { get; set; }
public string FamilyName { get; set; }
public string Email { get; set; }
public string PictureUrl { get; set; }
}
public class ResponseModel
{
public HttpStatusCode StatusCode { get; set; }
public string Message { get; set; }
public object Data { get; set; }
}

Remove ObjectId from mongodb document serialized to JSON in C#

I'm having a bit of an issue here. I am getting all my products from a mongodb collection with this function:
public async Task<string> getAllProducts()
{
List<string> all = new List<string>();
var document = await getCollection("produits").Find(new BsonDocument()).ToCursorAsync();
foreach (var doc in document.ToEnumerable())
{
var res = doc.ToJson();
all.Add(res);
}
return JsonConvert.SerializeObject(all);
}
and it returns a JSON that looks like this to my react front end.
{ "_id" : ObjectId("5e49bdf5f040e808847a17d7"),
"email" : "example#gmail.com",
"quantite" : 1,
"matricule" : 1}
problem is i cant parse this in my javascript because of this : ObjectId("5e49bdf5f040e808847a17d7")
Of course I could do some string magic before I parse it, but id rather it be corrected on the server side. So is there a way I can get rid of this problem and get a result like this?
{ "_id" : "5e49bdf5f040e808847a17d7",
"email" : "example#gmail.com",
"quantite" : 1,
"matricule" : 1}
give this a try. it will serialize string ids without objectid stuff.
public static async Task<string> getAllProducts()
{
var collection = db.GetCollection<object>("produits");
var all = new List<object>();
using (var cursor = await collection.FindAsync("{}"))
{
while (await cursor.MoveNextAsync())
{
foreach (var doc in cursor.Current.ToArray())
{
all.Add(doc);
}
}
}
return Newtonsoft.Json.JsonConvert.SerializeObject(all);
}
Fixed by creating a class for the mongodb object.
public class Product
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public int matricule { get; set; }
public int quantite { get; set; }
public string email { get; set; }
public float prix { get; set; }
public string image { get; set; }
}
get them and deserialize with BsonSerializer :
public async Task<List<Product>> getAllProducts(){
var collection = await getCollection("produits").Find(new BsonDocument()).ToListAsync();
List<Product> all = new List<Product>();
foreach(var doc in collection){
all.Add(BsonSerializer.Deserialize<Product>(doc));
}
return all;
}
return them on request :
[HttpGet]
public async Task<string> ShowProductsAsync()
{
MongodbModel model = new MongodbModel();
var products = await model.getAllProducts();
Console.WriteLine(products);
return JsonConvert.SerializeObject(products);
}
string GetAllProduits(){
var collection = database.GetCollection<BsonDocument>("produits");
var project = Builders<BsonDocument>.Projection.Exclude("_id");
var filter = Builders<BsonDocument>.Filter.Empty;
var rlt=collection.Find(filter).Project(project);
return rlt.ToList().ToJson();
}

Return object as json

I have this class.
public class SDS
{
public Guid A { get; set; }
public Guid B { get; set; }
public String C { get; set; }
}
I return the json like this
public HttpResponseMessage Val()
{
SDS svr = new SDS();
svr.A = ...
svr.B = ...
svr.C = ...
return Request.CreateResponse(HttpStatusCode.OK, json_serializer.Serialize(svr), "application/json");
}
In the client side I use jquery like this
var obj = jQuery.parseJSON(jqXHR.responseText);
The problem is that the json that gets returned is like this and I am unable to iterate ofer the values or access the elements via index:
{"A":"3a9779fe-9c92-4208-b34d-5113e0548d50","B":"206575a5-8a90-4a13-89ec-910e5a9a35a1","C":"Meta"}
To solve this issue I had to do this and this works:
obj = jQuery.parseJSON('{"List":[' + obj + ']}');
My question is is there any way to use an attribute on the class so that it returns a json that I can use?
[SomeAttribute name="List"]
public class SDS
{
public Guid A { get; set; }
public Guid B { get; set; }
public String C { get; set; }
}
...
...
...
Update2:
This question is still open as none of the provided answers were able to produce a fix.
You can return a JsonResult by calling Json() in your action method.
public ActionResult Get(int id)
{
var item = ...
return Json(item);
}
Did you try to use the JsonResult from System.Web.Mvc.JsonResult ?
public JsonResult Val() {}
Hope this Helps.
The JSON returned is correct, don't change anything in your controller
..but in your JS loop the object with a for in loop
for(var propertyName in obj){
...
}
propertyName gives you A, B and C
and...
var value = obj[propertyName]
gives you the value
Well, you're returning a single object, not a list, but you could do:
public HttpResponseMessage Val()
{
SDS svr = new SDS();
svr.A = ...
svr.B = ...
svr.C = ...
var list = new {List = new [] {svr}};
return Request.CreateResponse(HttpStatusCode.OK, json_serializer.Serialize(svr), "application/json");
}
add ApiController and using System.Web.Http;

Categories

Resources