returning data from model to view - asp.net-mvc

now how to get data back in View from model ?
my code:
View:
#using (Html.BeginForm("register","Home", FormMethod.Post, new {id="submitForm"}))
{
<div>
<i>#Html.Label("Name:")</i>
#Html.TextBox("txtboxName")
</div>
<div>
<i>#Html.Label("Email:")</i>
#Html.TextBox("txtboxEmail")
</div>
<div>
<i>#Html.Label("Password:")</i>
#Html.Password("txtboxPassword")
</div>
<div>
<button type="submit" id="btnSubmit" name="Command" value="Submit">Submit</button>
</div>
}
controller:
[HttpPost]
public ActionResult register(string command, FormCollection formData )
{
if (command == "Submit")
{
var name = formData["txtboxName"];
var email = formData["txtboxEmail"];
var pwd = formData["txtboxPassword"];
database db = new database();
db.connectDB(name, email, pwd);
ViewBag.Message = email;
}
return View();
}
}
}
Model:
namespace LoginSys.Models
{
public class database
{
public void connectDB(String name, String email, String pwd)
{
String conStr = "Data Source=HUNAIN-PC;Initial Catalog=registration;User ID=sa;Password=abc123!##";
sqlconnection sqlCon = new sqlconnection(conStr);
string comm = "insert into tblRegister values('"+name+"','"+email+"','"+pwd+"')";
sqlcommand sqlCom = new sqlcom(comm, con);
try
{
sqlCon.Open();
sqlCon.executeNonQuery();
}
catch(exception exc)
{
//code
}
finally
{
con.close();
}
}
}
}
now how to return NO OF ROWS EFFECTED BY EXECUTENONQUERY statement or suppose any thing to return ? simple words and please help me in this approach, will use advance techniques later.

If you want to return something, you can use SqlParameter ParameterDirection.Output like this:
SqlCommand cc = new SqlCommand(connStr); // connection string
cc.CommandText = "insert into tblRegister (Name, Email, Pwd) values (#name, #email, #pwd); select #result = ##identity";
cc.AddWithValue("#name", name);
cc.AddWithValue("#email", email);
cc.AddWithValue("#pwd", pwd);
cc.Parameters.Add("#result", SqlDbType.Int);
cc.Parameters["#result"].Direction = ParameterDirection.Output;
cc.ExecuteNonQuery();
// returs identity key
int id = (int)cc.Parameters["#result"].Value;
Then you can return this id from your function, but you have to modify it's prototype:
public int connectDB(String name, String email, String pwd) // changed void to int
{
// ...
return id;
}
Then you can simply put this value to ViewBag, or use other ways to pass it to your view:
database db = new database();
ViewBag.Id = db.connectDB(name, email, pwd);
ViewBag.Message = email;
If you use ViewBag, you can access it in your view with #ViewBag.Id

Related

WCF---Consuming CRUD operation using Linq in ASP.NET MVC application?

