Creating a comment-like box in ASP.NET Core - asp.net-mvc

I'm trying to create a comment and like box like the one shown in this tutorial what are the main changes I need to make in order to make it work with ASP.NET Core 3.1
https://www.c-sharpcorner.com/blogs/how-to-create-a-comment-box-session-as-like-facebook-comment-in-asp-net

To create a Facebook-like comment box in ASP.NET Coreļ¼Œ I do a demo to make it, referring to official documentation to configure database:https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/adding-model?view=aspnetcore-5.0&tabs=visual-studio
1.To Create the comment box, we need to create User, Reply, Comment models to add some tables ,and add some ViewModels.
User.cs:
public class User
{
[Key]
public int Id { get; set; }
[Required]
public string UserName { get; set; }
[Required]
public string Password { get; set; }
[Required]
public string Email { get; set; }
public string ImageUrl { get; set; }
public DateTime? CreateOn { get; set; }
}
Reply.cs:
public class Reply
{
[Key]
public int Id { get; set; }
[Required]
public string Text { get; set; }
public DateTime? CreateOn { get; set; }
public int UserId { get; set; }
[ForeignKey("UserId")]
public virtual User User { get; set; }
public int CommentId { get; set; }
[ForeignKey("CommentId")]
public virtual Comment Comment{get;set;}
}
Comment.cs:
public class Comment
{
[Key]
public int Id { get; set; }
[Required]
public string Text { get; set; }
public DateTime? CreateOn { get; set; }
public int UserId { get; set; }
[ForeignKey("UserId")]
public virtual User User { get; set; }
public ICollection<Reply> Replies { get; set; }
public ICollection<User> Users { get; set; }
}
LoginVM.cs:
public class LoginVM
{
[Required]
[Key]
public string UserName { get; set; }
[Required]
public string Password { get; set; }
}
RegisterVM.cs:
public class RegisterVM
{
[Required]
public string UserName { get; set; }
[Required]
public string Password { get; set; }
[Compare("Password")]
public string ConfirmPassword { get; set; }
[Required]
public string Email { get; set; }
}
ReplyVM.cs:
public class ReplyVM
{
public string Reply { get; set; }
public int CID { get; set; }
}
Installs the EF Core package
From the Tools menu, select NuGet Package Manager > Manage NuGet Packages for solution.
[Note]My core3.1 installed 3.1.21 version
Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.Tools
Microsoft.EntityFrameworkCore.SqlServer
Microsoft.EntityFrameworkCore.SqlServer.Design
Microsoft.EntityFrameworkCore.Proxies
Microsoft.Extensions.Configuration.JSON
creates a database context class: Models/ApplicationDbContext.cs
public class ApplicationDbContext: DbContext
{
public ApplicationDbContext(DbContextOptions options) :base(options)
{
}
public DbSet<User> Users { get; set; }
public DbSet<Comment> Comments { get; set; }
public DbSet<Reply> Replies { get; set; }
public DbSet<commentbox.ViewModels.LoginVM> LoginVM { get; set; }
}
4.Add codes in Startup.ConfigureServices:
public void ConfigureServices(IServiceCollection services)
{
services.AddSession();
services.AddControllersWithViews();
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("ApplicationDbContext")));
}
5.Add app.UseSession(); in Startup.Configure
6.Add a connection string to the appsettings.json file:
"ConnectionStrings": {
"ApplicationDbContext": "Server=(localdb)\\mssqllocaldb;Database=ApplicationDbContext-1;Trusted_Connection=True;MultipleActiveResultSets=true"}
7.In the Package Manager Console (PMC), enter the following commands separately:
Add-Migration InitialCreate
Update-Database
8.Add HomeController to set userId=0 when people first Login without register, add AccountController to manage user login or not, add ChatRoomController to manage user post comments or reply.
HomeController.cs:
public class HomeController : Controller
{ ....
public IActionResult Index()
{
ISession session = HttpContext.Session;
session.SetInt32("UserId", 0);
return View();
}
...
}
AccountController.cs:
public class AccountController : Controller
{
private readonly ApplicationDbContext db;
public AccountController(ApplicationDbContext context)
{
db = context;
}
//GET:Account/Register
[HttpGet]
public IActionResult Register()
{
return View();
}
//GET:Account/Register
[HttpPost]
public IActionResult Register(RegisterVM obj)
{
bool UserExistis=db.Users.Any(x=>x.UserName==obj.UserName);
if(UserExistis)
{
ViewBag.UserNameMessage = "This UserName is already in use, try another";
return View();
}
bool EmailExistis = db.Users.Any(y => y.Email == obj.Email);
if (EmailExistis)
{
ViewBag.EmailMessage = "This Email is already in use, try another";
return View();
}
//if username and email is unique, then we save or register the user
User u = new User();
u.UserName = obj.UserName;
u.Password = obj.Password;
u.Email = obj.Email;
u.ImageUrl = "";
u.CreateOn = DateTime.Now;
db.Users.Add(u);
db.SaveChanges();
return RedirectToAction("Index","ChatRoom");
}
//GET:Account/Login
[HttpGet]
public IActionResult Login()
{
return View();
}
//GET:Account/Login
[HttpPost]
public IActionResult Login(LoginVM obj)
{
bool existis = db.Users.Any(u => u.UserName == obj.UserName&&u.Password==obj.Password);
if(existis)
{
ISession session = HttpContext.Session;
session.SetInt32("UserId", db.Users.Single(x => x.UserName == obj.UserName).Id);
return RedirectToAction("Index","ChatRoom");
}
//if invalid credentials
ViewBag.Message = "Invalid Credentials!";
return View();
}
}
ChatRoomController.cs:
public class ChatRoomController: Controller
{
private readonly ApplicationDbContext db;
public ChatRoomController(ApplicationDbContext context)
{
db = context;
}
public IActionResult Index()
{
var comments = db.Comments.Include(x => x.Replies).ThenInclude(x=>x.User).OrderByDescending(x => x.CreateOn)
.ToList();
return View(comments);
}
//Post:ChatRoom/PostReply
[HttpPost]
public ActionResult PostReply(ReplyVM obj)
{
ISession session = HttpContext.Session;
int userId =(int)session.GetInt32("UserId");
if (userId==0)
{
return RedirectToAction("Login", "Account");
}
Reply r = new Reply();
r.Text = obj.Reply;
r.CommentId = obj.CID;
r.UserId =userId;
r.CreateOn = DateTime.Now;
db.Replies.Add(r);
db.SaveChanges();
return RedirectToAction("Index");
}
//Post:ChatRoom/PostComment
[HttpPost]
public ActionResult PostComment(string CommentText)
{
ISession session = HttpContext.Session;
int userId = (int)session.GetInt32("UserId");
if (userId == 0)
{
return RedirectToAction("Login", "Account");
}
Comment c = new Comment();
c.Text = CommentText;
c.CreateOn = DateTime.Now;
c.UserId = userId;
db.Comments.Add(c);
db.SaveChanges();
return RedirectToAction("Index");
}
}
9.Add views: Login.cshtml(for Login action in AccountController), Register.cshtml(for Register action in AccountController), index.cshtml(for Index action in ChatRoomController).
Login.cshtml:
#model commentbox.ViewModels.LoginVM
#{
ViewData["Title"] = "Login";
}
<h1>Login</h1>
#Html.AntiForgeryToken()
<div class="row">
<div class="col-md-4">
<form asp-action="Login">
<h4 class="text-danger">#ViewBag.Message</h4>
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="UserName" class="control-label"></label>
<input asp-for="UserName" class="form-control" />
<span asp-validation-for="UserName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Password" class="control-label"></label>
<input asp-for="Password" class="form-control" />
<span asp-validation-for="Password" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-success" />
</div>
</form>
</div>
</div>
Register.cshtml:
#model commentbox.ViewModels.RegisterVM
#{
ViewData["Title"] = "Register";
}
<h1 class="text-success">Register User</h1>
<div class="row">
<div class="col-md-4">
<form asp-action="Register">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="UserName" class="control-label"></label>
<input asp-for="UserName" class="form-control" />
<span asp-validation-for="UserName" class="text-danger"></span>
<p class="text-danger">#ViewBag.UserNameMessage </p>
</div>
<div class="form-group">
<label asp-for="Password" class="control-label"></label>
<input asp-for="Password" class="form-control" />
<span asp-validation-for="Password" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ConfirmPassword" class="control-label"></label>
<input asp-for="ConfirmPassword" class="form-control" />
<span asp-validation-for="ConfirmPassword" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Email" class="control-label"></label>
<input asp-for="Email" class="form-control" />
<span asp-validation-for="Email" class="text-danger"></span>
<p class="text-danger">#ViewBag.EmailMessage </p>
</div>
<div class="form-group">
<input type="submit" value="Register" class="btn btn-primary" style="border-radius:20px"/>
</div>
</form>
</div>
</div>
Index.cshtml:
#model IEnumerable<commentbox.Models.Comment>
#{
ViewData["Title"] = "Index";
}
<h1>Index</h1>
<h2 class="text-success text-center"> someone's post or some other things</h2>
#using (Html.BeginForm("PostComment", "ChatRoom", FormMethod.Post))
{
<input type="text" name="CommentText" placeholder="Type new comment..."
style="width:700px; height:60px; font-size:20px; margin-top:10px" />
<br />
<input type="submit" value="Post Comment" class="btn btn-success "
style="margin-top: 10px;margin-bottom: 10px " />
}
<table class="table text-center">
<tbody>
#foreach (var comment in Model)
{
<tr style="border:1px solid black;">
<td>
<span style="margin-right:15px;font-size:16px;color:green">
#Html.DisplayFor(modelItem => comment.User.UserName)
</span>
<span style="font-size:20px">
#Html.DisplayFor(modelItem => comment.Text)
</span>
<span style="margin-left:10px">
#Html.DisplayFor(modelItem => comment.CreateOn)
</span>
#foreach (var reply in comment.Replies)
{
<br />
<span style="margin-right:15px;font-size:16px;color:blue">
#Html.DisplayFor(modelItem => reply.User.UserName)
</span>
<span style="font-size:19px">
#reply.Text
</span>
<span style="margin-left:10px">
#reply.CreateOn
</span>
}
<br />
#using (Html.BeginForm("PostReply", "ChatRoom", FormMethod.Post))
{<input type="text" name="Reply" placeholder="Type reply..."
style="width:100%; height:60px; font-size:20px; margin-top:10px" />
<br />
<input type="hidden" name="CID" value="#comment.Id" />
<input type="submit" value="Post Reply" class="btn btn-success" style="margin-top :10px" />
}
</td>
</tr>
}
</tbody>
</table>
10.Add link in _Layout.cshtml.
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Account" asp-action="Register">Register</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Account" asp-action="Login">Login</a>
</li>

Related

how can i show the data that the user entered in the file input when he want to edit it

for your information the file is saved as a binary data
here is is the model:
public class Movie
{
[Key]
public int MovieId { get; set; }
public string MovieName { get; set; }
public string MovieDescription { get; set; }
public byte[] MovieImage { get; set; }
public string MovieTrailer { get; set; }
//FK
public int AdminId { get; set; }
//Navigation
public Admin Admin { get; set; }
public ICollection<Event> Events { get; set; }
public AddingCategory AddingCategory { get; set; }
public ViewingMovie ViewingMovie { get; set; }
}
}
And here is the controller :
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var movie = await _context.tblMovies.FindAsync(id);
if (movie == null)
{
return NotFound();
}
ViewData["AdminId"] = new SelectList(_context.Set<Admin>(), "AdminId", "Email", selectedValue: movie.AdminId);
return View(movie);
}
// POST: Movies/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("MovieId,MovieName,MovieDescription,MovieImage,MovieTrailer,AdminId")] Movie movie, IFormFile MovieImage)
{
if (id != movie.MovieId)
{
return NotFound();
}
if (MovieImage != null)
{
//This code is used to copy image to DataBase
using (var myStream = new MemoryStream())
{
await MovieImage.CopyToAsync(myStream);
movie.MovieImage = myStream.ToArray();
}
}
if (ModelState.IsValid)
{
try
{
_context.Update(movie);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!MovieExists(movie.MovieId))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction(nameof(Index));
}
ViewData["AdminId"] = new SelectList(_context.Set<Admin>(), "AdminId", "Email", movie.AdminId);
return View(movie);
}
and the last here is the edit view:
<div class="row">
<div class="col-md-4">
<form asp-action="Edit" method="post" enctype="multipart/form-data">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="MovieId" />
<div class="form-group">
<label asp-for="MovieName" class="control-label"></label>
<input asp-for="MovieName" class="form-control" />
<span asp-validation-for="MovieName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="MovieDescription" class="control-label"></label>
<input asp-for="MovieDescription" class="form-control" />
<span asp-validation-for="MovieDescription" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="MovieImage" class="control-label"></label>
<input asp-for="MovieImage" class="form-control" type="file" />
<span asp-validation-for="MovieImage" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="MovieTrailer" class="control-label"></label>
<input asp-for="MovieTrailer" class="form-control" />
<span asp-validation-for="MovieTrailer" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="AdminId" class="control-label"></label>
<select asp-for="AdminId" class="form-control" asp-items="ViewBag.AdminId"></select>
<span asp-validation-for="AdminId" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
</div>
all i want is to show what the user entered in the file input and if he want to edit it or keep as it is.
i have been struggling with this problem in days PLEASE somebody help me out

