由于比较字段

时间:2017-08-07 11:12:42

标签: c# asp.net asp.net-mvc entity-framework hash

所以我试图为我的应用程序创建一个登录系统,当用户正在进行注册时,我希望他写两次密码来确认它是正确的密码。如果我在注册后没有哈希我的用户密码注册运行顺利但是在哈希之后我得到一个例子,同时试图将它们保存在我的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();
    }

修改 我得到的exeption是:System.Data.Entity.Validation.DbEntityValidationException:一个或多个实体的验证失败

1 个答案:

答案 0 :(得分:1)

您使用的是ASP.NET MVC错误。

您正在设计的模型是一个UI模型 - View ModelData-Transfer Object。请选择:它符合以下特定标准:

  • 该模型用于呈现和获取用户的数据;
  • 模型间接表示数据库级数据;
  • 该模型代表传输数据;

通常在ASP.NET MVC中,我们围绕这样的想法进行设计:我们使用ViewModel / DTO将数据从数据库传输到用户,或者相反。 ViewModel / DTO仍然可以使用验证注释,并且仍然可以执行与常规模型相同的操作,而不是将从UI 中传输的模型传输到数据库直接地,我们将它放在代表实际数据库记录的常规 Model中。

如果你看一下基本的ASP.NET MVC模板,你会看到这个精确练习

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);
}

所以我们在这里看到的是设计师构建了两个模型:ApplicationUser(它是DbContext的一部分并被映射到数据库)和一个RegisterViewModel(这是 DbContext的一部分,仅用于从客户端请求数据。

现在这不是必然直观,许多基本操作(例如Add»View)都是错误的(它们会自动添加内容到{ {1}})但这是管理它的最有效方法。

因此,在您的情况下,您可能想要创建相同的结构:构建DbContext模型,然后构建UserRegisterViewModelRegisterDTO /之间的差异ViewModel只是一种惯例:DTO是自解释的,而ViewModel只是一个'数据传输对象'。)

作为一个自由的注释:我经常构建DTO / ViewModel构造函数,将数据库模型作为参数并从中构建自己,你可以做同样的事情,然后反过来如有必要,或使用某种“映射器”(例如'Automapper')来管理A»B的映射。