enter image description here
First step...Opened WCF created IService:
namespace CRUDOperationWCFMVC
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
[ServiceContract]
public interface IService1
{
[OperationContract]
bool CreateDetails(EmployeeDetails employeeDetails);
[OperationContract]
bool UpdateDetails(EmployeeDetails employeeDetails);
[OperationContract]
bool DeleteDetails(int id);
[OperationContract]
List<EmployeeDetails> GetDetails();
}
public class EmployeeDetails
{
[DataMember]
public int EmpID { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string Location { get; set; }
[DataMember]
public int? Salary { get; set; }
}
}
Step 2: then I implemented service code:
public class Service1 : IService1
{
DataClasses1DataContext dcd = new DataClasses1DataContext();
public bool CreateDetails(EmployeeDetails employeeDetails)
{
Nevint emp = new Nevint();
emp.EmpID= employeeDetails.EmpID;
emp.Name = employeeDetails.Name;
emp.Location = employeeDetails.Location;
emp.Salary = employeeDetails.Salary;
dcd.Nevints.InsertOnSubmit(emp);
dcd.SubmitChanges();
return true;
}
public bool DeleteDetails(int id)
{
var delete = (from v in dcd.Nevints where v.EmpID==id select v).FirstOrDefault();
dcd.Nevints.DeleteOnSubmit(delete);
dcd.SubmitChanges();
return true;
}
public List<EmployeeDetails> GetDetails()
{
List<EmployeeDetails> details = new List<EmployeeDetails>();
var select= (from v in dcd.Nevints select v);
foreach (var i in select)
{
EmployeeDetails emp = new EmployeeDetails();
emp.EmpID = i.EmpID;
emp.Name = i.Name;
emp.Location = i.Location;
emp.Salary = i.Salary;
details.Add(emp);
}
return details;
}
public bool UpdateDetails(EmployeeDetails employeeDetails)
{
var update = (from v in dcd.Nevints.ToList() where employeeDetails.EmpID==v.EmpID select v).FirstOrDefault();
update.EmpID = employeeDetails.EmpID;
update.Name = employeeDetails.Name;
update.Location = employeeDetails.Location;
update.Salary = employeeDetails.Salary;
dcd.SubmitChanges();
return true;
}
}
Step 3: then I add linq to sql, opened my ASP.NET MVC project for consuming, and added a controller and wrote this code:
namespace ConsumingClient.Controllers
{
public class EmpdetailsController : Controller
{
ServiceReference1.Service1Client serobj=new ServiceReference1.Service1Client();
ServiceReference1.EmployeeDetails empdetails=new ServiceReference1.EmployeeDetails();
// GET: Empdetails
public ActionResult Index()
{
List<employee> lstemp = new List<employee>();
var result = serobj.GetDetails();
foreach (var i in result)
{
employee emp = new employee();
empdetails.EmpID = i.EmpID;
empdetails.Name = i.Name;
empdetails.Location = i.Location;
empdetails.Salary = i.Salary;
lstemp.Add(emp);
}
return View(result);
}
// GET: Empdetails/Details/5
public ActionResult Details(int id)
{
Employees emp = new Employees();
return View();
}
// GET: Empdetails/Create
public ActionResult Create()
{
return View();
}
// POST: Empdetails/Create
[HttpPost]
public ActionResult Create(Employees employees)
{
try
{
// TODO: Add insert logic here
empdetails.EmpID=employees.EmpID;
empdetails.Name = employees.Name;
empdetails.Location = employees.Location;
empdetails.Salary = employees.Salary;
serobj.CreateDetails(empdetails);
return RedirectToAction("Index");
}
catch
{
return View();
}
}
// GET: Empdetails/Edit/5
public ActionResult Edit(int id)
{
Employees emp = new Employees();
var result = serobj.GetDetails().FirstOrDefault(a=>a.EmpID==id);
emp.EmpID = result.EmpID;
emp.Name = result.Name;
emp.Location = result.Location;
emp.Salary = result.Salary;
return View(emp);
}
// POST: Empdetails/Edit/5
[HttpPost]
public ActionResult Edit(Employees employees)
{
try
{
// TODO: Add update logic here
empdetails.EmpID = employees.EmpID;
empdetails.Name = employees.Name;
empdetails.Location = employees.Location;
empdetails.Salary = employees.Salary;
serobj.UpdateDetails(empdetails);
return RedirectToAction("Index");
}
catch
{
return View(employees);
}
}
// GET: Empdetails/Delete/5
public ActionResult Delete(int id)
{
Employees emp = new Employees();
var result = serobj.GetDetails().FirstOrDefault(a=>a.EmpID==id);
emp.EmpID = result.EmpID;
emp.Name = result.Name;
emp.Location = result.Location;
emp.Salary = result.Salary;
return View(emp);
}
// POST: Empdetails/Delete/5
[HttpPost]
public ActionResult Delete(int id, FormCollection collection)
{
try
{
// TODO: Add delete logic here
serobj.DeleteDetails(id);
return RedirectToAction("Index");
}
catch
{
return View(id);
}
}
}
}
Data was displaying fine. I can create data.
However, when I click on edit and delete, I'm getting an error:
ERROR Message "Server Error in '/' Application.
The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Edit(Int32)' in 'ConsumingClient.Controllers.EmpdetailsController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Parameter name: parameters
This error is thrown if you attempt to call this controller action and you do not specify the id either in the path portion or as query string parameter. Since your controller action takes an id as parameter you should make sure that you always specify this parameter.
Make sure that when you are requesting this action you have specified a valid id in the url:
http://example.com/somecontroller/Edit/123
If you are generating an anchor, make sure there's an id:
#Html.ActionLink("Edit", "somecontroller", new { id = "123" })
If you are sending an AJAX request, also make sure that the id is present in the url.
If on the other hand the parameter is optional, you could make it a nullable integer:
public ActionResult Edit(int? id)
but in this case you will have to handle the case where the parameter value is not specified.
https://coderedirect.com/questions/197477/mvc-the-parameters-dictionary-contains-a-null-entry-for-parameter-k-of-non-n

How to fill dropdownlist in MVC-4 using dapper