How do I upload pdf into a folder and store the path into a database, and be able to view the uploaded file? Thank you

Here is my controller code
namespace MyClassWorkApplication.Areas.Admin.Controllers
{
[Area("Admin")]
[Authorize(Roles = "Admin")]
public class ContentController : Controller
{
private readonly ApplicationDbContext _context;
private IWebHostEnvironment _env;
public ContentController(ApplicationDbContext context, IWebHostEnvironment env)
{
_context = context;
_env = env;
}
// GET: Admin/Content/Create
public IActionResult Create(int categoryItemId, int categoryId)
{
Content content = new Content
{
CategoryId = categoryId,
CatItemId = categoryItemId
};
return View(content);
}
// POST: Admin/Content/Create
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,Title,HTMLContent,VideoLink,CatItemId,CategoryId,PublicationPdfUrl")] Content content)
{
Profile profile = new Profile();
profile.Title = content.Title;
//loading remaining properties of the model from ViewModel
//uploading file....
string uniqueFileName = null;
if (content.PublicationPdfUrl != null)
{
string folder = "Publications/pdf/";
string serverFolder = Path.Combine(_env.WebRootPath, folder);
uniqueFileName = Guid.NewGuid().ToString() + "_" + content.PublicationPdfUrl.FileName;
string filePath = Path.Combine(serverFolder, uniqueFileName);
content.PublicationPdfUrl.CopyTo(new FileStream(filePath, FileMode.Create));
profile.PublicationPdfUrl = content.PublicationPdfUrl.FileName;
}
if (ModelState.IsValid)
{
content.CategoryItem = await _context.CategoryItem.FindAsync(content.CatItemId);
_context.Add(content);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index), "CategoryItem", new { categoryId = content.CategoryId });
}
return View(content);
}
// GET: Admin/Content/Edit/5
public async Task<IActionResult> Edit(int categoryItemId, int categoryId)
{
if (categoryItemId == 0)
{
return NotFound();
}
var content = await _context.Content.SingleOrDefaultAsync(item => item.CategoryItem.Id == categoryItemId);
content.CategoryId = categoryId;
if (content == null)
{
return NotFound();
}
return View(content);
}
// POST: Admin/Content/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,HTMLContent,VideoLink,CategoryId,PublicationPdfUrl")] Content content)
{
if (id != content.Id)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
_context.Update(content);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!ContentExists(content.Id))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction(nameof(Index), "CategoryItem", new { categoryId = content.CategoryId });
}
return View(content);
}
private bool ContentExists(int id)
{
return _context.Content.Any(e => e.Id == id);
}
}
}
My Second Controller
namespace MyClassWorkApplication.Controllers
{
public class ContentController : Controller
{
private readonly ApplicationDbContext _context;
public ContentController(ApplicationDbContext context)
{
_context = context;
}
public async Task<IActionResult> Index(int categoryItemId)
{
Content content = await (from item in _context.Content
where item.CategoryItem.Id == categoryItemId
select new Content
{
Title = item.Title,
VideoLink = item.VideoLink,
HTMLContent = item.HTMLContent,
PublicationPdfUrl = item.PublicationPdfUrl
}).FirstOrDefaultAsync();
return View(content);
}
}
}
This is my Model class (Content). It was reporting error with the IFormFile until I added the [NotMapped] attributes to it before the error disappears. However, It does not add the pdf Url into that database as I wanted.
public class Content
{
public int Id { get; set; }
[Required]
[StringLength(200, MinimumLength = 2)]
public string Title { get; set; }
[Display(Name = "HTML Content")]
public string HTMLContent { get; set; }
[Display(Name = "Video Link")]
public string VideoLink { get; set; }
public CategoryItem CategoryItem { get; set; }
[NotMapped]
public int CatItemId { get; set; }
//Note: This property cannot be
//named CategoryItemId because this would
//interfere with future migrations
//It has been named like this
//so as not to conflict with EF Core naming conventions
[NotMapped]
public int CategoryId { get; set; }
[NotMapped]
public IFormFile PublicationPdfUrl { get; set; }
}
public class Profile
{
[Key]
public int Id { get; set; }
public string Title { get; set; }
public string HTMLContent { get; set; }
public string VideoLink { get; set; }
public CategoryItem CategoryItem { get; set; }
public int CatItemId { get; set; }
public int CategoryId { get; set; }
[Display(Name = "Upload your publication in pdf format")]
public string PublicationPdfUrl { get; set; }
}
}
This is my Create View
#{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<h4>Content</h4>
<hr />
<div class="row">
<div class="col-md-10">
<form method="post" enctype="multipart/form-data" asp-action="Create">
<input type="hidden" asp-for="CategoryId">
<input type="hidden" asp-for="CatItemId">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Title" class="control-label"></label>
<input asp-for="Title" class="form-control" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="HTMLContent" class="control-label"></label>
<textarea asp-for="HTMLContent" row="10" class="form-control"></textarea>
<span asp-validation-for="HTMLContent" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="VideoLink" class="control-label"></label>
<input asp-for="VideoLink" class="form-control" />
<span asp-validation-for="VideoLink" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="PublicationPdfUrl" class="control-label"></label>
<div class="custom-file">
<input asp-for="PublicationPdfUrl" class="custom-file-input" id="customFile">
<label class="custom-file-label" for="customFile">Choose file...</label>
</div>
<span asp-validation-for="PublicationPdfUrl" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary float-right" />
<a asp-controller="CategoryItem" asp-action="Index" asp-route-categoryId="#Model.CategoryId" class="btn btn-outline-primary">Back to List</a>
</div>
</form>
</div>
</div>
This is my Edit View
#{
ViewData["Title"] = "Edit";
}
<h4>Edit</h4>
<h4>Content</h4>
<hr />
<div class="row">
<div class="col-md-10">
<form method="post" enctype="multipart/form-data" asp-action="Edit">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="Id" />
<input type="hidden" asp-for="CategoryId" />
<div class="form-group">
<label asp-for="Title" class="control-label"></label>
<input asp-for="Title" class="form-control" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="HTMLContent" class="control-label"></label>
<textarea asp-for="HTMLContent" row="10" class="form-control"></textarea>
<span asp-validation-for="HTMLContent" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="VideoLink" class="control-label"></label>
<input asp-for="VideoLink" class="form-control" />
<span asp-validation-for="VideoLink" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="PublicationPdfUrl" class="control-label"></label>
<div class="custom-file">
<input asp-for="PublicationPdfUrl" class="custom-file-input" id="customFile">
<label class="custom-file-label" for="customFile">Choose file...</label>
</div>
<span asp-validation-for="PublicationPdfUrl" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary float-right" />
<a asp-controller="CategoryItem" asp-action="Index" asp-route-categoryId="#Model.CategoryId" class="btn btn-outline-primary">Back to List</a>
</div>
</form>
</div>
</div>

