Searching method in asp.net core - asp.net-core

I'm building an asp.net core searching API which should return a list of videos who has the same searched QR code(the QR code is a ForeignKey)
This is the video model:
public class Video
{
[Key]
public int VideoId { get; set; }
public string Exercice { get; set; }
public string Titre { get; set; }
public int Sexe { get; set; }
public int Categorie { get; set; }
public int Level { get; set; }
public string FilePath { get; set; }
public DateTime DateUpload { get; set; } = DateTime.Now;
[ForeignKey("Machine")]
public string Machine_Qr { get; set; }
public Machine machine { get; set; }
public Coache Coache { get; set; }
}
And this is the search controller:
[HttpGet("{Qr}")]
public async Task<IEnumerable<Video>> Search(string qr)
{
IEnumerable<Video> query = _context.videos.Where(e => e.Machine_Qr == qr);
if ((query != null))
return query;
else
return Enumerable.Empty<Video>().ToList();
}
but I tested it and I got an empty list every time.

Edit: your edit fixed the first logic issue in the original question. But the query also needs to have an await since the function is an async Task.
Since your function returns an IEnumerable, you shouldn't need to call .ToList() ... try this:
[HttpGet("{Qr}")]
public async Task<IEnumerable<Video>> Search(string qr)
{
return await _context.videos.Where(e => e.Machine_Qr == qr) ?? Enumerable.Empty<Video>()
}

Related

Asp net core to list the author's books on the page

I want to show the books belonging to the author on the author edit page, but all the books are displayed on the page. I want to select and show only the books belonging to that author.
Admin Controller Page :
[HttpGet]
public IActionResult AuthorEdit(int? id)
{
if(id==null)
{
return NotFound();
}
var entity = _authorService.GetByIdWithBooks((int)id);
if(entity==null)
{
return NotFound();
}
var model = new AuthorModel()
{
Books = _bookService.GetAll(),
AuthorId = entity.AuthorId,
NameLastName = entity.NameLastName,
Description = entity.Description,
};
return View(model);
}
GetByIdWithBooks
public Author GetByIdWithBooks(int authorId)
{
return BookContext.Authors
.Where(i=>i.AuthorId==authorId)
.FirstOrDefault();
}
Book Model :
public class Book
{
public int BookId { get; set; }
public string Name { get; set; }
public string Url { get; set; }
public double? Price { get; set; }
public string Description { get; set; }
public string ImageUrl { get; set; }
public string BarcodeNumber { get; set; }
public int PageCount { get; set; }
public string FirstPrintDate { get; set; }
public bool IsApproved { get; set; }
public bool IsHome { get; set; }
public DateTime DateAdded { get; set; }
public List<BookCategory> BookCategories { get; set; }
public int AuthorId { get; set; }
public Author Author { get; set; }
public int PublisherId { get; set; }
public Publisher Publisher { get; set; }
}
Author Model :
public class Author
{
public int AuthorId { get; set; }
public string NameLastName { get; set; }
public string ImageUrl { get; set; }
public string Description { get; set; }
public List<Book> Books { get; set; }
}
If you're using EF you could just change GetByIdWithBooks() method to do it, and it would make sense.
public Author GetByIdWithBooks(int authorId)
{
return BookContext.Authors
.Include(c => c.Books)
.Where(i=>i.AuthorId==authorId)
.FirstOrDefault();
}
Since you have a FK between Books -> Author the "Include" would make the necessary joins to bring back the related books.
Or, if you want to keep the _booksService.GetAll() call, which in my opinion, may not make a lot of sense:
_bookService.GetAll().Where(c => c.AuthorId == id)
Which should probably be a different method inside your service.
Is that what you were trying to achieve?

Mapbox matching response convert to dynamic json in ASP.NET Core

I want to use mapbox matching in ASP.NET Core. This link you can get response https://api.mapbox.com/matching/v5/mapbox/driving/..
I want to convert this response to dynamic json in Asp.net core, I use this line
var jsonResponse = JsonConvert.DeserializeObject(mapResponse);
but I get empty values. Any help?
Firstly, The API you have shared I got follwing response using
postman:
If its same what you are getting then I follow below steps to retrive
the value from the API response in C# asp.net core controller
Model You should have :
public class Admin
{
public string iso_3166_1_alpha3 { get; set; }
public string iso_3166_1 { get; set; }
}
public class Leg
{
public List<object> via_waypoints { get; set; }
public List<Admin> admins { get; set; }
public double weight { get; set; }
public double duration { get; set; }
public List<object> steps { get; set; }
public double distance { get; set; }
public string summary { get; set; }
}
public class Matching
{
public double confidence { get; set; }
public string weight_name { get; set; }
public double weight { get; set; }
public double duration { get; set; }
public double distance { get; set; }
public List<Leg> legs { get; set; }
public string geometry { get; set; }
}
public class Tracepoint
{
public int matchings_index { get; set; }
public int waypoint_index { get; set; }
public int alternatives_count { get; set; }
public double distance { get; set; }
public string name { get; set; }
public List<double> location { get; set; }
}
public class MapResponseClass
{
public List<Matching> matchings { get; set; }
public List<Tracepoint> tracepoints { get; set; }
public string code { get; set; }
public string uuid { get; set; }
}
Asp.net core Controller:
public async Task<IActionResult> CallMapAPI()
{
try
{
HttpClient client = new HttpClient();
HttpResponseMessage response = await client.GetAsync("https://api.mapbox.com/matching/v5/mapbox/driving/-117.17282,32.71204;-117.17288,32.71225;-117.17293,32.71244;-117.17292,32.71256;-117.17298,32.712603;-117.17314,32.71259;-117.17334,32.71254?access_token=pk.eyJ1Ijoibm92ZXJzbWFwIiwiYSI6ImNreTdwc3ppNTE3dzkyb3B2MnVzNXpueTUifQ.csYTL2GKkl99Yqk_TQjr5w");
response.EnsureSuccessStatusCode();
string mapAPIjson = await response.Content.ReadAsStringAsync();
var data = JsonConvert.DeserializeObject<MapResponseClass>(mapAPIjson);
}
catch (Exception ex)
{
throw;
}
return data;
}}
Output:
Note:
You should bound your class as per your API response. What I am
assuming of your empty values is you haven't converted the relevant
class accordingly. I hope above steps guided you accordingly.

