gpt4 book ai didi

c# - 选择性地将要绑定(bind)的模型字段列入白名单

转载 作者:行者123 更新时间:2023-11-30 22:18:45 26 4
gpt4 key购买 nike

(我意识到这个问题与 How to whitelist/blacklist child object fields in the ModelBinder/UpdateModel method? 非常相似,但我的情况略有不同,现在可能有更好的解决方案。)

我们公司销售基于网络的软件,最终用户可对其进行高度配置。这种灵 active 的本质意味着我们必须在运行时做一些通常在编译时完成的事情。

关于谁对大多数所有内容具有读取或读/写访问权限,有一些相当复杂的规则。

例如,以我们想要创建的模型为例:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace j6.Business.Site.Models
{
public class ModelBindModel
{
[Required]
[Whitelist(ReadAccess = true, WriteAccess = true)]
public string FirstName { get; set; }

[Whitelist(ReadAccess = true, WriteAccess = true)]
public string MiddleName { get; set; }

[Required]
[Whitelist(ReadAccess = true, WriteAccess = true)]
public string LastName { get; set; }

[Required]
[Whitelist(ReadAccess = User.CanReadSalary, WriteAccess = User.CanWriteSalary)]
public string Salary { get; set; }

[Required]
[Whitelist(ReadAccess = User.CanReadSsn, WriteAccess = User.CanWriteSsn)]
public string Ssn { get; set; }

[Required]
public string SirNotAppearingOnThisPage { get; set; }
}
}

在 Controller 中,手动“解绑”并不难。

var resetValue = null;
modelState.Remove(field);

pi = model.GetType().GetProperty(field);
if (pi == null)
{
throw new Exception("An exception occured in ModelHelper.RemoveUnwanted. Field " +
field +
" does not exist in the model " + model.GetType().FullName);
}
// Set the default value.
pi.SetValue(model, resetValue, null);

使用 HTML 帮助程序,我可以轻松访问模型元数据并抑制呈现用户无权访问的任何字段。

关键:我无法弄清楚如何在 CONTROLLER 本身的任何位置访问模型元数据以防止过度发布。

请注意,使用 [Bind(Include...)] 不是功能性解决方案,至少在没有额外支持的情况下并非如此。要包含的属性依赖于运行时(而非编译时),排除该属性不会将其从验证中删除。

ViewData.Modelnull
ViewData.ModelMetaDatanull

[AllowAnonymous]
[HttpPost]
// [Bind(Exclude = "Dummy1" + ",Dummy2")]
public ViewResult Index(ModelBindModel dto)
{
zzz.ModelHelper.RemoveUnwanted(ModelState, dto, new string[] {"Salary", "Ssn"});

ViewBag.Method = "Post";
if (!ModelState.IsValid)
{
return View(dto);
}
return View(dto);
}

关于如何从 Controller 访问模型元数据有什么建议吗?或者在运行时将属性列入白名单的更好方法?


更新:

我从这个相当优秀的资源中借用了一页:
http://www.dotnetcurry.com/ShowArticle.aspx?ID=687

模型看起来像这样:

[Required]
[WhiteList(ReadAccessRule = "Nope", WriteAccessRule = "Nope")]
public string FirstName { get; set; }

[Required]
[WhiteList(ReadAccessRule = "Database.CanRead.Key", WriteAccessRule = "Database.CanWrite.Key")]
public string LastName { get; set; }

类(class):

public class WhiteList : Attribute
{
public string ReadAccessRule { get; set; }
public string WriteAccessRule { get; set; }

public Dictionary<string, object> OptionalAttributes()
{
var options = new Dictionary<string, object>();
var canRead = false;

if (ReadAccessRule != "")
{
options.Add("readaccessrule", ReadAccessRule);
}

if (WriteAccessRule != "")
{
options.Add("writeaccessrule", WriteAccessRule);
}

if (ReadAccessRule == "Database.CanRead.Key")
{
canRead = true;
}

options.Add("canread", canRead);
options.Add("always", "be there");

return options;
}
}

并将这些行添加到链接中提到的 MetadataProvider 类中:

var whiteListValues = attributes.OfType<WhiteList>().FirstOrDefault();

if (whiteListValues != null)
{
metadata.AdditionalValues.Add("WhiteList", whiteListValues.OptionalAttributes());
}

最后是系统的核心:

public static void DemandFieldAuthorization<T>(ModelStateDictionary modelState, T model)
{

var metaData = ModelMetadataProviders
.Current
.GetMetadataForType(null, model.GetType());

var props = model.GetType().GetProperties();

foreach (var p in metaData.Properties)
{
if (p.AdditionalValues.ContainsKey("WhiteList"))
{
var whiteListDictionary = (Dictionary<string, object>) p.AdditionalValues["WhiteList"];

var key = "canread";
if (whiteListDictionary.ContainsKey(key))
{
var value = (bool) whiteListDictionary[key];
if (!value)
{
RemoveUnwanted(modelState, model, p.PropertyName);
}
}
}
}
}

最佳答案

回顾一下我对你的问题的解释:

  • 现场访问是动态的;一些用户可能能够写入某个字段,而另一些则不能。
  • 您有一个解决方案可以在 View 中控制它。
  • 您希望防止恶意表单提交发送受限属性,然后模型绑定(bind)器会将这些属性分配给您的模型。

也许是这样的?

// control general access to the method with attributes
[HttpPost, SomeOtherAttributes]
public ViewResult Edit( Foo model ){

// presumably, you must know the user to apply permissions?
DemandFieldAuthorization( model, user );

// if the prior call didn't throw, continue as usual
if (!ModelState.IsValid){
return View(dto);
}

return View(dto);
}

private void DemandFieldAuthorization<T>( T model, User user ){

// read the model's property metadata

// check the user's permissions

// check the actual POST message

// throw if unauthorized
}

关于c# - 选择性地将要绑定(bind)的模型字段列入白名单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15936641/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com