How do I store user input into database using ASP.NET Core MVC?

I am struggling to find a solution on how to add user input like first name, last name, zipcode.... to the database. The email is already stored in database during signUp.
I tried looking at some resource but they seem complicated.
HomeController
public async Task<IActionResult> ProfileView(ApplicationUser users)
{
return View();
}
Application user model:
public class ApplicationUser: IdentityUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public int ZipCode { get; set; }
}
Profile view:
<form>
<div class="form-row">
<div class="form-row col-md-6">
<div class="col">
<label for="firstName">First Name:</label>
<input type="text" class="form-control" placeholder="First name">
</div>
<div class="col col-md-6">
<label for="lastName">Last Name:</label>
<input type="text" class="form-control" placeholder="Last name">
</div>
</div>
<div class="form-group col-md-6">
<label for="inputEmail4">Email</label>
<input type="email" class="form-control" id="inputEmail4" placeholder="Email">
</div>
</div>
Database context:
public class DataBaseContext: IdentityDbContext<ApplicationUser>
{
public DataBaseContext(DbContextOptions<DataBaseContext> options): base(options)
{
}
public new DbSet<SignUp> Users { get; set; }
public DbSet<Products> Products { get; set; }
}
When the user fills out the information in the view it should store it in an existing database.
Here is a working example on modifying user's profile after logining :
Profile View :
#model MVC2_2Project.Models.ApplicationUser
<div class="row">
<div class="col-md-6">
<form id="profile-form" method="post">
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<label asp-for="FirstName"></label>
<input asp-for="FirstName" class="form-control" placeholder="First name"/>
<span asp-validation-for="LastName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="LastName"></label>
<input asp-for="LastName" class="form-control" placeholder="Last name"/>
<span asp-validation-for="LastName" class="text-danger"></span>
</div>
<button id="update-profile-button" type="submit" class="btn btn-primary">Save</button>
</form>
</div>
</div>
#section Scripts {
<partial name="_ValidationScriptsPartial" />
}
HomeController:
public class HomeController : Controller
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly ApplicationDbContext _context;
public HomeController(
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
ApplicationDbContext context)
{
_userManager = userManager;
_signInManager = signInManager;
_context = context;
}
public async Task<IActionResult> ProfileView()
{
var user = await _userManager.GetUserAsync(User);
if (user == null)
{
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
}
return View(user);
}
[HttpPost]
public async Task<IActionResult> ProfileView(ApplicationUser users)
{
if (!ModelState.IsValid)
{
return View();
}
var user = await _userManager.GetUserAsync(User);
if (user == null)
{
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
}
user.FirstName = users.FirstName;
user.LastName = users.LastName;
_context.Users.Update(user);
await _context.SaveChangesAsync();
await _signInManager.RefreshSignInAsync(user);
return RedirectToAction();
}
}

