Unable to store images to database - asp.net

The following code below:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Car model, HttpPostedFileBase file)
{
var currentUser = UserManager.FindById(User.Identity.GetUserId());
var user = this.db.Users.Where(u => u.Id == currentUser.Id).FirstOrDefault();
if(ModelState.IsValid)
{
if (file != null && file.ContentLength > 0)
{
var photo = new FilePath
{
FileName = Guid.NewGuid().ToString() + System.IO.Path.GetExtension(file.FileName),
FileType = FileType.Photo
};
model.FilePaths = new List<FilePath>();
model.FilePaths.Add(photo);
file.SaveAs(Path.Combine(Server.MapPath("~/Images/"), photo.FileName));
}
user.Cars.Add(model);
db.SaveChanges();
return RedirectToAction("Default", "Home");
}
SetCategoryViewBag(model.Category.CategoryId);
return View(model);
}
Won't let me to store any images to the database. The image table doesn't store any information at all. However, the cars table is ok, but images is still showing as null.
What have I done wrong here?
Edit:
Car model:
public class Car
{
[Key]
public int CarId { get; set; }
public string Title { get; set; }
public int Price { get; set; }
public virtual Category Category { get; set; }
public int CategoryId { get; set; }
public virtual ICollection<FilePath> FilePaths { get; set; }
}
FilePath model:
public class FilePath
{
public int FilePathId { get; set; }
[StringLength(255)]
public string FileName { get; set; }
public FileType FileType { get; set; }
public int CarId { get; set; }
public virtual Car Cars { get; set; }
}

Related

How to save data in many to many relation without duplicate in my Card table [Entity Framework]

I have a problem. I cannot save cards without duplicates.
I have 3 tables a Deck, Card table and a CardDeck table which is the junction table.
The goal is to store a deck in the database without the cards being duplicated.
Table Card
namespace MTG_Deck.Models
{
public class Card
{
[Key]
public int CardId { get; set; }
public string Name { get; set; }
public string Text { get; set; }
public string Type { get; set; }
public string SetName { get; set; }
public string Artist { get; set; }
public string ManaCost { get; set; }
public string Rarity { get; set; }
public string ImageUrl { get; set; }
public string Toughness { get; set; }
public string Power { get; set; }
public string id { get; set; }
public virtual ICollection<DeckCard> Decks { get; set; }
}
}
Table Deck
namespace MTG_Deck.Models
{
public class Deck
{
[Key]
public int DeckId { get; set; }
[Required]
public string Name { get; set; }
[DataType(DataType.Date)]
public DateTime CreateAt { get; set; }
public User User { get; set; }
public virtual ICollection<DeckCard> Cards { get; set; }
}
}
Table CardDeck
namespace MTG_Deck.Models
{
public class DeckCard
{
public int DeckID { get; set; }
public int CardID { get; set; }
public Deck Deck { get; set; }
public Card Card { get; set; }
}
}
CardDeckRequest contains the content of the request.
namespace MTG_Deck.Models
{
public class CardDeckRequest
{
[Required]
public int UserID { get; set; }
[Required]
public string Token { get; set; }
[Required]
public Deck Deck { get; set; }
[Required]
[MinLength(5, ErrorMessage = "The deck must contain 60 cards.")]
public List<Card> Cards { get; set; }
}
}
Controller
[HttpPost]
public IActionResult Add([FromBody] CardDeckRequest request)
{
User user = _context.User.Where(u => u.Token == request.Token).FirstOrDefault<User>();
if (user == null) {
var error = new string[] {"You have to be connected to create a deck!"};
BadRequest(new { errors = new { success = error } });
}
List<DeckCard> deckList = new List<DeckCard>();
if (ModelState.IsValid) {
request.Deck.User = user;
foreach (var item in request.Cards)
{
Card card = _context.Card.FirstOrDefault(c => c.Name == item.Name);
if (card == null) {
card = item;
Console.WriteLine("coucou");
}
DeckCard deckCard = new DeckCard {
Card = card,
Deck = request.Deck
};
deckList.Add(deckCard);
}
_context.DeckCard.AddRange(deckList);
_context.SaveChanges();
var error = new string[] {"Your deck has been successfully saved."};
return Ok(new { errors = new { success = error } });
}
return BadRequest(ModelState.ToDictionary(
kvp => kvp.Key,
kvp => kvp.Value.Errors.Select(e => e.ErrorMessage).ToArray()
));
}