I filled Drop Down List in MVC which is working fine but now I want to do it using Dapper but got stuck.
DropDownList in MVC without Dapper
Controller
[HttpPost]
public ActionResult Create(User ur)
{
string str = #"Data Source=DEV_3\SQLEXPRESS;Initial Catalog=DB_Naved_Test;Integrated Security=True";
SqlConnection con = new SqlConnection(str);
string query = "Insert into tblTest (Name,Email,MobileNo) values('" + ur.Name + "','" + ur.Email + "','" + ur.MobileNo + "')";
con.Open();
SqlCommand cmd = new SqlCommand(query, con);
cmd.ExecuteNonQuery();
con.Close();
TempData["msg"] = "<script>alert('Inserted Successfully');</script>";
ModelState.Clear();
FillCountry();
}
public void FillCountry()
{
string str = #"Data Source=DEV_3\SQLEXPRESS;Initial Catalog=DB_Naved_Test;Integrated Security=True";
SqlConnection con = new SqlConnection(str);
string query = "select * from tbl_country ";
SqlCommand cmd = new SqlCommand(query, con);
con.Open();
SqlDataReader rdr = cmd.ExecuteReader();
List<SelectListItem> li = new List<SelectListItem>();
li.Add(new SelectListItem { Text = "Select", Value = "0" });
while (rdr.Read())
{
li.Add(new SelectListItem { Text = rdr[1].ToString(), Value = rdr[0].ToString() });
}
ViewData["country"] = li;
}
View
#{ Html.BeginForm("Create", "User", FormMethod.Post, new { enctype = "multipart/form-data" }); }
#Html.DropDownList("country", ViewData["country"] as List<SelectListItem>, new {onchange = "this.form.submit();" })
#{ Html.EndForm(); }
This is what I am trying to do now
DropDownList in MVC with Dapper
Model
public class Region
{
private int _CountryId;
private string _CountryName;
public int CountryId
{
get { return _CountryId; }
set { _CountryId = value; }
}
public string CountryName
{
get { return _CountryName; }
set { _CountryName = value; }
}
Controller
[HttpPost]
public ActionResult AddMobiles(TBMobileDetails MD, HttpPostedFileBase file)
{
FileUpload(file);
MobileMain MM = new MobileMain();
MM.AddMobiles(MD);
FillCountry();
return RedirectToAction("AllMobileList");
}
Stuck in this part how to fill it using dapper? How to populate my list?
public void FillCountry()
{
List<Region> li = new List<Region>();
var para = new DynamicParameters();
para.Add("#Type", 1);
var result = con.Query<Region>("Sp_MVCDapperDDl", para, commandType: CommandType.StoredProcedure);
}
View
#{ Html.BeginForm("AddMobiles", "AddMobile", FormMethod.Post, new { enctype = "multipart/form-data" }); }
#Html.DropDownList("country", ViewData["country"] as List<SelectListItem>, new { onchange = "this.form.submit();" })
#{ Html.EndForm(); }
You are passing in ViewData["country"] object of type IEnumerable<Region> while in View you are casting it to IEnumerable<SelectListItem> which won't work obviously in action change FillCountry() to make SelectList:
public void FillCountry()
{
List<Region> li = new List<Region>();
var para = new DynamicParameters();
para.Add("#Type", 1);
var result = con.Query<Region>("Sp_MVCDapperDDl", para, commandType: CommandType.StoredProcedure);
var list = new SelectList(result,"CountryId","CountryName");
}
and in View now cast it to SelectList:
#Html.DropDownList("country", ViewData["country"] as SelectList, new {onchange = "this.form.submit();" })
This will get you going.

I can login only when user's UserName is exacly the same Email in database

I created fresh ASP .NET MVC 5 web application with individual accounts(default template). When I create user if I give him different UserName and Email I cannot login. If Email and UserName are the same I can login.
I used default template. What I need change to let UserName and Email be different?
Put in other words: The problem is that I can login only the user which have UserName and Email properties equal.
Put in other other words: There are two users, one have: Email:mailbox#gmail.com, UserName:mailbox#gmail.com I can login as this user. Second user Email:mailbox#gmail.com, UserName:SOMETHING I cannot log as this user.
Account controller:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin.Security;
using Owin;
using WebApplication2.Models;
namespace WebApplication2.Controllers {
[Authorize]
public class AccountController : Controller {
private ApplicationUserManager _userManager;
public AccountController() {
}
public AccountController(ApplicationUserManager userManager) {
UserManager = userManager;
}
public ApplicationUserManager UserManager {
get {
return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set {
_userManager = value;
}
}
//
// GET: /Account/Login
[AllowAnonymous]
public ActionResult Login(string returnUrl) {
ViewBag.ReturnUrl = returnUrl;
return View();
}
//
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl) {
if (ModelState.IsValid) {
var user = await UserManager.FindAsync(model.Email, model.Password);
if (user != null) {
await SignInAsync(user, model.RememberMe);
return RedirectToLocal(returnUrl);
} else {
ModelState.AddModelError("", "Invalid username or password.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
//
// GET: /Account/Register
[AllowAnonymous]
public ActionResult Register() {
return View();
}
//
// POST: /Account/Register
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model) {
if (ModelState.IsValid) {
var user = new ApplicationUser() { UserName = model.Email, Email = model.Email };
IdentityResult result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded) {
await SignInAsync(user, isPersistent: false);
// For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771
// Send an email with this link
// string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
// var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
// await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking here");
return RedirectToAction("Index", "Home");
} else {
AddErrors(result);
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
//
// GET: /Account/ConfirmEmail
[AllowAnonymous]
public async Task<ActionResult> ConfirmEmail(string userId, string code) {
if (userId == null || code == null) {
return View("Error");
}
IdentityResult result = await UserManager.ConfirmEmailAsync(userId, code);
if (result.Succeeded) {
return View("ConfirmEmail");
} else {
AddErrors(result);
return View();
}
}
//
// GET: /Account/ForgotPassword
[AllowAnonymous]
public ActionResult ForgotPassword() {
return View();
}
//
// POST: /Account/ForgotPassword
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ForgotPassword(ForgotPasswordViewModel model) {
if (ModelState.IsValid) {
var user = await UserManager.FindByNameAsync(model.Email);
if (user == null || !(await UserManager.IsEmailConfirmedAsync(user.Id))) {
ModelState.AddModelError("", "The user either does not exist or is not confirmed.");
return View();
}
// For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771
// Send an email with this link
// string code = await UserManager.GeneratePasswordResetTokenAsync(user.Id);
// var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
// await UserManager.SendEmailAsync(user.Id, "Reset Password", "Please reset your password by clicking here");
// return RedirectToAction("ForgotPasswordConfirmation", "Account");
}
// If we got this far, something failed, redisplay form
return View(model);
}
//
// GET: /Account/ForgotPasswordConfirmation
[AllowAnonymous]
public ActionResult ForgotPasswordConfirmation() {
return View();
}
//
// GET: /Account/ResetPassword
[AllowAnonymous]
public ActionResult ResetPassword(string code) {
if (code == null) {
return View("Error");
}
return View();
}
//
// POST: /Account/ResetPassword
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ResetPassword(ResetPasswordViewModel model) {
if (ModelState.IsValid) {
var user = await UserManager.FindByNameAsync(model.Email);
if (user == null) {
ModelState.AddModelError("", "No user found.");
return View();
}
IdentityResult result = await UserManager.ResetPasswordAsync(user.Id, model.Code, model.Password);
if (result.Succeeded) {
return RedirectToAction("ResetPasswordConfirmation", "Account");
} else {
AddErrors(result);
return View();
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
//
// GET: /Account/ResetPasswordConfirmation
[AllowAnonymous]
public ActionResult ResetPasswordConfirmation() {
return View();
}
//
// POST: /Account/Disassociate
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Disassociate(string loginProvider, string providerKey) {
ManageMessageId? message = null;
IdentityResult result = await UserManager.RemoveLoginAsync(User.Identity.GetUserId(), new UserLoginInfo(loginProvider, providerKey));
if (result.Succeeded) {
var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
await SignInAsync(user, isPersistent: false);
message = ManageMessageId.RemoveLoginSuccess;
} else {
message = ManageMessageId.Error;
}
return RedirectToAction("Manage", new { Message = message });
}
//
// GET: /Account/Manage
public ActionResult Manage(ManageMessageId? message) {
ViewBag.StatusMessage =
message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed."
: message == ManageMessageId.SetPasswordSuccess ? "Your password has been set."
: message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed."
: message == ManageMessageId.Error ? "An error has occurred."
: "";
ViewBag.HasLocalPassword = HasPassword();
ViewBag.ReturnUrl = Url.Action("Manage");
return View();
}
//
// POST: /Account/Manage
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Manage(ManageUserViewModel model) {
bool hasPassword = HasPassword();
ViewBag.HasLocalPassword = hasPassword;
ViewBag.ReturnUrl = Url.Action("Manage");
if (hasPassword) {
if (ModelState.IsValid) {
IdentityResult result = await UserManager.ChangePasswordAsync(User.Identity.GetUserId(), model.OldPassword, model.NewPassword);
if (result.Succeeded) {
var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
await SignInAsync(user, isPersistent: false);
return RedirectToAction("Manage", new { Message = ManageMessageId.ChangePasswordSuccess });
} else {
AddErrors(result);
}
}
} else {
// User does not have a password so remove any validation errors caused by a missing OldPassword field
ModelState state = ModelState["OldPassword"];
if (state != null) {
state.Errors.Clear();
}
if (ModelState.IsValid) {
IdentityResult result = await UserManager.AddPasswordAsync(User.Identity.GetUserId(), model.NewPassword);
if (result.Succeeded) {
return RedirectToAction("Manage", new { Message = ManageMessageId.SetPasswordSuccess });
} else {
AddErrors(result);
}
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
//
// POST: /Account/ExternalLogin
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult ExternalLogin(string provider, string returnUrl) {
// Request a redirect to the external login provider
return new ChallengeResult(provider, Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl }));
}
//
// GET: /Account/ExternalLoginCallback
[AllowAnonymous]
public async Task<ActionResult> ExternalLoginCallback(string returnUrl) {
var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
if (loginInfo == null) {
return RedirectToAction("Login");
}
// Sign in the user with this external login provider if the user already has a login
var user = await UserManager.FindAsync(loginInfo.Login);
if (user != null) {
await SignInAsync(user, isPersistent: false);
return RedirectToLocal(returnUrl);
} else {
// If the user does not have an account, then prompt the user to create an account
ViewBag.ReturnUrl = returnUrl;
ViewBag.LoginProvider = loginInfo.Login.LoginProvider;
return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { Email = loginInfo.Email });
}
}
//
// POST: /Account/LinkLogin
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LinkLogin(string provider) {
// Request a redirect to the external login provider to link a login for the current user
return new ChallengeResult(provider, Url.Action("LinkLoginCallback", "Account"), User.Identity.GetUserId());
}
//
// GET: /Account/LinkLoginCallback
public async Task<ActionResult> LinkLoginCallback() {
var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(XsrfKey, User.Identity.GetUserId());
if (loginInfo == null) {
return RedirectToAction("Manage", new { Message = ManageMessageId.Error });
}
IdentityResult result = await UserManager.AddLoginAsync(User.Identity.GetUserId(), loginInfo.Login);
if (result.Succeeded) {
return RedirectToAction("Manage");
}
return RedirectToAction("Manage", new { Message = ManageMessageId.Error });
}
//
// POST: /Account/ExternalLoginConfirmation
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl) {
if (User.Identity.IsAuthenticated) {
return RedirectToAction("Manage");
}
if (ModelState.IsValid) {
// Get the information about the user from the external login provider
var info = await AuthenticationManager.GetExternalLoginInfoAsync();
if (info == null) {
return View("ExternalLoginFailure");
}
var user = new ApplicationUser() { UserName = model.Email, Email = model.Email };
IdentityResult result = await UserManager.CreateAsync(user);
if (result.Succeeded) {
result = await UserManager.AddLoginAsync(user.Id, info.Login);
if (result.Succeeded) {
await SignInAsync(user, isPersistent: false);
// For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771
// Send an email with this link
// string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
// var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
// SendEmail(user.Email, callbackUrl, "Confirm your account", "Please confirm your account by clicking this link");
return RedirectToLocal(returnUrl);
}
}
AddErrors(result);
}
ViewBag.ReturnUrl = returnUrl;
return View(model);
}
//
// POST: /Account/LogOff
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff() {
AuthenticationManager.SignOut();
return RedirectToAction("Index", "Home");
}
//
// GET: /Account/ExternalLoginFailure
[AllowAnonymous]
public ActionResult ExternalLoginFailure() {
return View();
}
[ChildActionOnly]
public ActionResult RemoveAccountList() {
var linkedAccounts = UserManager.GetLogins(User.Identity.GetUserId());
ViewBag.ShowRemoveButton = HasPassword() || linkedAccounts.Count > 1;
return (ActionResult)PartialView("_RemoveAccountPartial", linkedAccounts);
}
protected override void Dispose(bool disposing) {
if (disposing && UserManager != null) {
UserManager.Dispose();
UserManager = null;
}
base.Dispose(disposing);
}
#region Helpers
// Used for XSRF protection when adding external logins
private const string XsrfKey = "XsrfId";
private IAuthenticationManager AuthenticationManager {
get {
return HttpContext.GetOwinContext().Authentication;
}
}
private async Task SignInAsync(ApplicationUser user, bool isPersistent) {
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, await user.GenerateUserIdentityAsync(UserManager));
}
private void AddErrors(IdentityResult result) {
foreach (var error in result.Errors) {
ModelState.AddModelError("", error);
}
}
private bool HasPassword() {
var user = UserManager.FindById(User.Identity.GetUserId());
if (user != null) {
return user.PasswordHash != null;
}
return false;
}
private void SendEmail(string email, string callbackUrl, string subject, string message) {
// For information on sending mail, please visit http://go.microsoft.com/fwlink/?LinkID=320771
}
public enum ManageMessageId {
ChangePasswordSuccess,
SetPasswordSuccess,
RemoveLoginSuccess,
Error
}
private ActionResult RedirectToLocal(string returnUrl) {
if (Url.IsLocalUrl(returnUrl)) {
return Redirect(returnUrl);
} else {
return RedirectToAction("Index", "Home");
}
}
private class ChallengeResult : HttpUnauthorizedResult {
public ChallengeResult(string provider, string redirectUri)
: this(provider, redirectUri, null) {
}
public ChallengeResult(string provider, string redirectUri, string userId) {
LoginProvider = provider;
RedirectUri = redirectUri;
UserId = userId;
}
public string LoginProvider { get; set; }
public string RedirectUri { get; set; }
public string UserId { get; set; }
public override void ExecuteResult(ControllerContext context) {
var properties = new AuthenticationProperties() { RedirectUri = RedirectUri };
if (UserId != null) {
properties.Dictionary[XsrfKey] = UserId;
}
context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider);
}
}
#endregion
}
}
Login view:
#using WebApplication2.Models
#model LoginViewModel
#{
ViewBag.Title = "Log in";
}
<h2>#ViewBag.Title.</h2>
<div class="row">
<div class="col-md-8">
<section id="loginForm">
#using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { #class = "form-horizontal", role = "form" }))
{
#Html.AntiForgeryToken()
<h4>Use a local account to log in.</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(m => m.Email, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.Email, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.Email, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.Password, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.PasswordFor(m => m.Password, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.Password, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<div class="checkbox">
#Html.CheckBoxFor(m => m.RememberMe)
#Html.LabelFor(m => m.RememberMe)
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Log in" class="btn btn-default" />
</div>
</div>
<p>
#Html.ActionLink("Register as a new user", "Register")
</p>
#* Enable this once you have account confirmation enabled for password reset functionality
<p>
#Html.ActionLink("Forgot your password?", "ForgotPassword")
</p>*#
}
</section>
</div>
<div class="col-md-4">
<section id="socialLoginForm">
#Html.Partial("_ExternalLoginsListPartial", new ExternalLoginListViewModel { Action = "ExternalLogin", ReturnUrl = ViewBag.ReturnUrl })
</section>
</div>
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
DISCLAIMER: I do not ask how to create users I did.
var store = new UserStore<ApplicationUser>(context);
var userManager = new ApplicationUserManager(store);
var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
string roleName = "Admin";
if (!roleManager.RoleExists(roleName)) {
roleManager.Create(new IdentityRole(roleName));
}
roleName = "TeleMarketer";
if (!roleManager.RoleExists(roleName)) {
roleManager.Create(new IdentityRole(roleName));
}
roleName = "Marketer";
if (!roleManager.RoleExists(roleName)) {
roleManager.Create(new IdentityRole(roleName));
}
var user = new ApplicationUser() { Email = "informatyka4444#wp.pl", UserName = "Robert" };
userManager.Create(user, "TestPass44!");
userManager.AddToRole(user.Id, "Admin");
user = new ApplicationUser() { Email = "s8359#pjwstk.edu.pl", UserName = "Admin" };
userManager.Create(user, "TestPass44!");
userManager.AddToRole(user.Id, "Admin");
user = new ApplicationUser() { Email = "marketer#wp.pl", UserName = "Marketer" };
userManager.Create(user, "TestPass44!");
userManager.AddToRole(user.Id, "TeleMarketer");
user = new ApplicationUser() { Email = "telemarketer#wp.pl", UserName = "TeleMarketer" };
userManager.Create(user, "TestPass44!");
userManager.AddToRole(user.Id, "Marketer");
The problem is actually very simple and quite reproducible. It looks like the guys at Microsoft took a shortcut and assumed that everyone would always want their email address to be their username. In my case I had a strict requirement where the user name cannot be an email address.
I was able to make the changes necessary to use both fields as truly intended, but when I tried to log in using the scaffolded/provided/out-of-the-box /Manage/Login.cshtml view it absolutely forced me to use an email address as the user name. This is not the intended behavior because even the under the covers method specifies "username" as the parameter. I don't have this problem when I use my own view/processing to log into the application. And yes, my stuff goes through the same (and official) SignInManger.
The validation happening on the client side is what was forcing us to use an email address field value. This doesn't appear to be exposed anywhere that is configurable... and it took me the LONGEST time to find it. I actually felt pretty stupid for about 5 minutes.
The solution (for my scenario) was to...
Open the /Models/AccountViewModels.cs file.
Navigate to the LoginViewModel class.
On the Email property remove (or comment out) the [EmailAddress] decorator Attribute.
Modify the Display decorator Attribute (specifically, the Name property) to something appropriate -- fyi, this is what will be shown in the #Html.LabelFor() and validation messages as well.
Clear out the browser cache for that site. You can try a hard refresh, but YMMV depending on your browser.
Give it a whirl
In my case, problem solved. I hope this helps (even though it's nearly a year later)!
If you look closely into the generated code you will find the LogIn method:
//
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl) {
if (ModelState.IsValid) {
var user = await UserManager.FindAsync(model.Email, model.Password);
if (user != null) {
await SignInAsync(user, model.RememberMe);
return RedirectToLocal(returnUrl);
} else {
ModelState.AddModelError("", "Invalid username or password.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
Here you see that the user is being found by using his email address - that is why u have to login using the Email. If you want to change the behaviour - simply modify the LoginViewModel class and the login View.
Take a look at what you're doing in your Register action:
var user = new ApplicationUser() { UserName = model.Email, Email = model.Email };
When a user registers, they supply a username and an email. But you're ignoring the username and using the email for both values. I imagine this would be highly unintuitive for users registering in your application.
Try using the username value as the username value:
var user = new ApplicationUser() { UserName = model.UserName, Email = model.Email };
Asp.Net Identity uses username and password to authenticate if you want to login with either username or password check if email is supplied then use the userManager.FindByEmailAsync(model.Email); to retrieve corresponding username and login check my login code below
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
if (model.Email.IndexOf('#') > -1)
{
//Validate email format
string emailRegex = #"^([a-zA-Z0-9_\-\.]+)#((\[[0-9]{1,3}" +
#"\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\" +
#".)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$";
Regex re = new Regex(emailRegex);
if (!re.IsMatch(model.Email))
{
ModelState.AddModelError("Email", "Email is not valid");
}
}
else
{
//validate Username format
string emailRegex = #"^[a-zA-Z0-9]*$";
Regex re = new Regex(emailRegex);
if (!re.IsMatch(model.Email))
{
ModelState.AddModelError("Email", "Username is not valid");
}
}
if (ModelState.IsValid)
{
var userName = model.Email;
if (userName.IndexOf('#') > -1)
{
var user = await _userManager.FindByEmailAsync(model.Email);
if (user == null)
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return View(model);
}
else
{
userName = user.UserName;
}
}
var result = await _signInManager.PasswordSignInAsync(userName, model.Password, model.RememberMe, lockoutOnFailure: false);

MVC 5: On password change using UserManger, Invalid length for a Base-64 char array or string

In my MVC(5.1) application. I wanted to add password change.
This is what I have done,
public class AccountController : Controller
{
private readonly ILicenserepository _licenserepository;
private readonly IUserRepository _userRepository;
public AccountController(ILicenserepository licenserepository, IUserRepository userRepository)
{
_licenserepository = licenserepository;
_userRepository = userRepository;
//UserManager = userManager;
}
public UserManager<ApplicationUser> UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new DatePickerDbContext()));
....
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Manage(ManageUserViewModel model)
{
bool hasPassword = HasPassword();
ViewBag.HasLocalPassword = hasPassword;
ViewBag.ReturnUrl = Url.Action("Manage");
if (hasPassword)
{
if (ModelState.IsValid)
{
string userId = User.Identity.GetUserId();
IdentityResult result = UserManager.ChangePassword(userId, model.OldPassword, model.NewPassword);
if (result.Succeeded)
{
return RedirectToAction("Manage", new { Message = ManageMessageId.ChangePasswordSuccess });
}
else
{
AddErrors(result);
}
}
}
else
{
// User does not have a password so remove any validation errors caused by a missing OldPassword field
ModelState state = ModelState["OldPassword"];
if (state != null)
{
state.Errors.Clear();
}
if (ModelState.IsValid)
{
IdentityResult result = await UserManager.AddPasswordAsync(User.Identity.GetUserId(), model.NewPassword);
if (result.Succeeded)
{
return RedirectToAction("Manage", new { Message = ManageMessageId.SetPasswordSuccess });
}
else
{
AddErrors(result);
}
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
}
When I run the application I get this error on browser
Invalid length for a Base-64 char array or string.
at line
IdentityResult result = UserManager.ChangePassword(userId, model.OldPassword, model.NewPassword);
I don't know what's wrong.
Is it because I haven't initialized my UserManger in constructor?
when I inspect the values in userId, model.OldPassword and model.NewPassword, all the values are as I expect. userId holds userId value, oldpassword holds oldpassowrd value and new password holds newpassword value provided from user.
It was my stupid mistake
I had created User like this before
var user = new ApplicationUser
{
FirstName = model.FirstName,
LastName = model.Lastname,
Phone = model.Phone,
Email = model.EmailId,
Company = model.Company,
PasswordHash = model.ConfirmPassword
UserName = model.UserName,
DateTimeRegistered = DateTime.UtcNow,
License = model.SelectedLicense,
IsApproved = true,
};
var result = UserManager.Create(user);
Here, the password would not be hashed and be saved as exact string user provides.
That was creating error.
should have provided password while creating the user like
var user = new ApplicationUser
{
FirstName = model.FirstName,
LastName = model.Lastname,
Phone = model.Phone,
Email = model.EmailId,
Company = model.Company,
UserName = model.UserName,
DateTimeRegistered = DateTime.UtcNow,
License = model.SelectedLicense,
IsApproved = true,
};
var result = UserManager.Create(user,model.ConfirmPassword);

How to return a DataSet to a View

I am sending a standard Sql select statement to my Sql box via the SqlDataAdapter, then populating a DataSet object.
I can access the rows in the resulting DataSet, but how can I convert the DataSet into a List which can be returned to the MVC View. i.e. I'm assuming a List object is the best way to handle this.
Here's my controller c# code:
public class QAController : Controller
{
private readonly static string connString = ConfigurationManager.ConnectionStrings["RegrDBConnection"].ToString();
private readonly static SqlConnection sqlConn = new SqlConnection(connString);
private readonly static SqlCommand sqlComm = new SqlCommand();
public ActionResult Index()
{
DbRegressionExec();
return View();
}
public static void DbRegressionExec()
{
// SELECT TABLE CONTENTS FROM SQL !!
RegressDB_TableList regresDB = new RegressDB_TableList();
string sqlStr = "select * from [RegressionResults].[dbo].[Diff_MasterList] order by TableName";
// POPULATE DATASET OBJECT
DataSet ds = new DataSet();
SqlDataAdapter da = new SqlDataAdapter(sqlStr, sqlConn);
da.SelectCommand.CommandType = CommandType.Text;
sqlConn.Open();
try
{
da.Fill(ds, "RegresDB");
}
catch (Exception e)
{
throw;
}
finally
{
sqlConn.Close();
}
// I can iterate thru rows here, but HOW DO CONVERT TO A LIST OBJECT ????
int numRows = ds.Tables["RegresDB"].Rows.Count;
for (int i = 0; i < numRows; i++)
{
string tblName = ds.Tables["RegresDB"].Rows[i].Field<string>("TableName");
}
//List<RegressDB_TableList> masterList = regresDB.RegresTableList.ToList(); //not working !!
//var masterList = regresDB.TableName.ToList(); //
}
}
and a simple class I may need to make this happen:
namespace RegressionMvc.Models
{
public class RegresDB_TableName
{
public string TableName { get; set; }
}
public class RegressDB_TableList
{
public List<RegresDB_TableName> RegresTableList { get; set; }
}
}
In the end, I'm trying to figure out the best way to handle DataSet results from Sql Server and how to make them back to an MVC View.
I can probably go with jQuery and Json, meaning just convert the data fields to Json and return to JQuery, but I'm sure there are several ways to handle Sql based result sets.
Thanks in advance for your advice....
Best,
Bob
In your controller put the code like this
[HttpGet]
public ActionResult View(Modelclass viewmodel)
{
List<Modelclass> employees = new List<Modelclass>();
DataSet ds = viewmodel.GetAllAuthors();
var empList = ds.Tables[0].AsEnumerable().Select(dataRow => new Modelclass{
AuthorId = dataRow.Field<int>("AuthorId"),
Fname = dataRow.Field<string>("FName"),
Lname = dataRow.Field<string>("Lname")
});
var list = empList.ToList();
return View(list);
}
And in view
#{
var gd = new WebGrid(Model, canPage: true, rowsPerPage: 5, selectionFieldName: "selectedRow",ajaxUpdateContainerId: "gridContent");
gd.Pager(WebGridPagerModes.NextPrevious);}
#gd.GetHtml(tableStyle: "table",
columns: gd.Columns(
gd.Column("AuthorId", "AuthorId"),
gd.Column("Fname", " Fname"),
gd.Column("Lname", "Lname", style: "description")
))
Short answer
Directly answering your question:
var tableList = new List<RegresDB_TableName>();
int numRows = ds.Tables["RegresDB"].Rows.Count;
for (int i = 0; i < numRows; i++)
{
string tblName = ds.Tables["RegresDB"].Rows[i].Field<string>("TableName");
tableList.Add(new RegresDB_TableName() { TableName = tblName };
}
return View(tableList);
Long answer (that's actually shorter)
Try out dapper-dot-net.
Your code could change to something like:
string sqlStr = "SELECT * FROM [RegressionResults].[dbo].[Diff_MasterList] ORDER BY TableName";
return sqlConn.Query<RegresDB_TableName>(sqlStr);
If you're stuck with using DAO, I would suggest not using a DataSet and instead use a strongly typed class with the speed of SqlDataReader.GetValues() method. It's more work, but it has to be done somewhere if you want strongly typed classes which I would highly recommend.
public class Person
{
public Person(Object[] values]
{
this.FirstName = (string)values[0];
this.LastName = (string)values[1];
this.Birthday = (DateTime)values[2];
this.HasFavoriteColor = (bool)values[3];
}
public string FirstName { get; private set; }
public string LastName { get; private set; }
public DateTime Birthday { get; private set; }
public bool HasFavoriteColor { get; private set; }
}
public static void DbRegressionExec()
{
List<Person> viewModel = new List<Person>();
// SELECT TABLE CONTENTS FROM SQL !!
RegressDB_TableList regresDB = new RegressDB_TableList();
string sqlStr = "select
FirstName
,LastName
,Birthday
,HasFavoriteColor
from [RegressionResults].[dbo].[Diff_MasterList]
order by TableName";
// POPULATE VIEWMODEL OBJECT
sqlConn.Open();
try
{
using (SqlCommand com = new SqlCommand(sqlStr, sqlConn))
{
using (SqlDbReader reader = com.ExecuteReader())
{
while(reader.Read())
{
viewModel.Add(new Person(com.GetValues()));
}
}
}
}
catch (Exception e)
{
throw;
}
finally
{
sqlConn.Close();
}
return this.View(viewModel);
}
Controller code
//pQ is your query you have created
//P4DAL is the key name for connection string
DataSet ds = pQ.Execute(System.Configuration.ConfigurationManager.ConnectionStrings["Platform4"].ConnectionString);
//ds will be used below
//create your own view model according to what you want in your view
//VMData is my view model
var _buildList = new List<VMData>();
{
foreach (DataRow _row in ds.Tables[0].Rows)
{
_buildList.Add(new VMData
{
//chose what you want from the dataset results and assign it your view model fields
clientID = Convert.ToInt16(_row[1]),
ClientName = _row[3].ToString(),
clientPhone = _row[4].ToString(),
bcName = _row[8].ToString(),
cityName = _row[5].ToString(),
provName = _row[6].ToString(),
});
}
}
//you will use this in your view
ViewData["MyData"] = _buildList;
View
#if (ViewData["MyData"] != null)
{
var data = (List<VMData>)ViewData["MyData"];
<div class="table-responsive">
<table class="display table" id="Results">
<thead>
<tr>
<td>Name</td>
<td>Telephone</td>
<td>Category </td>
<td>City </td>
<td>Province </td>
</tr>
</thead>
<tbody>
#foreach (var item in data)
{
<tr>
<td>#Html.ActionLink(item.ClientName, "_Display", new { id = item.clientID }, new { target = "_blank" })</td>
<td>#item.clientPhone</td>
<td>#item.bcName</td>
<td>#item.cityName</td>
<td>#item.provName</td>
</tr>
}
</tbody>
</table>
</div>
}

Resources