簡體   English   中英

指定實現的同時具有接口類的WebAPI模型[ModelBinder]

[英]WebAPI Model [ModelBinder] with interface class while specifying implementation

是否可以將要內聯使用的實現傳遞給ModelBinder?

給出以下定義:

public interface ISomeInterface
{
    string MyString{get;set;}
}

public class SomeInterfaceImplementation_One : ISomeInterface
{
    private string _MyString;

    public string MyString
    {
       get {return "This is implementation One " + _MyString ; }
       set { _MyString = value;  }
    }
}

public class SomeInterfaceImplementation_Two : ISomeInterface
{
    private string _MyString;

    public string MyString
    {
       get {return "This is implementation Two" + _MyString ; }
       set { _MyString = value;  }
    }
}

在asp.net mvc核心中給出以下路由:

public ActionResult InterfaceWithInlineImplementation([ModelBinder(typeof(SomeBinder))]ISomeInterface SomeInterface)
{
       //Return actionresult
}

我不想為每個實現使用不同的ModelBinder類,而是希望每個路由指定內聯哪個實現。

所以像這樣:

[UseImplementation(SomeInterfaceImplementation_One)]
public ActionResult InterfaceWithInlineImplementation([ModelBinder(typeof(SomeBinder))]ISomeInterface SomeInterface)
{

}

要么:

 public ActionResult InterfaceWithInlineImplementation([ModelBinder(typeof(SomeBinder), ConcreteType = SomeInterfaceImplementation_Two )]ISomeInterface SomeInterface)
    {

    }

這樣,SomeBinder類可以訪問SomeBinder:IModelBinder類的BindModelAsync方法中請求的實現。

public class SomeBinder : Microsoft.AspNetCore.Mvc.ModelBinding.IModelBinder
    {

        public Task BindModelAsync(Microsoft.AspNetCore.Mvc.ModelBinding.ModelBindingContext bindingContext)
        {
            if (bindingContext == null)
                throw new ArgumentNullException(nameof(bindingContext));

            string valueFromBody = string.Empty;

            using (var sr = new StreamReader(bindingContext.HttpContext.Request.Body))
            {
                valueFromBody = sr.ReadToEnd();
            }

            if (string.IsNullOrEmpty(valueFromBody))
            {
                return Task.CompletedTask;
            }

            var settings = new JsonSerializerSettings()
            {
                ContractResolver = new InterfaceContractResolver(), // Need requested implementation from InterfaceWithInlineImplementation() method

            }; 

            var obj = JsonConvert.DeserializeObject(valueFromBody, [**Need Requested Implementation from Method**], settings);
            bindingContext.Model = obj;


            bindingContext.Result = ModelBindingResult.Success(obj);


            return Task.CompletedTask;
        }

使用泛型。

public class SomeBinder<TConcreteType> : IModelBinder
{
}

然后你的簽名變成

public ActionResult InterfaceWithInlineImplementation(
  [ModelBinder(typeof(SomeBinder<SomeInterfaceImpelemtation_One>))]ISomeInterface SomeInterface)

然后反序列化是:

JsonConvert.DeserializeObject<TConcreteType>(json)

但是,根據您的最新評論,聽起來您只需要防止過度發布,而不是這種復雜的模型綁定即可。

因此,可以說客戶知道服務器實現具有安全性方法,並嘗試匹配簽名,以希望例如一切反序列化。 它對您的期望是明確的。 您顯然只期望合同定義,僅此而已。

摘抄:

質量分配通常在模型綁定期間作為MVC的一部分發生。 一個簡單的例子是您在網站上有一個正在編輯一些數據的表單。 您的模型上還具有一些屬性,這些屬性不能作為表單的一部分進行編輯,而是用於控制表單的顯示,或者可能根本不使用。

public class UserModel
{
  public string Name { get; set; }
  public bool IsAdmin { get; set; }
}

因此,這里的想法是,您只向標記呈現一個輸入標簽,但是將其發布到使用與呈現相同模型的方法中:

[HttpPost]
public IActionResult Vulnerable(UserModel model)
{
    return View("Index", model);
}

但是,通過簡單的HTML操作或使用Postman / Fiddler,惡意用戶可以將IsAdmin字段設置為true。 模型綁定器將忠實地綁定值,而您剛剛成為批量分配/過帳的犧牲品:

那么如何防止這種攻擊呢? 幸運的是,有很多不同的方法,它們通常與您在以前版本的ASP.NET中可以使用的方法相同。 我將在這里介紹您的許多選擇。

繼續文章...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM