WebAPI Model [ModelBinder] with interface class while specifying implementationInterface vs Base classC# Interfaces. Implicit implementation versus Explicit implementationDifference between abstract class and interface in PythonTest if object implements interfaceInterface vs Abstract Class (general OO)What is the difference between an interface and abstract class?Why are C# 4 optional parameters defined on interface not enforced on implementing class?How to determine if a type implements an interface with C# reflectionHow should I have explained the difference between an Interface and an Abstract class?
How do you manage to study and have a balance in your life at the same time?
Can a system of three stars exist?
Is Chuck the Evil Sandwich Making Guy's head actually a sandwich?
New coworker has strange workplace requirements - how should I deal with them?
Is Borg adaptation only temporary?
Should we run PBKDF2 for every plaintext to be protected or should we run PBKDF2 only once?
Is it good practice to speed up and slow down where not written in a song?
Can authors email you PDFs of their textbook for free?
D Scale Question
Heuristic argument for the Riemann Hypothesis
Single vs Multiple Try Catch
Can my UK debt be collected because I have to return to US?
Cheap oscilloscope showing 16 MHz square wave
German equivalent to "going down the rabbit hole"
What is the point of building arithmetic circuit in a quantum computer?
Could these polynomials be identified?
How to run a command 1 out of N times in Bash
Colored grid with coordinates on all sides?
Are there consequences for not filing a DMCA (any country)
Blender - Alpha is Luminance equivalent
How were US credit cards verified in-store in the 1980's?
meaning of "educating the ice"?
Can UV radiation be safe for the skin?
Datasets of Large Molecules
WebAPI Model [ModelBinder] with interface class while specifying implementation
Interface vs Base classC# Interfaces. Implicit implementation versus Explicit implementationDifference between abstract class and interface in PythonTest if object implements interfaceInterface vs Abstract Class (general OO)What is the difference between an interface and abstract class?Why are C# 4 optional parameters defined on interface not enforced on implementing class?How to determine if a type implements an interface with C# reflectionHow should I have explained the difference between an Interface and an Abstract class?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
Is it possible to pass into the ModelBinder which implementation you want to use inline?
Given the following definitions:
public interface ISomeInterface
string MyStringget;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;
Given this route in asp.net mvc core:
public ActionResult InterfaceWithInlineImplementation([ModelBinder(typeof(SomeBinder))]ISomeInterface SomeInterface)
//Return actionresult
I do not want a different ModelBinder class for each implementation rather I would like each route to specify which implementation inline.
So something like:
[UseImplementation(SomeInterfaceImplementation_One)]
public ActionResult InterfaceWithInlineImplementation([ModelBinder(typeof(SomeBinder))]ISomeInterface SomeInterface)
Or:
public ActionResult InterfaceWithInlineImplementation([ModelBinder(typeof(SomeBinder), ConcreteType = SomeInterfaceImplementation_Two )]ISomeInterface SomeInterface)
This way the SomeBinder class can access which implementation is being requested in the BindModelAsync method of SomeBinder : IModelBinder class.
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;
asp.net-mvc interface asp.net-web-api2 interface-implementation
|
show 4 more comments
Is it possible to pass into the ModelBinder which implementation you want to use inline?
Given the following definitions:
public interface ISomeInterface
string MyStringget;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;
Given this route in asp.net mvc core:
public ActionResult InterfaceWithInlineImplementation([ModelBinder(typeof(SomeBinder))]ISomeInterface SomeInterface)
//Return actionresult
I do not want a different ModelBinder class for each implementation rather I would like each route to specify which implementation inline.
So something like:
[UseImplementation(SomeInterfaceImplementation_One)]
public ActionResult InterfaceWithInlineImplementation([ModelBinder(typeof(SomeBinder))]ISomeInterface SomeInterface)
Or:
public ActionResult InterfaceWithInlineImplementation([ModelBinder(typeof(SomeBinder), ConcreteType = SomeInterfaceImplementation_Two )]ISomeInterface SomeInterface)
This way the SomeBinder class can access which implementation is being requested in the BindModelAsync method of SomeBinder : IModelBinder class.
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;
asp.net-mvc interface asp.net-web-api2 interface-implementation
This really doesn't make sense. Restful API endpoints should be unique based on url. I shouldn't be able to pass aCustomer
to aUser
API just because it implements the same interface. To me this just looks like an overly complicated problem that only exists because it's poorly designed (as using an interface instead of a class provides no real benefit).
– Erik Philips
Mar 28 at 0:56
If the contract is broad enough, then yes? All interface/contract is going to do is guarantee certain properties and or methods are present. When you deserialize based on the Interface a customer/user won't exist but only the contract. The server can then determine if it wants to use a customer or user implementation.
– Watson
Mar 28 at 1:03
You can't deserialize to an interface. So you're telling a model binder to deserialize to a type, but only pass specific interface properties. Way way way overly complicated. Just bind to a base (non-abstract) base class that has all the properties of the interface. Now none of your issues exist.
– Erik Philips
Mar 28 at 1:04
Yes you can! In json you can deserialize to the interface. Which means stripping out anything that was added by the implementor. Whats left? Only the contract. If you define the contract and let the Client do its implementation and let the server do its implementation you can create rich implementation for the server and then the client can be super rich or super cheap.
– Watson
Mar 28 at 1:05
There is no such thing as an Instance of an Interface in .Net. So no you cannot have an instance of an interface. You can have run-time objects that derive from an interface and only passed as interfaces, but they are still concrete objects.
– Erik Philips
Mar 28 at 1:08
|
show 4 more comments
Is it possible to pass into the ModelBinder which implementation you want to use inline?
Given the following definitions:
public interface ISomeInterface
string MyStringget;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;
Given this route in asp.net mvc core:
public ActionResult InterfaceWithInlineImplementation([ModelBinder(typeof(SomeBinder))]ISomeInterface SomeInterface)
//Return actionresult
I do not want a different ModelBinder class for each implementation rather I would like each route to specify which implementation inline.
So something like:
[UseImplementation(SomeInterfaceImplementation_One)]
public ActionResult InterfaceWithInlineImplementation([ModelBinder(typeof(SomeBinder))]ISomeInterface SomeInterface)
Or:
public ActionResult InterfaceWithInlineImplementation([ModelBinder(typeof(SomeBinder), ConcreteType = SomeInterfaceImplementation_Two )]ISomeInterface SomeInterface)
This way the SomeBinder class can access which implementation is being requested in the BindModelAsync method of SomeBinder : IModelBinder class.
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;
asp.net-mvc interface asp.net-web-api2 interface-implementation
Is it possible to pass into the ModelBinder which implementation you want to use inline?
Given the following definitions:
public interface ISomeInterface
string MyStringget;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;
Given this route in asp.net mvc core:
public ActionResult InterfaceWithInlineImplementation([ModelBinder(typeof(SomeBinder))]ISomeInterface SomeInterface)
//Return actionresult
I do not want a different ModelBinder class for each implementation rather I would like each route to specify which implementation inline.
So something like:
[UseImplementation(SomeInterfaceImplementation_One)]
public ActionResult InterfaceWithInlineImplementation([ModelBinder(typeof(SomeBinder))]ISomeInterface SomeInterface)
Or:
public ActionResult InterfaceWithInlineImplementation([ModelBinder(typeof(SomeBinder), ConcreteType = SomeInterfaceImplementation_Two )]ISomeInterface SomeInterface)
This way the SomeBinder class can access which implementation is being requested in the BindModelAsync method of SomeBinder : IModelBinder class.
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;
asp.net-mvc interface asp.net-web-api2 interface-implementation
asp.net-mvc interface asp.net-web-api2 interface-implementation
asked Mar 28 at 0:26
WatsonWatson
6601 gold badge9 silver badges31 bronze badges
6601 gold badge9 silver badges31 bronze badges
This really doesn't make sense. Restful API endpoints should be unique based on url. I shouldn't be able to pass aCustomer
to aUser
API just because it implements the same interface. To me this just looks like an overly complicated problem that only exists because it's poorly designed (as using an interface instead of a class provides no real benefit).
– Erik Philips
Mar 28 at 0:56
If the contract is broad enough, then yes? All interface/contract is going to do is guarantee certain properties and or methods are present. When you deserialize based on the Interface a customer/user won't exist but only the contract. The server can then determine if it wants to use a customer or user implementation.
– Watson
Mar 28 at 1:03
You can't deserialize to an interface. So you're telling a model binder to deserialize to a type, but only pass specific interface properties. Way way way overly complicated. Just bind to a base (non-abstract) base class that has all the properties of the interface. Now none of your issues exist.
– Erik Philips
Mar 28 at 1:04
Yes you can! In json you can deserialize to the interface. Which means stripping out anything that was added by the implementor. Whats left? Only the contract. If you define the contract and let the Client do its implementation and let the server do its implementation you can create rich implementation for the server and then the client can be super rich or super cheap.
– Watson
Mar 28 at 1:05
There is no such thing as an Instance of an Interface in .Net. So no you cannot have an instance of an interface. You can have run-time objects that derive from an interface and only passed as interfaces, but they are still concrete objects.
– Erik Philips
Mar 28 at 1:08
|
show 4 more comments
This really doesn't make sense. Restful API endpoints should be unique based on url. I shouldn't be able to pass aCustomer
to aUser
API just because it implements the same interface. To me this just looks like an overly complicated problem that only exists because it's poorly designed (as using an interface instead of a class provides no real benefit).
– Erik Philips
Mar 28 at 0:56
If the contract is broad enough, then yes? All interface/contract is going to do is guarantee certain properties and or methods are present. When you deserialize based on the Interface a customer/user won't exist but only the contract. The server can then determine if it wants to use a customer or user implementation.
– Watson
Mar 28 at 1:03
You can't deserialize to an interface. So you're telling a model binder to deserialize to a type, but only pass specific interface properties. Way way way overly complicated. Just bind to a base (non-abstract) base class that has all the properties of the interface. Now none of your issues exist.
– Erik Philips
Mar 28 at 1:04
Yes you can! In json you can deserialize to the interface. Which means stripping out anything that was added by the implementor. Whats left? Only the contract. If you define the contract and let the Client do its implementation and let the server do its implementation you can create rich implementation for the server and then the client can be super rich or super cheap.
– Watson
Mar 28 at 1:05
There is no such thing as an Instance of an Interface in .Net. So no you cannot have an instance of an interface. You can have run-time objects that derive from an interface and only passed as interfaces, but they are still concrete objects.
– Erik Philips
Mar 28 at 1:08
This really doesn't make sense. Restful API endpoints should be unique based on url. I shouldn't be able to pass a
Customer
to a User
API just because it implements the same interface. To me this just looks like an overly complicated problem that only exists because it's poorly designed (as using an interface instead of a class provides no real benefit).– Erik Philips
Mar 28 at 0:56
This really doesn't make sense. Restful API endpoints should be unique based on url. I shouldn't be able to pass a
Customer
to a User
API just because it implements the same interface. To me this just looks like an overly complicated problem that only exists because it's poorly designed (as using an interface instead of a class provides no real benefit).– Erik Philips
Mar 28 at 0:56
If the contract is broad enough, then yes? All interface/contract is going to do is guarantee certain properties and or methods are present. When you deserialize based on the Interface a customer/user won't exist but only the contract. The server can then determine if it wants to use a customer or user implementation.
– Watson
Mar 28 at 1:03
If the contract is broad enough, then yes? All interface/contract is going to do is guarantee certain properties and or methods are present. When you deserialize based on the Interface a customer/user won't exist but only the contract. The server can then determine if it wants to use a customer or user implementation.
– Watson
Mar 28 at 1:03
You can't deserialize to an interface. So you're telling a model binder to deserialize to a type, but only pass specific interface properties. Way way way overly complicated. Just bind to a base (non-abstract) base class that has all the properties of the interface. Now none of your issues exist.
– Erik Philips
Mar 28 at 1:04
You can't deserialize to an interface. So you're telling a model binder to deserialize to a type, but only pass specific interface properties. Way way way overly complicated. Just bind to a base (non-abstract) base class that has all the properties of the interface. Now none of your issues exist.
– Erik Philips
Mar 28 at 1:04
Yes you can! In json you can deserialize to the interface. Which means stripping out anything that was added by the implementor. Whats left? Only the contract. If you define the contract and let the Client do its implementation and let the server do its implementation you can create rich implementation for the server and then the client can be super rich or super cheap.
– Watson
Mar 28 at 1:05
Yes you can! In json you can deserialize to the interface. Which means stripping out anything that was added by the implementor. Whats left? Only the contract. If you define the contract and let the Client do its implementation and let the server do its implementation you can create rich implementation for the server and then the client can be super rich or super cheap.
– Watson
Mar 28 at 1:05
There is no such thing as an Instance of an Interface in .Net. So no you cannot have an instance of an interface. You can have run-time objects that derive from an interface and only passed as interfaces, but they are still concrete objects.
– Erik Philips
Mar 28 at 1:08
There is no such thing as an Instance of an Interface in .Net. So no you cannot have an instance of an interface. You can have run-time objects that derive from an interface and only passed as interfaces, but they are still concrete objects.
– Erik Philips
Mar 28 at 1:08
|
show 4 more comments
1 Answer
1
active
oldest
votes
Use generics.
public class SomeBinder<TConcreteType> : IModelBinder
Then your signature becomes
public ActionResult InterfaceWithInlineImplementation(
[ModelBinder(typeof(SomeBinder<SomeInterfaceImpelemtation_One>))]ISomeInterface SomeInterface)
Then deserialization is:
JsonConvert.DeserializeObject<TConcreteType>(json)
However based on your last comment it sounds like you just need to Prevent overposting instead of this convoluted model binding.
So lets say the client knows that the server implementation has security methods and tries to match the signature hoping everything get deseriazled for example. Its being explicit as to what you're expecting. And you're explicitly expecting only the contract definition and nothing more.
Excerpt:
Mass assignment typically occurs during model binding as part of MVC. A simple example would be where you have a form on your website in which you are editing some data. You also have some properties on your model which are not editable as part of the form, but instead are used to control the display of the form, or may not be used at all.
public class UserModel
public string Name get; set;
public bool IsAdmin get; set;
So the idea here is that you only render a single input tag to the markup, but you post this to a method that uses the same model as you used for rendering:
[HttpPost]
public IActionResult Vulnerable(UserModel model)
return View("Index", model);
However, with a simple bit of HTML manipulation, or by using Postman/Fiddler , a malicious user can set the IsAdmin field to true. The model binder will dutifully bind the value, and you have just fallen victim to mass assignment/over posting:
So how can you prevent this attack? Luckily there's a whole host of different ways, and they are generally the same as the approaches you could use in the previous version of ASP.NET. I'll run through a number of your options here.
Continue to article...
It was either that or a custom attribute, this is much cleaner. Thank you!!!
– Watson
Mar 28 at 1:41
Finished updating based on your last comments. I hope you're only worried about over posting.
– Erik Philips
Mar 28 at 1:44
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55388441%2fwebapi-model-modelbinder-with-interface-class-while-specifying-implementation%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Use generics.
public class SomeBinder<TConcreteType> : IModelBinder
Then your signature becomes
public ActionResult InterfaceWithInlineImplementation(
[ModelBinder(typeof(SomeBinder<SomeInterfaceImpelemtation_One>))]ISomeInterface SomeInterface)
Then deserialization is:
JsonConvert.DeserializeObject<TConcreteType>(json)
However based on your last comment it sounds like you just need to Prevent overposting instead of this convoluted model binding.
So lets say the client knows that the server implementation has security methods and tries to match the signature hoping everything get deseriazled for example. Its being explicit as to what you're expecting. And you're explicitly expecting only the contract definition and nothing more.
Excerpt:
Mass assignment typically occurs during model binding as part of MVC. A simple example would be where you have a form on your website in which you are editing some data. You also have some properties on your model which are not editable as part of the form, but instead are used to control the display of the form, or may not be used at all.
public class UserModel
public string Name get; set;
public bool IsAdmin get; set;
So the idea here is that you only render a single input tag to the markup, but you post this to a method that uses the same model as you used for rendering:
[HttpPost]
public IActionResult Vulnerable(UserModel model)
return View("Index", model);
However, with a simple bit of HTML manipulation, or by using Postman/Fiddler , a malicious user can set the IsAdmin field to true. The model binder will dutifully bind the value, and you have just fallen victim to mass assignment/over posting:
So how can you prevent this attack? Luckily there's a whole host of different ways, and they are generally the same as the approaches you could use in the previous version of ASP.NET. I'll run through a number of your options here.
Continue to article...
It was either that or a custom attribute, this is much cleaner. Thank you!!!
– Watson
Mar 28 at 1:41
Finished updating based on your last comments. I hope you're only worried about over posting.
– Erik Philips
Mar 28 at 1:44
add a comment |
Use generics.
public class SomeBinder<TConcreteType> : IModelBinder
Then your signature becomes
public ActionResult InterfaceWithInlineImplementation(
[ModelBinder(typeof(SomeBinder<SomeInterfaceImpelemtation_One>))]ISomeInterface SomeInterface)
Then deserialization is:
JsonConvert.DeserializeObject<TConcreteType>(json)
However based on your last comment it sounds like you just need to Prevent overposting instead of this convoluted model binding.
So lets say the client knows that the server implementation has security methods and tries to match the signature hoping everything get deseriazled for example. Its being explicit as to what you're expecting. And you're explicitly expecting only the contract definition and nothing more.
Excerpt:
Mass assignment typically occurs during model binding as part of MVC. A simple example would be where you have a form on your website in which you are editing some data. You also have some properties on your model which are not editable as part of the form, but instead are used to control the display of the form, or may not be used at all.
public class UserModel
public string Name get; set;
public bool IsAdmin get; set;
So the idea here is that you only render a single input tag to the markup, but you post this to a method that uses the same model as you used for rendering:
[HttpPost]
public IActionResult Vulnerable(UserModel model)
return View("Index", model);
However, with a simple bit of HTML manipulation, or by using Postman/Fiddler , a malicious user can set the IsAdmin field to true. The model binder will dutifully bind the value, and you have just fallen victim to mass assignment/over posting:
So how can you prevent this attack? Luckily there's a whole host of different ways, and they are generally the same as the approaches you could use in the previous version of ASP.NET. I'll run through a number of your options here.
Continue to article...
It was either that or a custom attribute, this is much cleaner. Thank you!!!
– Watson
Mar 28 at 1:41
Finished updating based on your last comments. I hope you're only worried about over posting.
– Erik Philips
Mar 28 at 1:44
add a comment |
Use generics.
public class SomeBinder<TConcreteType> : IModelBinder
Then your signature becomes
public ActionResult InterfaceWithInlineImplementation(
[ModelBinder(typeof(SomeBinder<SomeInterfaceImpelemtation_One>))]ISomeInterface SomeInterface)
Then deserialization is:
JsonConvert.DeserializeObject<TConcreteType>(json)
However based on your last comment it sounds like you just need to Prevent overposting instead of this convoluted model binding.
So lets say the client knows that the server implementation has security methods and tries to match the signature hoping everything get deseriazled for example. Its being explicit as to what you're expecting. And you're explicitly expecting only the contract definition and nothing more.
Excerpt:
Mass assignment typically occurs during model binding as part of MVC. A simple example would be where you have a form on your website in which you are editing some data. You also have some properties on your model which are not editable as part of the form, but instead are used to control the display of the form, or may not be used at all.
public class UserModel
public string Name get; set;
public bool IsAdmin get; set;
So the idea here is that you only render a single input tag to the markup, but you post this to a method that uses the same model as you used for rendering:
[HttpPost]
public IActionResult Vulnerable(UserModel model)
return View("Index", model);
However, with a simple bit of HTML manipulation, or by using Postman/Fiddler , a malicious user can set the IsAdmin field to true. The model binder will dutifully bind the value, and you have just fallen victim to mass assignment/over posting:
So how can you prevent this attack? Luckily there's a whole host of different ways, and they are generally the same as the approaches you could use in the previous version of ASP.NET. I'll run through a number of your options here.
Continue to article...
Use generics.
public class SomeBinder<TConcreteType> : IModelBinder
Then your signature becomes
public ActionResult InterfaceWithInlineImplementation(
[ModelBinder(typeof(SomeBinder<SomeInterfaceImpelemtation_One>))]ISomeInterface SomeInterface)
Then deserialization is:
JsonConvert.DeserializeObject<TConcreteType>(json)
However based on your last comment it sounds like you just need to Prevent overposting instead of this convoluted model binding.
So lets say the client knows that the server implementation has security methods and tries to match the signature hoping everything get deseriazled for example. Its being explicit as to what you're expecting. And you're explicitly expecting only the contract definition and nothing more.
Excerpt:
Mass assignment typically occurs during model binding as part of MVC. A simple example would be where you have a form on your website in which you are editing some data. You also have some properties on your model which are not editable as part of the form, but instead are used to control the display of the form, or may not be used at all.
public class UserModel
public string Name get; set;
public bool IsAdmin get; set;
So the idea here is that you only render a single input tag to the markup, but you post this to a method that uses the same model as you used for rendering:
[HttpPost]
public IActionResult Vulnerable(UserModel model)
return View("Index", model);
However, with a simple bit of HTML manipulation, or by using Postman/Fiddler , a malicious user can set the IsAdmin field to true. The model binder will dutifully bind the value, and you have just fallen victim to mass assignment/over posting:
So how can you prevent this attack? Luckily there's a whole host of different ways, and they are generally the same as the approaches you could use in the previous version of ASP.NET. I'll run through a number of your options here.
Continue to article...
edited Mar 28 at 1:43
answered Mar 28 at 1:38
Erik PhilipsErik Philips
43.2k6 gold badges98 silver badges132 bronze badges
43.2k6 gold badges98 silver badges132 bronze badges
It was either that or a custom attribute, this is much cleaner. Thank you!!!
– Watson
Mar 28 at 1:41
Finished updating based on your last comments. I hope you're only worried about over posting.
– Erik Philips
Mar 28 at 1:44
add a comment |
It was either that or a custom attribute, this is much cleaner. Thank you!!!
– Watson
Mar 28 at 1:41
Finished updating based on your last comments. I hope you're only worried about over posting.
– Erik Philips
Mar 28 at 1:44
It was either that or a custom attribute, this is much cleaner. Thank you!!!
– Watson
Mar 28 at 1:41
It was either that or a custom attribute, this is much cleaner. Thank you!!!
– Watson
Mar 28 at 1:41
Finished updating based on your last comments. I hope you're only worried about over posting.
– Erik Philips
Mar 28 at 1:44
Finished updating based on your last comments. I hope you're only worried about over posting.
– Erik Philips
Mar 28 at 1:44
add a comment |
Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.
Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55388441%2fwebapi-model-modelbinder-with-interface-class-while-specifying-implementation%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
This really doesn't make sense. Restful API endpoints should be unique based on url. I shouldn't be able to pass a
Customer
to aUser
API just because it implements the same interface. To me this just looks like an overly complicated problem that only exists because it's poorly designed (as using an interface instead of a class provides no real benefit).– Erik Philips
Mar 28 at 0:56
If the contract is broad enough, then yes? All interface/contract is going to do is guarantee certain properties and or methods are present. When you deserialize based on the Interface a customer/user won't exist but only the contract. The server can then determine if it wants to use a customer or user implementation.
– Watson
Mar 28 at 1:03
You can't deserialize to an interface. So you're telling a model binder to deserialize to a type, but only pass specific interface properties. Way way way overly complicated. Just bind to a base (non-abstract) base class that has all the properties of the interface. Now none of your issues exist.
– Erik Philips
Mar 28 at 1:04
Yes you can! In json you can deserialize to the interface. Which means stripping out anything that was added by the implementor. Whats left? Only the contract. If you define the contract and let the Client do its implementation and let the server do its implementation you can create rich implementation for the server and then the client can be super rich or super cheap.
– Watson
Mar 28 at 1:05
There is no such thing as an Instance of an Interface in .Net. So no you cannot have an instance of an interface. You can have run-time objects that derive from an interface and only passed as interfaces, but they are still concrete objects.
– Erik Philips
Mar 28 at 1:08