Asp validation decimal not binded correctly

I have a problem with the asp-validation.
I have a decimal field which I want to be between 0.00 and 1.00.
Here is my model :
public class Intent
{
public Guid Id { get; set; }
public Language Language_ { get; set; }
public Boolean Active { get; set; }
[Range(0.00, 1.00)]
public decimal Tolerance { get; set; }
public LuisApp LuisAppFr_ { get; set; }
public LuisApp LuisAppEn_ { get; set; }
public LuisApp LuisAppNl_ { get; set; }
public string UrlImage { get; set; }
}
Here is the signature of my post method:
public async Task<IActionResult> Create([Bind("Id,Active,Tolerance,UrlImage,Language_,Language_.TextEn,Language_.TextFr,Language_.TextNl")] Intent intent)
Here is a part of my Create View:
<form asp-action="Create">
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<div class="checkbox">
<label>
<input asp-for="Active" /> #Html.DisplayNameFor(model => model.Active)
</label>
</div>
</div>
<div class="form-group">
<label asp-for="Tolerance" class="control-label"></label>
<input asp-for="#Model.Tolerance" class="form-control"/>
<span asp-validation-for="Tolerance" class="text-danger"></span>
</div>
...
<div class="form-group">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</form>
Here is an image showing the value of my Tolerance field when it gets to the controller
And here is an image of my network request
Error Message I get
The binding seems to be good on the frontend but isn't in the backend.
Has anyone an idea of what my error could be ?
Thanks forward for your answer.
Sorry if it's a repost.
I solved my problem by adding this in my startup.cs :
app.UseRequestLocalization(new RequestLocalizationOptions
{
DefaultRequestCulture = new RequestCulture("en-US")
});

