I have a login page and registration page all are working fine. I have a users table i created in sql server database with the column Username, FullName, School, Course. I want to display all the user detail in a sidemenu view page in MVC. But when i login i get the error message"object-reference-not-set-to-an-instance-of-an-object". I also have a controller action. Please someone help.
This is for MVC
#model ORMOnlineExamApp.Models.Candidate
<div class="row">
<div class="col-md-3">
<div class="container-fluid">
<div class="thumbnail" style="width:200px">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">Candidate's Details</h3>
</div>
</div>
<p>
<h4 style="font-weight:bold">Application No:</h4>
</p>
<p>
#Model.Username
</p>
<hr />
<p>
<h4 style="font-weight:bold">Name:</h4>
</p>
<p>
#Model.FullName
</p>
<hr />
<p>
<h4 style="font-weight:bold">School:</h4>
</p>
<p>
#Model.School
</p>
<hr />
<p>
<h4 style="font-weight:bold">Course:</h4>
</p>
<p>
#Model.Course
</p>
</div>
//Controller
public ActionResult Contact(string id)
{
using (ORMOnlineExamEntitiesApp db = new ORMOnlineExamEntitiesApp())
{
var user = db.Candidates.SingleOrDefault(u => u.Username == id);
return View(user);
}
}
Please find the login page below:
//Login POST
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login(CandidateLogin login, string ReturnUrl = "")
{
string message = "";
using (ORMOnlineExamEntitiesApp dc = new ORMOnlineExamEntitiesApp())
{
var v = dc.Candidates.Where(a => a.Username == login.Username).FirstOrDefault();
if (v != null)
{
if (string.Compare(Crypto.Hash(login.Password), v.Password) == 0)
{
int timeout = login.RememberMe ? 525600 : 20; // 525600 min = 1 year
var ticket = new FormsAuthenticationTicket(login.Username, login.RememberMe, timeout);
string encrypted = FormsAuthentication.Encrypt(ticket);
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encrypted);
cookie.Expires = DateTime.Now.AddMinutes(timeout);
cookie.HttpOnly = true;
Response.Cookies.Add(cookie);
if (Url.IsLocalUrl(ReturnUrl))
{
return Redirect(ReturnUrl);
}
else
{
FormsAuthentication.SetAuthCookie(login.Username, true);
Session["UserId"] = login.Username.ToString();
return RedirectToAction("Contact", "Home");
}
}
else
{
message = "Invalid credential provided";
}
}
else
{
message = "Invalid credential provided";
}
}
ViewBag.Message = message;
return View();
}
Related
In my college ecommerce gallery project I want do when the image is uploaded the size of the image automatically compressed like if the image size is 2mb after upload its gonna 600 kb or 400kb so how to do that..my code is below..
ProductController.cs
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Upsert(ProductVM productVM)
{
if (ModelState.IsValid)
{
string webRootPath = _hostEnvironment.WebRootPath; //getting image Path
var files = HttpContext.Request.Form.Files; //Retrive all the files that are uploaded
if(files.Count > 0) //that means file was uploaded
{
string fileName = Guid.NewGuid().ToString();
var uploads = Path.Combine(webRootPath, #"images\products");
var extenstion = Path.GetExtension(files[0].FileName);
if (productVM.Product.ImageUrl != null)
{
//this is an edit and we need to remove old image
var imagePath = Path.Combine(webRootPath,
productVM.Product.ImageUrl.TrimStart('\\'));
if (System.IO.File.Exists(imagePath))
{
System.IO.File.Delete(imagePath);
}
}
using (var filesStreams = new FileStream(Path.Combine(uploads, fileName +
extenstion), FileMode.Create))
{
files[0].CopyTo(filesStreams);
}
productVM.Product.ImageUrl = #"\images\products\" + fileName + extenstion;
}
else
{
//update when they do not change the image
if (productVM.Product.Id != 0)
{
Product objFromDb = await _unitOfWork.Product.GetAsync(productVM.Product.Id);
productVM.Product.ImageUrl = objFromDb.ImageUrl;
}
}
if (productVM.Product.Id == 0)
{
await _unitOfWork.Product.AddAsync(productVM.Product);
}
else
{
_unitOfWork.Product.Update(productVM.Product);
}
_unitOfWork.Save();
return RedirectToAction(nameof(Index));
}
..
..
..
return View(productVM);
}
Upsert.cshtml
<section>
<div class="container-lg pt-4">
<form method="post" enctype="multipart/form-data">
<div class="row p-3 border">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="col-8 pt-4">
<div class="form-group row">
<div class="col-4">
<label asp-for="Product.Title"></label>
</div>
<div class="col-8">
<input asp-for="Product.Title" class="form-control" />
<span asp-validation-for="Product.Title" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<div class="col-4">
Image
</div>
<div class="col-8">
<input type="file" name="files" id="uploadBox" multiple class="form-control"
/>
</div>
</div>
<div class="form-group row">
<div class="col-8 offset-4">
#if (Model.Product.Id != 0)
{
<partial name="_EditAndBackToListButton" model="Model.Product.Id" />
}
else
{
<div class="row">
<div class="col">
<button type="submit" class="btn btn-primary form-control">Create</button>
</div>
<div class="col">
<button asp-action="Index" class="btn btn-success form-control">Back To List</button>
</div>
</div>
}
</div>
</div>
</div>
</div>
</form>
</div>
Is there any nuget package to compress the image size
You can check this demo, after testing, it can make 65KB image to 15KB image:
You just need to send source image location with the compress level 0~100, and where to send the
compressed image.
public IActionResult Index()
{
string filename = #"C:\*****\Saved Pictures\dog.jpg"; //source image location
Bitmap img = new Bitmap(filename); //image to bitmap
var name = "result.jpg"; //your output image name
Compress(img, #"C:\****\wwwroot\images\"+name, 0); //level 0~100, 0 is the worst resolution
return View();
}
public static void Compress(Bitmap srcBitMap, string destFile, long level)
{
Stream s = new FileStream(destFile, FileMode.Create); //create FileStream,this will finally be used to create the new image
Compress(srcBitMap, s, level); //main progress to compress image
s.Close();
}
private static ImageCodecInfo GetEncoderInfo(String mimeType)
{
int j;
ImageCodecInfo[] encoders;
encoders = ImageCodecInfo.GetImageEncoders();
for (j = 0; j < encoders.Length; ++j)
{
if (encoders[j].MimeType == mimeType)
return encoders[j];
}
return null;
}
private static void Compress(Bitmap srcBitmap, Stream destStream, long level)
{
ImageCodecInfo myImageCodecInfo;
Encoder myEncoder;
EncoderParameter myEncoderParameter;
EncoderParameters myEncoderParameters;
myImageCodecInfo = GetEncoderInfo("image/jpeg");
myEncoder = Encoder.Quality;
myEncoderParameters = new EncoderParameters(1);
myEncoderParameter = new EncoderParameter(myEncoder, level);
myEncoderParameters.Param[0] = myEncoderParameter;
srcBitmap.Save(destStream, myImageCodecInfo, myEncoderParameters);
}
Result(after vs before):
yes, you could use this: https://github.com/omuleanu/imager
so it would be something like this:
Image img = Imager.Resize(sourceImage, newWidth, maxHeight);
this is if you want to resize it on the server, after you uploaded it, but you could also resize it before the upload, as shown in this demo website:
https://prodinner.aspnetawesome.com/Meal
try to click edit on any item, after "change image"
for this cropper.js and dropzone.js are used.
https://fengyuanchen.github.io/cropperjs/
https://www.dropzonejs.com/
I want my user to be able to change his username so i made this:
<form asp-action="UpdateUserProfile" asp-controller="Account" method="post">
<div class="account-details-item">
<h2 class="center-text text-left account-details-item-title">UserName:</h2>
<input name="username" id="username-text" readonly="readonly" class="center-text account-details-item-value" asp-for="User.UserName" value=#Model.User.UserName>
<a id="btn-username" class="account-details-item-btn" >Edit</a>
</div>
<div class="account-details-item">
<h2 class="center-text text-left account-details-item-title">Email:</h2>
<input name="email" readonly="readonly" id="email-text" class="center-text account-details-item-value email" asp-for="User.Email" value=#Model.User.Email />
<a id="btn-email" class="account-details-item-btn" >Edit</a>
</div>
<div class="account-details-item">
<h2 class="center-text text-left account-details-item-title">Phone number:</h2>
<input name="phonenumber" readonly="readonly" id="phone-text" class="center-text account-details-item-value" asp-for="User.PhoneNumber" value=#Model.User.PhoneNumber>
<a id="btn-phone" class="account-details-item-btn" >Edit</a>
</div>
<div class="btns-container">
<div class="btn-item"><a asp-action="Index" asp-controller="Cart" asp-route-id=#Model.User.CartId>Go To Cart</a></div>
<div id="save-btn" class="btn-item"><button type="submit">Save Changes</button></div>
</div>
</form>
And in AccountController:
[HttpPost]
public IActionResult UpdateUserProfile()
{
var username = Request.Form["username"];
var phonenumber = Request.Form["phonenumber"];
var email = Request.Form["email"];
var user = _userService.GetUser(User);
if(`enter code here`IsUsernameDiffrent(username))
{
_userService.UpdateUsername(User, username);
_userManager.UpdateAsync(user.Result);
}
else if(IsEmailDiffrent(email))
{
_userService.UpdateEmail(User, email);
_userManager.UpdateAsync(user.Result);
}
else if (IsPhoneNumberDiffrent(phonenumber))
{
_userService.UpdatePhoneNumber(User, phonenumber);
_userManager.UpdateAsync(user.Result);
}
return RedirectToAction("Index");
}
And in Service Class:
public async void UpdateUsername(ClaimsPrincipal user, string newUsername)
{
var currentUser = await GetUser(user);
currentUser.UserName = newUsername;
_dbContext.SaveChanges();
}
The issue is that if user change his username he still have to login with the old one,
changes are made in database but whenever i try to login with new username it says "Invalid login attempt"
I have an Update User Action in my project and it does work in mine, and its little different from yours, but you can try to change it like that:
[HttpPost]
public async Task<IActionResult> UpdateUserProfile()
{
var user = _userService.GetUser(User);
if (user == null)
{
return StatusCode(404);
}
var username = Request.Form["username"];
if(IsUsernameDifferent(username))
{
user.UserName = username;
var result = await _userManager.UpdateAsync(user);
if (result.Succeeded)
{
return RedirectToAction("Action", "Controller");
}
return View();
}
return View();
}
I feel that more code must be seen to analyze the issue. But, make sure you are using transaction scope in your services when you are making changes to the data in the database like update or delete.
Using this technique will ensure that the code is consistent. Changes to the database will not happen unless everything inside the scope is successful. For example, if you are updating and then deleting, what if while deleting an error occurs. Then your data will be updated in the database but not deleted. This is to make sure that both happens successfully or nothing happens at all.
Refer this link.
https://learn.microsoft.com/en-us/ef/core/saving/transactions
I have a list of users and if you click on a user there has to be create a new message.
But every time I click on a user id is 0
I have this:
action method:
public ActionResult StuurBericht(int id = 0, string onderwerp = "")
{
using (var rep = new GebruikerRepository(Context.Klant.Id))
{
var model = PersoneelsDossierService.GetPersoneelsDossierMutatieModel(Context.Klant.Id, GetMutatieRol(), int.Parse(Context.Gebruiker.ExternId), Gebruiker.DienstverbandId, Gebruiker.DienstverbandId, "Functionarissen");
model.Functionarissen = PersoneelsDossierService.GetFunctionarissen(Context.Klant.Id, Gebruiker.DienstverbandId);
BeveiligingService.ControleerGebruikerVanKlant(Context.Klant.Id, Context.Gebruiker.Id);
if (id > 0)
{
ModelState.Clear();
var modelMessage = new Message();
modelMessage.GebruikerId = id;
modelMessage.Onderwerp = string.Format("RE: {0}", onderwerp);
return View(model);
}
}
return View();
}
and this is the view:
#model List<SDB.Models.Stamtabel>
#{
var ItemsByAccordatieFunctieGroep = Model.GroupBy(a => a.Code);
<div class="row">
#foreach (var Accordeerders in ItemsByAccordatieFunctieGroep)
{
<div class="col-md-4">
<div class="panel panel-default">
<!-- Default panel contents -->
<div class="panel-heading blue">#Accordeerders.Key</div>
<!-- List group -->
<ul class="list-group">
#foreach (var Accordeerder in Accordeerders)
{
<li class="list-group-item">
#Accordeerder.Omschrijving
</li>
}
</ul>
</div>
</div>
}
</div>
}
So my question is:
How to return the correct user and that you will get the correct id?
Thank you
this has to be the link for new message:
SelfService/Profiel/Nieuw?id=6240&onderwerp=test
So the controller is: Profiel.
But now the link is this:
/PersoneelsDossier/StuurBericht/0?onderwerp=HRM%20Management
So the controller link is incorrect.
Your #Url.Action is wrong, it should be:
#Accordeerder.Omschrijving
I'm very new to ASP.NET, but I've added a FirstName (string), LastName (string), and AccountType (int, which can be a 0, 1, or 2) to my AspNetUsers database. I am working in MVC 5. While I've found numerous articles about changing the password, but I'd like to add the ability to let users change AccountType.
I am aware that the Roles might have been a better option in this case, but I've implemented so much already I'd rather not change that now.
The form for the Account Type Change contains a field for the user to input his/her password (to confirm that they would like the Account Type changed, and a dropdown list giving three options whose value is either 0, 1, or 2.
In short, the user will enter their password, click an option on the dropdownlist, then click the "sumbit button" and AccountType will be changed to a different int
#using SouthMeckNTHS.Models
#using SouthMeckNTHS.Extensions
#model ChangeAccountViewModel
#{
ViewBag.Title = "Change Account Type";
}
<section class="engine"></section>
<section class="mbr-section article mbr-parallax-background mbr-after-navbar" id="msg-box8-7d" style="background-image: url(../assets/images/full-unsplash-photo-1438354886727-070458b3b5cf-2000x1553-39.jpg); padding-top: 120px; padding-bottom: 80px;">
<div class="mbr-overlay" style="opacity: 0.5; background-color: rgb(34, 34, 34);">
</div>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2 text-xs-center">
<h3 class="mbr-section-title display-2">MANAGE YOUR ACCOUNT</h3>
<div class="lead"><p>Change your account settings</p></div>
</div>
</div>
</div>
#using (Html.BeginForm("AccountChange", "Manage", FormMethod.Post, new {
#class = "form-horizontal", role = "form" }))
{
Html.AntiForgeryToken();
<div class="mbr-section mbr-section__container mbr-section__container--middle">
<div class="container">
<div class="row">
<div class="col-xs-12 text-xs-center">
</div>
</div>
</div>
</div>
<div class="mbr-section mbr-section-nopadding">
<div class="container">
<div class="row">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="col-xs-12 col-lg-10 col-lg-offset-1">
<div class="row row-sm-offset">
<div class="col-xs-12 col-md-12">
<div class="form-group">
<label class="form-control-label" for="form1-z-name">Enter your current email<span class="form-asterisk">*</span></label>
#Html.TextBoxFor(m => m.CurrentPassword, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.CurrentPassword, "", new { #class = "text-danger", #style = "color:white" })
<!--<input type="text" class="form-control" name="name" required="" data-form-field="Name" id="form1-z-name">-->
</div>
</div>
<div class="col-xs-12 col-md-12">
<div class="form-group">
<label class="form-control-label" for="form1-z-name">Choose Your Account Type<span class="form-asterisk">*</span></label>
#Html.DropDownListFor(
m => m.NewAccountType,
new SelectList(
new List<Object>
{
new { value = 0 , text
= "Learner" },
new { value = 1 , text
= "Contributor" },
new { value = 2 , text
= "Competitor"}
},
"value",
"text"
), new { #style = "border: 1px solid #e8e8e8;padding: 0.5em 1.07em 0.5em;background: #f5f5f5;font-size: 0.875rem;border-radius: 5px;width: 100%;line-height: 1.43;min-height: 3.5em;" }
)
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<section class="mbr-section mbr-section__container" id="buttons1-r" style="background-color: rgb(255, 255, 255); padding-top: 10px; padding-bottom: 5px;">
<div class="container">
<div class="row">
<div class="col-xs-12">
<div class="text-xs-center"><input type="submit" class="btn btn-primary text-xs-center" value="CHANGE ACCOUNT TYPE" /> </div>
</div>
</div>
</div>
</section>
}
And here is part of ManageViewModels.cs:
public class ChangeAccountViewModel
{
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string CurrentPassword { get; set; }
[Required]
[Display(Name = "Choose Account Type")]
public int NewAccountType { get; set; }
}
So, likely in ManageController.cs, what should I add to allow the information from the first part of the form to check against the user's password and what should I add to the same file so that (if the passwords match) it will update the AccountType database with the user's choice?
(An edited copy of the "change password" function did not work)
UPDATE
I added this to ManageController.cs:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> AccountChange(ChangeAccountViewModel model)
{
if (ModelState.IsValid)
{
// Get the current application user
var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
//Update the details
user.AccountType = model.NewAccountType;
// Update user address
var result = await UserManager.UpdateAsync(user);
}
return View(model);
}
But it only works once. I run a test of it, I change the user's account type, and it saves to the AspNetUsers db. However, when I run it again, I can't change it anymore in ANY user accounts. What should I do to get this to work every time the user changes the dropdownlist and clicks the submit button?
I decided to just log the user out and have them sign back in.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> AccountChange(ChangeAccountViewModel model)
{
//THE THING THAT ONLY WORKED ONCE:
if (ModelState.IsValid)
{
// Get the current application user
var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
//Update the details
user.AccountType = model.NewAccountType;
// Update user account type
var result = await UserManager.UpdateAsync(user);
if (result.Succeeded)
{
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
return RedirectToAction("../Account/Login");
}
}
return View(model);
}
I am new in MVC asp.net i am developing a project where i want to add floors sequence wise. Want to start sequence from 0.
Message=LINQ to Entities does not recognize the method 'NTB.Floor LastOrDefault[Floor](System.Linq.IQueryable1[NTB.Floor], System.Linq.Expressions.Expression1[System.Func`2[NTB.Floor,System.Boolean]])' method, and this method cannot be translated into a store expression.
Controller:
public ActionResult Create(int id)
{
var cfloorno = 0;
//if (bid > 0)
//{
var lastfloor = db.Floors.Last(x => x.BuildingId == id);
if (lastfloor != null)
{
cfloorno = lastfloor.FloorNo.GetValueOrDefault() + 1;
}
//}
var building = db.Buildings.ToList();
ViewBag.Building = building;
var type = db.FloorTypes.ToList();
ViewBag.Type = type;
ViewBag.CurrentFloor = cfloorno;
ViewBag.buildingid = id;
return View();
}
[HttpPost]
public ActionResult Create(Floor f)
{
using (db)
{
db.Floors.Add(f);
db.SaveChanges();
}
return RedirectToAction("List");
}
View:
<input type="hidden" name="BuildingId" value="#ViewBag.buildingid" />
<div class="row">
<label class="col-sm-2 control-label">Floor #</label>
<div class="col-sm-10">
<input class="form-control" name="FloorNo" value="#ViewBag.CurrentFloor" disabled type="number">
#Html.ValidationMessageFor(model => model.FloorNo)
</div>
</div>