首页 > 解决方案 > 如何在 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; }
}

标签: c#asp.net-core

解决方案


您可以使用自定义模型绑定来排除该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; }
}

推荐阅读