generate a list of products of a category

I am developing a shop application and I need to show products of each category. The problem is each product is created from a product template which is stored in a table and each template is related to a category. here is the product model:
namespace fardashahr.Models
{
[Table("Product")]
public class ProductModel
{
public ProductModel()
{
if (Specs == null)
{
Specs = new Dictionary<string, SpecItemsModel>();
}
}
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
public int ProductTemplateId { get; set; }
[Required]
public bool IsPublished { get; set; }
[Required]
public bool InStock { get; set; }
[Range(95, 110)]
public float SyncRate { get; set; }
public DateTime? ProductionDate { get; set; }
[Required]
public DateTime RegisterationDate { get; set; }
public string ImageName { get; set; }
public IEnumerable<string> GalleryImages { get; set; }
[NotMapped]
public Dictionary<string, SpecItemsModel> Specs { get; set; }
[ForeignKey("ProductTemplateId")]
public virtual ProductTemplateModel ProductTemplate { get; set; }
[ForeignKey("ManufacturerId")]
public virtual CodingItemModel Manufacturer { get; set; }
[ForeignKey("BrandId")]
public virtual CodingItemModel Brand { get; set; }
[ForeignKey("ModelId")]
public virtual CodingItemModel Model { get; set; }
[ForeignKey("SeriesId")]
public virtual CodingItemModel Series { get; set; }
}
}
and here is the the ProductTemplate:
namespace fardashahr.Models
{
[Table("ProductTemplate")]
public class ProductTemplateModel
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[StringLength(500)]
public string Name { get; set; }
[Required]
public int CategoryId { get; set; }
[StringLength(500)]
public string Description { get; set; }
[ForeignKey("CategoryId")]
public virtual CategoryModel Category{ get; set; }
}
}
and the controller is:
namespace fardashahr.Controllers
{
public class ProductsController : Controller
{
// GET: Products
public ActionResult Index()
{
return RedirectToAction("Index", "Home");
}
public ActionResult Category(string name)
{
//declare a list of products
List<ProductModel> productList;
using(MainModel db = new MainModel())
{
//get category id
CategoryModel category = db.Categories.Where(x => x.CategorytUrl == name).FirstOrDefault();
int catId = category.Id;
//initialize the list
productList = db.Products.Where(x => x. == catId).ToList();
}
}
}
}
finaly, what I want to know is how to initialize a list of products.
In your models, you added virtual keyword which indicates that navigation property will be automatically loaded without the need of LINQ lambda .include() expression.
Hence you can immediately access the navigation property and load the list like this;
productList = db.Products.Where(x => x.ProductTemplate.CategoryId == catId).ToList();
string categoryNameOfFirstProduct = productList.FirstOrDefault().ProductTemplate.Category.Name;
string categoryNameOfFirstProduct = productList.FirstOrDefault().ProductTemplate.Category.CategorytUrl;

How to include another table to view its data in Views in asp.net mvc