map string filed to generic list in automapper based on .net core

I have a DomainModel and a DTO like this :
public class PostEntity: IEntity
{
[Required]
public string Description { get; set; }
public int Id { get; set; }
[Required]
public string Slug { get; set; }
[Required]
public string Tags { get; set; }
[Required]
public string Title { get; set; }
[Required]
public DateTime CreatedOn { get; set; }
public DateTime? UpdatedOn { get; set; }
public PostStatus Status { get; set; }
public User Writer { get; set; }
public int WriterId { get; set; }
}
public class PostDto
{
public int Id { get; set; }
public string Description { get; set; }
public string Slug { get; set; }
public string Tags { get; set; }
public string Title { get; set; }
public DateTime CreatedOn { get; }
public List<string> TagList { get; set; }
public PostDto()
{
TagList = new List<string>();
}
}
PostEntity'Tags contains some tags seperated by ",", now I want to split tags value by "," and convert it to List, to do this, I've tried this but I get the below compilation error
CreateMap<PostEntity, PostDto>().ForMember(dest => dest.TagList, cc => cc.MapFrom(src => src.Tags.Split(",").ToList()));
I get this error :
An expression tree may not contain a call or invocation that uses optional arguments
I can't reproduce your error, it seems to work fine.
Below is an example where the TagList is correctly mapped
The code I used :
MapperConfiguration MapperConfiguration = new MapperConfiguration(configuration =>
{
configuration
.CreateMap<PostEntity, PostDto>().ForMember(dest => dest.TagList, cc => cc.MapFrom(src => src.Tags.Split(',').ToList()));
});
IMapper mapper = MapperConfiguration.CreateMapper();
PostEntity postEntity = new PostEntity
{
Tags = "Tag1,Tag2,Tag3,Tag4"
};
var mappedObject = mapper.Map<PostEntity, PostDto>(postEntity);
Please bear in mind that Expression.Call API does not support optional parameters. So, you should Replace Split(',') with
Split(',', System.StringSplitOptions.None)
or
Split(',', System.StringSplitOptions.RemoveEmptyEntries)
doing so you won't see that error again.

How can I display the number of posts?

I create a forum and I have a problem: how can I add the number of posts for each category? I would like to use the viewmodel
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public virtual List<Post> Posts { get; set; }
}
public IActionResult Index()
{
var model = categoryService.GetAll();
return View(model);
}
You can add a property to your ViewModel that will retrieve the number of Post's for that Category.
It could look something like this:
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public virtual List<Post> Posts { get; set; }
public int PostCount
{
get
{
return Posts != null ? Posts.Count : 0;
}
}
}

EF5 Entry not updating

Im trying to update an entry with EF5 with the following actionresult:
[HttpPost]
public ActionResult Edit(int id, IEnumerable<HttpPostedFileBase> files)
{
if (ModelState.IsValid)
{
Reference reference = db.References.Single(x => x.Id == id);
db.Entry(reference).State = EntityState.Modified;
db.SaveChanges();
//Other stuff regarding files/images
return RedirectToAction("Index");
}
return View();
}
Nothing happens. When I debug it, it goes trough the code as everything was fine. But nothing is updated in the db.
Here's the model if needed:
public class Reference
{
public int Id { get; set; }
public string Headline { get; set; }
public string Text { get; set; }
public DateTime Date { get; set; }
public IEnumerable<HttpPostedFileBase> ImageUploadMain { get; set; }
public String MainFileName { get; set; }
public IEnumerable<HttpPostedFileBase> ImageUpload { get; set; }
public virtual ICollection<Image> Files { get; set; }
public virtual ICollection<RefProperties> Properties { get; set; }
public int CategoryId { get; set; }
public virtual Category Category { get; set; }
}
public class Image
{
public int Id { get; set; }
public string FileName { get; set; }
public virtual Reference Reference { get; set; }
}
public class RefProperties
{
public int Id { get; set; }
public string Key { get; set; }
public string Value { get; set; }
}
public class Category
{
public int CategoryId { get; set; }
public string Name { get; set; }
public virtual ICollection<Reference> References { get; set; }
}
Not only is the related entries not updated, a main property like "Headline" cant be updated either. What am I doing wrong? Create/delete works fine btw.
As Gert Arnold says, you're not actually modifying any of the Reference values so nothing will be updated. By calling db.Entry(reference).State = EntityState.Modified you're just setting the retrieved entity's state to modified in the ChangeTracker. When you call SaveChanges() it's just going to update the Reference record in the database with the same values that you fetched.
You need to update some of the Reference instance properties to see a change.
[HttpPost]
public ActionResult Edit(int id, IEnumerable<HttpPostedFileBase> files)
{
if (ModelState.IsValid)
{
Reference reference = db.References.Single(x => x.Id == id);
reference.HeaderText = "Changed";
/* No need to interact with the change tracker as the entity is already tracked and you've made a change */
// db.Entry(reference).State = EntityState.Modified;
/* Create/Modify/Update/Delete other entities */
db.SaveChanges();
//Other stuff regarding files/images
return RedirectToAction("Index");
}
return View();
}
Heres what I was looking for:
TryUpdateModel(reference, "");
It has a shitload of overloads. This works though