我对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的新手,所以我很感激任何帮助。
答案 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
}
我认为这和我可以解决的问题一样。希望它有意义。