I have this code -
var add = (from h in db.Hotels
where h.Address.Contains(hotels.Address)
select h).Take(2);
ViewBag.Related = add;
Now, in the View, I want to display the images, so I'm using this code -
<img src="~/img/#item.FirstOrDefault().Image" />
This is giving me this error -
'System.Data.Entity.DynamicProxies.Hotels_D1EE6FD2E11BD1D9436F26FEA6336CFE76F33C59111E2ABC7C1BBE456FF61C23' does not contain a definition for 'FirstOrDefault'
I've tried using 'joins' also but same error occurs. Please help me out in this! :(
My Hotels class -
public class Hotels
{
[ScaffoldColumn(false)]
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Address { get; set; }
[StringLength(8)]
public string PinCode { get; set; }
public string Phone { get; set; }
public string Email { get; set; }
public string FilledBy { get; set; }
public DateTime DateAdded { get; set; }
//public int ImageId { get; set; }
public int TotalRooms { get; set; }
public bool Available { get; set; }
public virtual ICollection <Rooms> Rooms { get; set; }
public virtual ICollection <Images> Images { get; set; }
public virtual ICollection<Ameneties> Ameneties { get; set; }
public virtual ICollection <Bookings> Bookings { get; set; }
public virtual ICollection<NearByLocations> Nearby { get; set; }
public virtual ICollection<Ratings> Ratings { get; set; }
public virtual ICollection<RoomType> RoomTypes { get; set; }
public virtual ICollection<CustomerReviews> Reviews { get; set; }
public virtual ICollection<HotelRules> HotelRules { get; set; }
}
My Images class -
public class Images
{
[ScaffoldColumn(false)]
public int id { get; set; }
public string Image { get; set; }
public int? HotelId { get; set; }
public virtual Hotels Hotels { get; set; }
//public ICollection<Hotels> Hotels { get; set; }
}
I have used this type of collections...
This is my Details View Controller code -
public ActionResult Details(int? id)
{
IEnumerable<Images> galleries = (from gallery in db.Images
where gallery.Hotels.Id == id
select gallery);
ViewBag.Images = galleries;
ViewBag.ImgCount = galleries.Count();
IEnumerable<Ameneties> ameneties = (from a in db.Ameneties
where a.Hotels.Id == id
select a);
ViewBag.Ameneties = ameneties;
IQueryable<Rooms> rooms = (from room in db.Rooms
where room.Hotels.Id == id
select room);
var ratings = (from rating in db.Ratings
where rating.Hotels.Id == id
select rating.Points);
ViewBag.Ratings = ratings;
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Hotels hotels = db.Hotels.Find(id);
if (hotels == null)
{
return HttpNotFound();
}
var add = db.Hotels.Include("Images").Where(h => h.Address.Contains(hotels.Address))
.Select(h => h)
.Take(2)
.ToList();
var model = new MyViewModel { Hotels = add };
ViewBag.Reviews = hotels.Reviews;
ViewBag.Ratings = hotels.Ratings;
ViewBag.NearBy = hotels.Nearby;
ViewBag.RoomTypes = hotels.RoomTypes;
ViewBag.Rules = hotels.HotelRules;
return View(hotels);
}
Could you add ToList() at the end of the query?
var add = (from h in db.Hotels
where h.Address.Contains(hotels.Address)
select h).Take(2)
.ToList();
ViewBag.Related = add;
Then you could call item.Images.FirstOrDefault()?.Image.
#foreach (var item in ViewBag.Related)
{
<img src="~/img/#item.Images.FirstOrDefault().Image" />
}
If it still doesn't work, you will need to explicitly load Image when you query Hotel. For example,
public IActionResult Index()
{
var add = db.Hotels
.Include("Images")
.Where(h => h.Address.Contains(hotels.Address))
.Select(h => h)
.Take(2)
.ToList();
var model = new MyViewModel { Hotels = add };
return View(model);
}
View
#model YourNameSpace.Models.MyViewModel
#foreach (var item in Model.Hotels)
{
<img src="~/img/#item.Images.FirstOrDefault().Image" />
}
Model
public class MyViewModel
{
public List<Hotels> Hotels { get; set; }
}

Join tables and get data from both of them

