是否可以仅从视图中跟踪模型更改的值。例如我有模型命名SampleModel
public class SampleModel
{
public int Id { get; set; }
public string ImageUrl1 { get; set; }
public string ImageUrl2 { get; set; }
}
如何仅检查控制器内更改的模型值?
是否可以仅从视图中跟踪模型更改的值。例如我有模型命名SampleModel
public class SampleModel
{
public int Id { get; set; }
public string ImageUrl1 { get; set; }
public string ImageUrl2 { get; set; }
}
如何仅检查控制器内更改的模型值?
控制器只知道来自请求的值。为了可靠地确定发生了什么变化,您需要将接收到的模型与从控制器操作逻辑或业务层逻辑中的 (repository/dao/dal/whatever) 获得的当前模型进行比较,只要更适合您的应用程序。
那么您可能需要某种形式的 DTO 模式。
例如,假设您希望“创建”和“编辑”操作具有不同的形式,那么您将执行以下操作:
新形式的一类:
public class NewSampleModelDto
{
[Required]
public string ImageUrl1 { get; set; }
public NewSampleModelDto() { }
public SampleModel ToModel()
{
return new SampleModel
{
ImageUrl1 = ImageUrl1
};
{
}
编辑表单的一类:
public class EditSampleModelDto
{
public int Id { get; set; }
[Required]
public string ImageUrl2 { get; set; }
// default constructor required for mvc model binding
public EditSampleModelDto() { }
// from model ==> dto
public EditSampleModelDto(SampleModel sampleModel)
{
Id = sampleModel.Id;
ImageUrl2 = sampleModel.ImageUrl2;
}
// from dto ==> model
public void UpdateModel(SampleModel sampleModel)
{
sampleModel.ImageUrl2 = ImageUrl2;
{
}
这使您能够灵活地为每个表单定义自定义验证逻辑。为了保持代码干燥,您可以创建一个基本 SampleModelDto,您可以在其中提供一个处理所有“模型 ==> dto”逻辑的构造函数。您还可以在此处将显示属性放在您的属性上。
无论如何,如果您在表单中使用这些 DTO 并将它们提交给您的控制器,您可以更自由地指定您的验证和更新逻辑。
如果我正确理解您想要什么,您可以为此目的使用 jQuery。例如,您可以为旧值创建隐藏的 div 并将其与当前值进行比较。如果当前值等于旧值,则不需要发布它。
<script>
$('oldValue').hide();
$(#ok).click(function())
{
var ImageUrl1;
if ($(newValue).val() != $(oldValue).val())
$post(.....)
});
</script>
<div class="oldValue">@Model.ImageUrl1</div>
<div class="newValue">........</div>
<button id="ok">ok</button>
尽管有一些选择,但没有本地方法可以做到这一点。因为您没有告诉我们您正在使用哪个持久性框架(ef、linq2sql、lightspeed、subsonic 等),所以我们不能说该框架是否有本地方式。
将起始模型序列化为表单字段。在服务器端对其进行反序列化并将其与 MVC 从 POST 中提供给您的模型进行比较。我通常使用 Newtonsoft.Json 和 UrlEncode 它。
对于每个模型字段,添加一个<input name="field_original" value="....">
然后在服务器端一次比较它们,例如Model.Name == Form["name_original"]
使用 jQuery 跟踪输入是否已更改,并将其保存为隐藏输入。例如if (Form["name_modified"] == "true")) { _save name_ }
使用 jQuery 做一些其他花哨的跟踪系统。有太多的选择。例如,您可以使用原始值向每个输入添加“data-originalValue”属性。然后在表单提交之前,您可以检查每个项目,并<input>
使用更改的属性的名称更新另一个项目。
从您的数据存储中获取您的模型所基于的原始实体。手动检查每个字段,并仅更新已更改的字段。
如果您的持久层支持更改跟踪(如 EF)
获取原始实体
使用模型中的值更新实体中的值
确保设置与现有值相同的值不会将该属性标记为已更改
保存实体(它应该只保存修改后的字段)
###上面#1的例子
<form ...>
<input type="hidden" name="OldModel" value="@Url.Encode(JsonConvert.SerializeObject(Model))"/>
<!-- the rest of your model fields --!>
@Html.TextBoxFor(m => m.Url)
控制器方法
using Newtonsoft.Json;
[HttpPost]
public ActionResult Save(MyModel model) {
var oldModel = JsonConvert.DeserializeObject<MyModel>(
HttpUtility.UrlDecode(Request.Form["OldModel"]));
if (oldModel.Url != model.Url) {
// code to save the Url field only
}
}