c# - 如何在 ASP.NET Core 中的模型绑定时排除某些列
问题描述
我正在开发一个 ASP.NET MVC 项目,我必须将视图模型绑定到视图,但我不希望Tracking_Id
用户编辑该列,起初我通过使用来避免这种情况
[Bind("Id,ContratId,OrganizationName,ContratDate,StartDate,EndDate,DateUploaded,MediumName,LastEditorUserId")]
在我的后处理程序操作参数上,但我被迫使用视图模型类,我不能再这样做了,因为我只能在参数上使用该属性。问题是,如果我将呈现的网站输入字段value
和“名称”修改为contrat.Tracking_Id
并提交表单,那么它会更新该Tracking_Id
列,我担心这可能会导致安全问题。我还是这个框架的新手,在此先感谢。
Contrat
班级:
public class Contrat
{
[Key]
public int Id { get; set; }
public string ContratId { get; set; }
[Required]
public string OrganizationName { get; set; }
//[Required]
[DataType(DataType.Date)]
public DateTime ContratDate { get; set; }
[Required]
[DataType(DataType.Date)]
public DateTime StartDate { get; set; }
[DataType(DataType.Date)]
[Required]
public DateTime EndDate { get; set; }
[Required]
public DateTime DateUploaded { get; set; }
[Required]
public string documentPath { get; set; }
[DisplayName("Medium")]
public string MediumName { get; set; }
[ForeignKey("MediumName")]
public virtual Medium Medium { get; set; }
[DisplayName("Last Edited by")]
public string LastEditorUserId { get; set; }
[ForeignKey("LastEditorUserId")]
public virtual ApplicationUser User { get; set; }
public string TrackingID { get; set; }
}
视图模型:
public class ContratUpsertVM
{
[DisplayName("Contrat Document")]
public IFormFile documentPath { get; set; }
public Contrat contrat { get; set; }
}
解决方案
您可以使用自定义模型绑定来排除该TrackingID
属性。
CustomModelBinder.cs:
public class CustomModelBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
var model = new Contrat();
var properties = bindingContext.ModelMetadata.Properties;
foreach(var property in properties)
{
var valueresult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName + "." + property.Name).FirstOrDefault();
if (valueresult != null)
{
if(property.Name != "TrackingID")
{
if (property.ModelType == typeof(DateTime))
{
model.GetType().GetProperty(property.Name).SetValue(model, Convert.ToDateTime(valueresult));
}else if(property.ModelType == typeof(Int32))
{
model.GetType().GetProperty(property.Name).SetValue(model, int.Parse(valueresult));
}
else
{
model.GetType().GetProperty(property.Name).SetValue(model, valueresult);
}
}
}
}
bindingContext.Result = ModelBindingResult.Success(model);
return Task.CompletedTask;
}
}
然后在Contrat 属性上设置它。
public class ContratUpsertVM
{
[DisplayName("Contrat Document")]
public IFormFile documentPath { get; set; }
[ModelBinder(BinderType = typeof(CustomModelBinder))]
public Contrat contrat { get; set; }
}
推荐阅读
- python - 使用 TF1 读取使用 TF2 创建的 protobuf
- sql - SQL Server:按条件计数
- c# - C# Tcp BeginAcceptTcpClient 抛出 ObjectDisposedException
- android - 无需电子邮件即可通过谷歌进行最简单的 android 应用程序 firebase 身份验证
- scheme - 是否可以根据要比较的数据生成相等函数?
- mysql - 删除除查询返回的行之外的所有行
- javascript - 获取从分配给它的函数内的事件侦听器返回的值
- python - 如何调试这个 Python 3.7 语法错误?
- swift - 如何在 Swift 的 MKMapView 中将搜索到的位置名称传递给 TextField?
- node.js - Docker 容器中的 NodeJS 14 无法连接到 Postgres DB(输入/输出 docker)