Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 由于比较字段,无法存储哈希密码_C#_Asp.net_Asp.net Mvc_Entity Framework_Hash - Fatal编程技术网

C# 由于比较字段,无法存储哈希密码

C# 由于比较字段,无法存储哈希密码,c#,asp.net,asp.net-mvc,entity-framework,hash,C#,Asp.net,Asp.net Mvc,Entity Framework,Hash,因此,我试图为我的应用程序建立一个登录系统,当用户进行注册时,我希望他写两次密码,以确认这是正确的密码。如果在注册后我没有散列我的用户密码,注册会顺利运行,但是在散列之后,我会在尝试将它们保存到我的sql数据库时得到一个验证,因为(我认为)它们不再匹配。我需要如何解决这个问题 用户模型 using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.

因此,我试图为我的应用程序建立一个登录系统,当用户进行注册时,我希望他写两次密码,以确认这是正确的密码。如果在注册后我没有散列我的用户密码,注册会顺利运行,但是在散列之后,我会在尝试将它们保存到我的sql数据库时得到一个验证,因为(我认为)它们不再匹配。我需要如何解决这个问题

用户模型

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Web;

namespace TimeTrackerProject.Models
{
    [Table("Users")]
    public class Users
    {
        [Key]
        public int Iduser { get; set; }
        [Required(ErrorMessage = "Email is required")]
        [RegularExpression(@"^([\w-\.]+)@((\[[0-9]{1,3]\.)|(([\w-]+\.)+))([a-zA-Z{2,4}|[0-9]{1,3})(\]?)$", ErrorMessage = "Please enter valid email.")]
        public String Email { get; set; }
        [Required(ErrorMessage = "Firstname is required")]
        public String Firstname { get; set; }
        [Required(ErrorMessage = "Surname is required")]
        public String Surname { get; set; }
        [Required(ErrorMessage = "Password is required")]
        [DataType(DataType.Password)]
        public String Password { get; set; }
        [Compare("Password", ErrorMessage = "Please confirm your password")]
        [DataType(DataType.Password)]
        public String ComfirmPassword { get; set; }
        [Required(ErrorMessage = "Function is required")]
        public String Function { get; set; }
        public Boolean Active { get; set; }






        [ForeignKey("RoleId")]
        public virtual Roles role { get; set; }
        public int? RoleId { get; set; }


    }
}
加密类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;


namespace TimeTrackerProject
{
    public static class Crypto
    {
        public static string Hash(string value)
        {
            return Convert.ToBase64String(
                System.Security.Cryptography.HMACSHA256.Create().ComputeHash(Encoding.UTF8.GetBytes(value))
                );
        }
    }
}
注册控制器方法

  public ActionResult Register(Users account)
    {
        if (ModelState.IsValid)
        {
            account.Password = Crypto.Hash(account.Password);
            account.ComfirmPassword = Crypto.Hash(account.ComfirmPassword);
            using (TimeTrackerEntities db = new TimeTrackerEntities())
            {
                db.Users.Add(account);
                db.SaveChanges();
            }
            ModelState.Clear();
            ViewBag.Message = account.Firstname + " was successfully registered.";


        }
        return View();
    }
编辑:
我得到的验证是:System.Data.Entity.Validation.DbEntityValidationException:一个或多个实体的验证失败

您错误地使用了ASP.NET MVC


您正在设计的模型是一个UI模型—一个
视图模型
,一个
数据传输对象
。选择:它符合以下特定标准:

  • 模型的存在是为了向用户展示和获取数据
  • 模型间接地表示数据库级数据
  • 该模型表示数据的传输
通常,在ASP.NET MVC中,我们的设计思想是使用
ViewModel
/
DTO
将数据从数据库传输到用户,或者反过来。
ViewModel
/
DTO
仍然可以有验证注释,并且仍然可以做与常规模型相同的事情,但是我们不会将从UI获取的模型直接传输到数据库,而是将其放在表示实际数据库记录的常规
模型中

如果您查看基本的ASP.NET MVC模板,您将看到以下实际操作:

公共类应用程序用户:IdentityUser
{
}
公共类RegisterViewModel
{
[必需]
[电邮地址]
[显示(Name=“电子邮件”)]
公共字符串电子邮件{get;set;}
[必需]
[StringLength(100,ErrorMessage={0}的长度必须至少为{2}个字符。”,MinimumLength=6)]
[数据类型(数据类型.密码)]
[显示(Name=“密码”)]
公共字符串密码{get;set;}
[数据类型(数据类型.密码)]
[显示(Name=“确认密码”)]
[比较(“密码”,ErrorMessage=“密码和确认密码不匹配。”)]
公共字符串ConfirmPassword{get;set;}
}
[HttpPost]
[异名]
[ValidateAntiForgeryToken]

例如,公共异步任务)为您管理A»B中的映射。

什么异常?请将您的问题包括在相关信息中。您的数据模型中没有
ComfirmPassword
属性。该属性仅在视图模型中显示。如果不想知道问题所在,请阅读异常。而且此外,您不必比较散列密码,只需比较明文密码即可。不要重新发明身份验证轮子,使用安全、经过良好测试的库。为什么要同时存储
密码
确认密码
(无论是否散列)?比较操作是UI功能,如果两者匹配,则可以存储该密码的单个哈希。这还有助于识别第二个可能的问题:不要将数据库模型对象用于UI,为UI使用一个单独的视图模型对象,其中有许多相同的字段,但视图模型对象有两个密码字段,而数据库模型对象只有一个。@pedroopes请不要使用您自己的加密。使用内置的库…哇,谢谢你的解释,我明白我现在做错了什么。将修改我的代码来实现这一点,谢谢!
public class ApplicationUser : IdentityUser
{
}

public class RegisterViewModel
{
    [Required]
    [EmailAddress]
    [Display(Name = "Email")]
    public string Email { get; set; }

    [Required]
    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Confirm password")]
    [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }
}

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
    if (ModelState.IsValid)
    {
        // Build an `ApplicationUser` (database model) out of the `RegisterViewModel`
        var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
        var result = await UserManager.CreateAsync(user, model.Password);
        if (result.Succeeded)
        {
            await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false);

            return RedirectToAction("Index", "Home");
        }
        AddErrors(result);
    }

    // If we got this far, something failed, redisplay form
    return View(model);
}