How do I get my view to show my database table

i'm new to ASP.net. I am trying to figure out how to get my Edit/Display pages working properly for a multiselect listbox.
My create works fine, and saves to my database, but I cannot figure out how to return to the edit page, and still see the values selected.
Hopes this makes sense.
Here is the code that I have for the create method. The record saves fine in both tables, but I am having trouble getting the values from my Options table.
I want to try to make the Edit view look like the Create View
Controller
[HttpPost]
public IActionResult Create(MusicViewModel model)
{
if(ModelState.IsValid)
{
var album = new Music();
album.Album = model.Album;
album.Artist = model.Artist;
album.Label = model.Label;
album.Review = model.Review;
album.ReleaseDate = model.ReleaseDate;
foreach(Types type in model.Options)
{var opt = new Options();
opt.Music = album;
opt.Types = type;
_musicData.AddOptions(opt);
}
_musicData.Add(album);
_musicData.Commit();
return RedirectToAction("Details", new { id = album.MusicID });
}
return View();
}
Music.cs
public enum Types
{
Spotify,
Groove,
CD,
Vinyl,
Pandora
}
public class Music
{
public int MusicID { get; set; }
[Required]
[MaxLength(50),MinLength(5)]
public string Artist { get; set; }
[Required, MinLength(5)]
public string Album { get; set; }
public int Rating { get; set; }
public Label Label { get; set; }
[DataType(DataType.Date)]
[Display(Name ="Release Date")]
public DateTime ReleaseDate { get; set; }
public string Review { get; set; }
public List<Options> Options { get; set; }
}
public class Options
{
public int OptionsID { get; set; }
public Types Types { get; set; }
public int MusicID { get; set; }
public Music Music { get; set; }
}
public class MusicDbContext:DbContext
{
public DbSet<Music> Albums { get; set; }
public DbSet<Options> Options { get; set; }
}
View
#model Music
....
<form asp-action="Create" method="post">
<div class="row">
<div class="col-md-3 col-md-offset-2">
<fieldset class="form-group">
<label asp-for="Artist"></label>
<input class="form-control" asp-for="Artist" />
<span asp-validation-for="Artist" class="alert"></span>
</fieldset>
</div>
<div class="col-md-3">
<fieldset class="form-group">
<label asp-for="Album"></label>
<input class="form-control" asp-for="Album" />
<span asp-validation-for="Album" class="alert"></span>
</fieldset>
</div>
<div class="col-md-3">
<label asp-for="Label"></label>
#Html.DropDownList("Label", Html.GetEnumSelectList(typeof(Label)), "-------", new { #class = "form-control" })
</div>
</div>
<div class="row">
<div class="col-md-3 col-md-offset-2">
<fieldset class="form-group">
<label asp-for="Options"></label>
<select multiple class="form-control" asp-for="Options"
asp-items="#Html.GetEnumSelectList(typeof(Types))"></select>
</fieldset>
</div>
<div class="col-md-3">
<fieldset class="form-group">
<label asp-for="ReleaseDate"></label>
<input type="text" asp-for="ReleaseDate" class="DateBox form-control" />
<span asp-validation-for="ReleaseDate" class="alert"></span>
</fieldset>
</div>
</div>
<div class="col-md-offset-3"><input class="btn btn-info" type="submit" value="Submit" /></div>
</form>
I figured it out, probably not the most efficient way, but at least the code works
[HttpPost]
public IActionResult Edit(int id,MusicViewModel model)
{
var album = _musicData.GetM(id);
if (album != null && ModelState.IsValid)
{
album.Album = model.Album;
album.Artist = model.Artist;
album.Label = model.Label;
album.Review = model.Review;
album.ReleaseDate = model.ReleaseDate;
_musicData.RemoveOptions(id);
foreach (Types type in model.Options)
{
var opt = new Options();
opt.MusicID = id;
opt.Types = type;
_musicData.AddOptions(opt);
}
_musicData.Commit();
return RedirectToAction("Details",id);
}
return View(album);
}

Resources