Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.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
Asp.net mvc 将模型传递到视图并返回到新控制器_Asp.net Mvc - Fatal编程技术网

Asp.net mvc 将模型传递到视图并返回到新控制器

Asp.net mvc 将模型传递到视图并返回到新控制器,asp.net-mvc,Asp.net Mvc,我制作了一个密码重置控制器,它接受GUID查询字符串。正如您在下面的代码中所看到的,我的控制器检查我的数据库中是否存在GUID值,然后将user返回到具有属性name和userId的视图 [HttpGet] public ActionResult RetreivePass(string ac) { MySqlContext db = new MySqlContext(); PwRetreival PwRetreival = new PwRetreival(); Users

我制作了一个密码重置控制器,它接受GUID查询字符串。正如您在下面的代码中所看到的,我的控制器检查我的数据库中是否存在GUID值,然后将
user
返回到具有属性name和userId的视图

[HttpGet]
public ActionResult RetreivePass(string ac)
{
    MySqlContext db = new MySqlContext();
    PwRetreival PwRetreival = new PwRetreival();
    Users user = new Users();

    if (db.PwRetreival.FirstOrDefault(u => u.Token == ac) != null)
    {
        PwRetreival.uId = db.PwRetreival.Where(u => u.Token == ac).Select(u => u.uId).First();
        var Attributes = db.Users.Where(u => u.UserId == PwRetreival.uId).Select(u => new { u.Name, u.UserId }).FirstOrDefault();
        user.Name = Attributes.Name;
        user.UserId = Attributes.UserId;
        return View(user);
    }

    return RedirectToAction("Index", "Home");
}
在我看来,情况是这样的:

<p>Hello @Model.Name</p>

@using (Html.BeginForm(FormMethod.Post))
{
    <p>Change password</p>
    @Html.TextBoxFor(u => u.Password)
    <p>
        <button type="submit">Register</button>
    </p>
}
不幸的是,我的问题是,参数(Name和UserId)在提交时没有随模型返回给控制器。因此,我只有密码,我不能使用任何东西,因为我不能告诉我的控制器将更新的密码放在哪里

我错过了什么吗

为方便起见,我的型号如下:

public class Users
{
    [Key]
    public int UserId { get; set; }
    public string Email { get; set; }
    public string Password { get; set; }
    public string Name { get; set; }
    public short EmailConfirmed { get; set; }
}

public class PwRetreival
{
    [Key]
    public int Id { get; set; }
    public int uId { get; set; } //FK to Users.UserId
    public string Token { get; set; }
}

确保将名称作为输入参数包含到表单中(如果用户不应该修改它,则隐藏):

@使用(Html.BeginForm(FormMethod.Post))
{
更改密码

@Html.HiddenFor(u=>u.UserId) @Html.TextBoxFor(u=>u.Password) 登记

}
因此,基本上,回发时希望检索的所有参数都必须作为表单中的输入字段或查询字符串参数包含

当然,您会意识到隐藏字段或查询字符串参数可以从外部修改,从而使其变得非常不安全。任何知道另一个用户的
UserId
的人都可以为他触发密码重置。为了实现安全的密码重置功能,您可能需要一些加密技术。例如,您可以使用对称加密算法加密
用户ID
,并在密码重置电子邮件中将加密值发送给客户端。然后,当表单发回时,可以在服务器上解密加密值,以提取原始客户端id和新密码。如果加密值被篡改,您将立即知道


另一种方法是在服务器上生成一些令牌,这些令牌将与您的用户关联并存储在后端。然后在密码重置电子邮件中将此令牌发送给客户端,当发回时,通过查看您的后端,您将知道原始用户是谁。使用服务器密码对此令牌进行签名也是一个好主意,以确保其未被篡改。

但这样做安全吗?最终,这个隐藏参数(userId)应该决定在数据库中更改哪个密码属性。不,当然它是不安全的。我更新了我的答案,提到这一点。为了使密码重置功能,你需要一些加密。我刚刚意识到。否则我怎么做呢?很明显,我想以负责任的方式构建它。你可以使用一些对称加密算法加密用户id,然后从客户端传递加密值,并在服务器上解密。我明白你的意思!但是,真的不能用更聪明的方式吗?
public class Users
{
    [Key]
    public int UserId { get; set; }
    public string Email { get; set; }
    public string Password { get; set; }
    public string Name { get; set; }
    public short EmailConfirmed { get; set; }
}

public class PwRetreival
{
    [Key]
    public int Id { get; set; }
    public int uId { get; set; } //FK to Users.UserId
    public string Token { get; set; }
}
@using (Html.BeginForm(FormMethod.Post))
{
    <p>Change password</p>
    @Html.HiddenFor(u => u.UserId)
    @Html.TextBoxFor(u => u.Password)
    <p>
        <button type="submit">Register</button>
    </p>
}