没有密钥的MVC 3模型绑定

时间:2012-08-03 17:49:47

标签: asp.net-mvc key model-binding

我对ASP.NET MVC3模型绑定有疑问。如果我有一个班级,我试图用作模型,但我不想把键放在页面上,模型不会在POST上绑定。这是一个例子:

//Data Model
public class MyModel
{
    [Key]
    public string MyKey {get;set;} //Perhaps this is an ssn that I don't want on the form.
    public string MyValueToGet {get;set;} //This is the value I want the user to enter.
}

//Conroller code.
public ViewResult Index()
{
    MyModel model = new MyModel{ MyKey = "SecretInfo", MyValueToGet = "" };
    return View(new model);
}
public ActionResult Edit(MyModel model)
{
    repository.SaveChanges(model)
}

//View code.
@using(Html.BeginForm("Edit", "Home", FormMethod.Post))
{
    Enter a value: @Html.EditorFor(m => m.MyValueToGet)
    <input type="submit" value="Salve" />
}

所以我的问题是,在表单提交时调用Edit方法时,model为null。我可以通过将MyKey放在页面上的某个位置(可能作为隐藏字段)来解决这个问题,但如果它是某种敏感数据,这是不可接受的。有没有办法解决这个问题?我是MVC的新手,所以我很感激任何帮助。

2 个答案:

答案 0 :(得分:0)

另一种方法是在将id发送到客户端之前对其进行加密。查看此帖子,了解有关如何完成此操作的更多信息。 Asp MVC 3: Modifiy Values Sent to View

答案 1 :(得分:0)

创建另一个唯一但无意义的标识符,如(auto increment int)并使用它来绑定。

换句话说,将模型修改为:

public class MyModel
{
    [Key]
    public int ID {get; set;}
    public string MyKey {get;set;} //Now this can be sensitive, it doesn't matter because you no longer rely on it.
    public string MyValueToGet {get;set;} //This is the value I want the user to enter.
}

修改

我相信你最好的选择是更改MyModel对象,因为它的设计存在缺陷。大多数情况下的主键(我认为这是其中之一)应该是一个简单的自动递增整数,除了它作为表的键之外没有其他意义。

虽然Luke建议使用Session是一个可行的选择和一个可行的解决方案,但我个人会做类似于我在这里解释的事情,因为在我看来,它更像是'mvc方式'做事。

数据模型: 要么将当前模型更改为我上面建议的内容,要么,如果由于某种原因(断开依赖性或FK关系)不可行,请创建一个可用作连接或代理的新表,如果您将:

public class Proxy
{
    public int ProxyId {get;set;}
    public MyModel MyModel {get; set;}
}

显然,您必须做一些工作来填充此表,但是您可以使用它来从MyModel获取记录而无需直接访问MyKey属性。

在您的视图中直接使用您的数据模型并不是一种好习惯,因此您还要创建视图模型

public class MyModelViewModel
{
    public int ModelId {get; set;}
    public string ModelValueToGet {get; set;}
}

请注意,我们甚至不需要视图模型中包含敏感数据的密钥。

然后将视图键入viewModel,而不是数据模型,并为ModelId包含隐藏字段

@using(Html.BeginForm("Edit", "Home", FormMethod.Post))
{
    Enter a value: @Html.EditorFor(m => m.ModelValueToGet)
    @Html.HiddenFor(m => m.ModelId)
    <input type="submit" value="Save" />
}

现在您的控制器中有get方法

public ViewResult Index()
{
    //fetch the users record from the database 
    //if you're using the Proxy table, you'll want to write a LINQ query here
    //instantiate a viewModel and populate it's properties using the fetched record
    //remember, the viewModel.ModelId should be set to MyModel.ID or Proxy.ProxyId 
    //render the view
}

和post方法

public ViewResult Edit (MyModelViewModel viewModel)
{
    //fetch the users record from the database using viewModel.ModelId
    //If you're using the proxy table, you'll need to use that LINQ query again here
    //update the record you fetched with the new data the user just entered
    //you have complete control here of what gets updated and what stays the same
    //pass the updated record to the repository to save the changes.
    //redirect the user to be on their merry way
}

我认为这和我可以解决的问题一样。希望它有意义。