绕过模型验证控制器中? [英] bypassing model validation in controller?

查看:101
本文介绍了绕过模型验证控制器中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建我的数据库的ADO.NET模型。
创建一个新的控制器,CRUD(实体框架和使用我创建的ADO.NET实体模型)。

在我的数据库我有一个简单的用户表。该表中的一行密码将与SimpleCrypto(PBKDF2)密码加密的用户。

在我的ADO.NET Users.cs模型我已经添加以下​​验证:

  [必需]
[数据类型(DataType.Password)
[StringLength(20,MinimumLength = 6)]
[显示(NAME =密码)]
公共字符串密码{搞定;组; }

这与jQuery与验证的浏览器。
但在我的控制,我加密密码,然后密码字符串,便一路超过20个字符的lenght。

  VAR密码=新SimpleCrypto.PBKDF2();
VAR encryptedPass = crypto.Compute(user.password的);user.password的= encryptedPass;
user.PasswordSalt = crypto.Salt;_db.Users.Add(用户);
_db.SaveChanges();

和这给了我和验证失败的一个或多个实体。 - 误差

我可以通过用户复制到变种NEWUSER,然后将那里所有的属性,但不存在绕过在这种情况下,模型验证一个更简单的方法

编辑:如果我删除密码道具的验证模型,然后一切正常。因此,它是给我的错误,因为我改变从6-20个字符长度的密码,因为在控制器中的加密+100 lengt字符验证。

编辑:插入到这个问题的完整的控制器部分

  [HttpPost]
公众的ActionResult创建(用户用户)
{
    如果(!ModelState.IsValid)
    {
        返回查看();
    }
    如果(_db.Users.FirstOrDefault(U => u.Email == user.Email)!= NULL)
    {
        ModelState.AddModelError(,用户已存在于数据库!);
        返回查看();
    }    VAR加密=新SimpleCrypto.PBKDF2();
    VAR encryptedPass = crypto.Compute(user.password的);    user.password的= encryptedPass;
    user.PasswordSalt = crypto.Salt;    _db.Users.Add(用户);
    _db.SaveChanges();    返回RedirectToAction(指数,用户);
}


解决方案

如果我理解正确,你有一个密码字段的数据库表。结果
根据你的模型该密码字段为20个字符长的结果。

  [StringLength(20 MinimumLength = 6)]

和要插入大于20个字符的值。结果
如果实体框架没有阻止你,那么你会得到一个数据库错误。(实体框架并不知道有你的数据模型和数据库之间的不匹配,并没有想通过采取推嵌件的风险)
结果
然而,我认为你彪指定您的视图模型一个客户方验证规则,而不是数据库的长度约束。结果
我希望你明白为什么这是一个令人困惑的设置。结果

我的建议是要么分裂您的视图模型和模型,以便可以发布视图模型与最大长度20的未加密的密码,你可以转换到模型密码长度100搜索结果
如果您发现太多的麻烦,您可以创建当您发布它,将其转换为在控制器密码属性你从HTML设置未映射密码属性。结果
你的类可以是这样的:

 公共类RegisterModel
{
    [需要]
    公共字符串用户名{获得;组; }    [需要]
    [NotMapped]
    [StringLength(20,MinimumLength = 6)]
    [显示(NAME =密码)]
    公共字符串PlainTextPassword {搞定;组; }    [需要]
    [StringLength(300)] //这是可选
    [数据类型(DataType.Password)
    公共字符串密码{搞定;组; }
}

I have created an ADO.NET model of my database. Created a new controller with CRUD (entity framework and using the ADO.NET entity model I created).

In my database I have a simple Users table. The Password row in the table will hold the users passwords encrypted with SimpleCrypto (PBKDF2).

In my ADO.NET Users.cs model I have added following validation:

[Required]
[DataType(DataType.Password)]
[StringLength(20, MinimumLength = 6)]
[Display(Name = "Password")]
public string Password { get; set; }

That works with jQuery in the browser with validation. But in my controller I am encrypting the Password, and then the Password string will be way more than 20 chars in lenght.

var crypto = new SimpleCrypto.PBKDF2();
var encryptedPass = crypto.Compute(user.Password);

user.Password = encryptedPass;
user.PasswordSalt = crypto.Salt;

_db.Users.Add(user);
_db.SaveChanges();

And this gives me and "Validation failed for one or more entities."-error.

I can copy the user over to a "var newUser" and then set all the properties there, but isn't there a easier way to bypass the model validation in this case?

EDIT: If I remove the validation of the Password prop in the model then everything works. So it is the validation that gives me the error because I alter the Password from 6-20 length chars to +100 lengt chars because of the encryption in the controller.

EDIT: Complete controller section inserted to this question.

[HttpPost]
public ActionResult Create(Users user)
{
    if (!ModelState.IsValid)
    {
        return View();
    }
    if (_db.Users.FirstOrDefault(u => u.Email == user.Email) != null)
    {
        ModelState.AddModelError("", "User already exists in database!");
        return View();
    }

    var crypto = new SimpleCrypto.PBKDF2();
    var encryptedPass = crypto.Compute(user.Password);

    user.Password = encryptedPass;
    user.PasswordSalt = crypto.Salt;

    _db.Users.Add(user);
    _db.SaveChanges();

    return RedirectToAction("Index", "User");
}

解决方案

If i understand correctly you have a database table with a password field.
According to your model this password field is 20 characters long

[StringLength(20, MinimumLength = 6)]

And you want to insert a value greater then 20 characters.
If entity framework did not stop you then you would get a database error.(Entity framework doesn't know there is a mismatch between your data model and the database and it doesn't wanna take the risk of pushing the insert through)

I assume however that you ment to specify a clientSide validation rule on your viewmodel and not a length constraint on the database.
I hope you see why this is a confusing setup.

My advice would be to either split your viewModel and model up so you can post a viewModel with unencrypted password of maxlength 20 that you can convert to a model password with length 100.

If you find that too much hassle you could create an unmapped password property which you set from html when you post it and you convert it to the password property in your controller.
Your class could look like this :

public class RegisterModel
{
    [Required]
    public string UserName { get; set; }

    [Required]
    [NotMapped]
    [StringLength(20, MinimumLength = 6)]
    [Display(Name = "Password")]
    public string PlainTextPassword { get; set; }

    [Required]
    [StringLength(300)]//This is optional
    [DataType(DataType.Password)]
    public string Password { get; set; }
}

这篇关于绕过模型验证控制器中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