I have been trying to get data from the table I have joined to the main user table, the second table is to hold images. My current code posted below, only return the ImageID from the table when I want to be retrieving the ImagePath field, just to note this is a separate table as the user can add many images.
These are the models:
[Table("accountInfo")] // Table name
public class accountInfo
{
[Key]
public int AccountID { get; set; }
public int UserId { get; set; }
public int UserIdent { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
public virtual ICollection<UserImages > UserImages { get; set; }
}
[Table("UserImages")] // Table name
public class UserImages
{
[Key]
public int ImageID { get; set; }
public int AccountID { get; set; }
public string ImagePath { get; set; }
public string ImageDesc { get; set; }
public int ProfileImage { get; set; }
}
Controller:
public ActionResult Index()
{
int id = (int)WebSecurity.CurrentUserId;
var users = db.AccountInformation.Include(c => c.UserImages).Where(c => c.UserId == id);
return View(users.ToList());
}
I am assuming I have gone wrong in the models set up. Can anyone help?
var a = db.AccountInformation.Include(c => c.UserImages.Select(x => x.AccountId)).Where(c => c.UserId == id);

ASP.NET MVC 4 Code First Many to Many Adding to Collection

I am using ASP.NET MVC 4 code first pattern for database layer. I have a many to many relationship between UserProfile and Task. When I try to add a task to the the collection of tasks of a user, it's added but if I try to query it and see if it's there it's not showing up.
My model:
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public string FirstName { get; set; }
public string SirName { get; set; }
public string Position { get; set; }
public string Email { get; set; }
public ICollection<TaskModels> Tasks {get; set; }
public bool? isActive { get; set; }
public UserProfile()
{
Tasks = new HashSet<TaskModels>();
}
}
public class TaskModels
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public DateTime? StartDate { get; set; }
public DateTime? EndDate { get; set; }
public ICollection<UserProfile> Employees { get; set; }
public int TimeNeeded { get; set; }
public int TimeWorked { get; set; }
public string Status { get; set; }
public bool isActive { get; set; }
public TaskModels()
{
Employees = new HashSet<UserProfile>();
}
}
public class WorkLogModels
{
public int Id { get; set; }
public UserProfile Author { get; set; }
public DateTime TimeBeganWorking { get; set; }
public int TimeWorkedOn { get; set; }
public TaskModels Task { get; set; }
public string Description { get; set; }
}
public class TimeTrackerDb : DbContext
{
public TimeTrackerDb() : base("DefaultConnection")
{
}
public DbSet<UserProfile> UserProfiles { get; set; }
public DbSet<TaskModels> Tasks { get; set; }
public DbSet<WorkLogModels> WorkLogs { get; set; }
}
I try to check if a UserProfile already exists in a Task's Employees list and it's always empty.
[HttpPost]
public ActionResult Create(WorkLogModels worklogmodels)
{
var tasks = db.Tasks.Where(x => x.Name == worklogmodels.Task.Name).SingleOrDefault();
if (tasks == null)
{
return View(worklogmodels);
}
if (ModelState.IsValid)
{
var user = db.UserProfiles.Where(x => x.UserId == WebSecurity.CurrentUserId).FirstOrDefault();
var task = db.Tasks.Where(x => x.Name == worklogmodels.Task.Name).FirstOrDefault();
WorkLogModels log = new WorkLogModels();
log.Description = worklogmodels.Description;
log.TimeBeganWorking = worklogmodels.TimeBeganWorking;
log.TimeWorkedOn = worklogmodels.TimeWorkedOn;
log.Author = user;
log.Task = task;
db.WorkLogs.Add(log);
if (!db.UserProfiles.Where(x => x.UserId == WebSecurity.CurrentUserId).First().Tasks.Any(x=> x.Name == worklogmodels.Task.Name))
{
db.UserProfiles.Where(x => x.UserId == WebSecurity.CurrentUserId).FirstOrDefault().Tasks.Add(task);
db.Tasks.Where(x => x.Name == worklogmodels.Task.Name).FirstOrDefault().Employees.Add(user);
}
db.SaveChanges();
return RedirectToAction("Index");
}
return View(worklogmodels);
}
I've been fighting with this for two days now.
Any help will be greatly appreciated
EDIT:
I am not sure if I made myself clear. In the Crate action for the WorkLog Controller I am trying to put the current user in the current task's collection and vice versa. It works correctly the first time, but then if I do it again it fails to skip the if statement and tries to add it once again and throws an exception : System.Data.SqlClient.SqlException. It's trying to add the same record to the intermediate table.

Resources