Missing HttpParameterBinding and ParameterBindingAttribute - asp.net-web-api

I'm investigating Web Api in ASP.NET vNext using the daily builds. In a web api 2x project, I use HttpParameterBinding and ParameterBindingAttribute in some situations (see http://bit.ly/1sxAxdk); however, I can't seem to find either in vNext. Do/will these classes exist? If not, what are my alternatives?
Edit (1-22-15):
I want to be able to serialize a complex JS object to a JSON string, put the JSON string in a hidden form field (say name="data"), submit the form, and then bind my parameter to that JSON object on the server. This will never be done by a human, but rather by a machine. I also want this very same mechanism to work if the JSON is sent directly in the request body instead of form data. I also need this to work for several different types of objects.
I've been able to accomplish this scenario in Web Api 2.2 in a few different ways, including a custom ModelBinder; however, I remember reading an MSFT blog post that suggested to use a ModelBinder for query string binding, formatters for request body, and HttpParameterBinding for more general scenarios. Is it okay to read the request body in a ModelBinder ASP.NET 5, or is there a better mechanism for that? If so, then case closed and I will port my ModelBinder with a few minor changes.
I'm not sure that IInputFormatter will work for me in this case either.

Here are two rough approaches
Approach 1:
A quick and dirty approach would be to start with a Dto model
public class Dto
{
public Serializable Result { get; set; }
public Serializable FromForm
{
get { return Result; }
set { Result = value; }
}
[FromBody]
public Serializable FromBody
{
get { return Result; }
set { Result = value; }
}
}
public class Serializable
{
}
And an action method
public IActionResult DoSomething(Dto dto)
{
// Do something with Dto.Result
}
Then write a custom model binder for Serializable, that just works with Request.Form this way you never actually read the body yourself, and Form only reads it if it of type Form.
The down side of this is that ApiExplorer will not provide correct details (but I think since this is none-standard you are going to be in trouble here anyways).
Approach 2
You can alternatively just use the code from BodyModelBinder and create a custom binder for Serializable type above, that first tries to get it from the Form, and if it fails tries to get it from the Body. The Dto class in that case is not necessary.
Here is some pseudo code
if (inputType is yourtype)
{
if (request.Form["yourkey"] != null)
{
Use Json.Net to deserialize your object type
}
else
{
fall back to BodyModelBinder code
}
}
With this approach you can make it generic, and ApiExplorer will say the way to bind the type is unknown/custom (we haven't decided on the term yet :) )
Note:
Instead of registering the model binder you can use the [ModelBinder(typeof(customBinder))] attribute to apply it sparingly.
Here is a link to the BodyModelBinder code.

There is a new [FromHeader] attribute that allows you to bind directly to http header values if that is what you need.
https://github.com/aspnet/Mvc/issues/1671
https://github.com/aspnet/Mvc/search?utf8=%E2%9C%93&q=fromheader

Related

Server-side validation

I am having trouble figuring out how to get server-side DbContext validation errors back to the client. I understand that Breeze has default validators that react to a few of the attributes such as Required, but what about all the other attributes? I could write a custom JavaScript validator for Breeze that will check on the client side, but I also need to check to make sure the entity is valid on the server-side.
For example, the application requires a Person to to have a valid email address. A malicious user comes along and gets an email address past the client and posts to the server with a data that would not pass the EmailAddress validator. Thus far my experience with Breeze is that the email address will save and not bubble up any DbContext Entity Framework errors.
Assuming the model below, what would be the best way to get any entity validation errors?
public class PeopleContext : DbContext
{
public PeopleContext()
: base("name=ConnectionString"){ }
public DbSet<Person> People { get; set; }
}
public class Person
{
public int PersonId { get; set; }
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
[EmailAddress]
[Required]
public string Email { get; set; }
}
UPDATE 1:
Here are some instructions to re-create the issue that I am experiencing.
Follow the instructions to create the "Todo" sample (http://www.breezejs.com/documentation/start-nuget)
Add a new custom validator to the BreezeSampleTodoItem.cs file:
[AttributeUsage(AttributeTargets.Property)]
public class CustomValidator : ValidationAttribute
{
public override Boolean IsValid(Object value)
{
string val = (string)value;
if (!string.IsNullOrEmpty(val) && val == "Error")
{
ErrorMessage = "{0} equal the word 'Error'";
return false;
}
return true;
}
}
Decorate the Description field with the new custom validator:
[CustomValidator]
public string Description { get; set; }
Add the proper usings of course (System and System.ComponentModel.DataAnnotations).
Run the project.
In one of the description fields type "Error" and save.
This is where I would expect to see an error come up through Breeze, or even an DbEntityValidationException be thrown from Entity Framework. I have tried on 2 separate computers with the same result. The entity saves to the database as if there were no error. In fact, if you put a breakpoint anywhere inside IsValid method of the custom validator you will see that its not even being called.
As of Breeze v 0.78.1 all registered DbContext server side validations will now execute during an EntityManager SaveChanges call. Any exceptions encountered will cause the save to rollback, and any validation errors to be serialized back to the Breeze client.
Note that this functionality is not yet supported for older ObjectContext ( as opposed to DbContext) based EF models.
And ... thanks to adamlj for discovering this issue and suggesting the solution.
I'm not sure what you mean by
get server-side DbContext validation errors back to the client
You could mean that you want the validation error messages to be sent to the client. But the rest of your question suggests that you want to know (a) how to run a custom validation on the server and (b) how to acquire and run a corresponding JavaScript version of that validation on the client. I will address this interpretation of your question.
Server
The Entity Framework (which you're using in your example) automatically runs Data Annotation validation rules for you ... unless you've disabled that feature manually. If you create custom validation rules in the proper way, EF will run these as well. This post by Daniel Wertheim describes how to write such rules. I can't vouch for that post in every detail but it seems correct to me. It even defines a custom Email-validationattribute!
If authoring a custom Data Annotation validation rule seems too Baroque to you (as it often does to me), you can write and call your own validation logic in one of the BeforeSave... methods discussed in "Server-side Interception".
I think these are your best server options. On to the client ...
Client
Breeze registers client-side JavaScript validations to match certain of the server-side Data Annotations (e.g., Required and MaxLength) that come across the wire in the metadata. As I write, custom Data Annotations are not recognized nor included in the metadata and they have no out-of-the-box analogs on the client. If you want the client to prescreen your entities using these rules, you'll have to write your own corresponding JavaScript validators and register them for the pertinent entity types as discussed in the Validation documentation page.
If you have suggestions or better alternatives, we'd love to hear them.

ASP.NET Web API IQueryable<T> challenge

I want to use the following pattern in my controllers:
api/{controller}/{id}/{collection}
Example: api/customers/123/addresses
But I want to return IQueryable Of T from the corresponding Get action. I want something like this (simplified):
public IQueryable<????> GetCollection(int id, string collection)
{
switch(collection)
{
case "addresses":
return _addresses.AsQueryable();
break;
case "orders":
return _orders.AsQueryable();
break;
default:
throw new Exception(NotSupported);
}
}
Can this be done?
What would be the recommended approach?
#SLacks is correct that you should return IQueryable<object> or IQueryable<someBaseType> if you can.
The error your getting is a function of the DataContract Serializer. So you have a few options.
Switch to an alternate xml serlializer that supports what you want.
Swtitch to a form of output that bypasses the serializer at issue (say JSON using JSON.net)
Teach the data contract serializer how to serialize your object using the
For the "teach" option, you can teach in two ways.
(A) leverage the [KnownType(typeof(...))] attribute. Here's a post on the KnownType attribute. It's for WCF but should get you started.
(B) use a data contract resolver. This post should get you started.
Expanding on what #Ebarr said, the easiest way to accomplish this is to update the various classes which you want to be able to return this way, and have them inherit from a common base class or interface.
Example:
[KnownType(typeof(Address))]
[KnownType(typeof(Order))]
public abstract class _BaseObject { }
public partial class Address : _BaseObject { }
public partial class Order : _BaseObject { }
Now you can have your controller method look like:
public IQueryable<_BaseObject> GetCollection(int id, string collection) {
switch(collection) {
case "addresses":
return _addresses.AsQueryable();
case "orders":
return _orders.AsQueryable();
default:
throw new NotSupportedException();
}
}
Note that the [KnownType] attribute is in System.Runtime.Serialization. You should also be aware that this method will result in exactly what you would expect with regards to JSON serialization - but XML serialization will generally result in tags which show your objects as the base class (because that's what you returned) rather than the sub-classes.
Just return the non-generic IQueryable.
Or IQueryable<object> via covariance.

The difference between object validation and persistence validation in DDD?

Right now, I have a domain entity named StyleBundle. This StyleBundle takes a list of Styles:
public class StyleBundle
{
public StyleBundle(List<Style> styles)
{
this.Styles = styles;
}
public IEnumerable<Style> Styles { get; private set;}
}
So, in my original design, a StyleBundle should never be created with an empty Style list. This was a rule that the domain experts basically said was good.
I wrote this using a guard clause in the constructor:
if (styles.Count() == 0)
throw new Exception("You must have at least one Style in a StyleBundle.");
which made sure I could not create StyleBundle in an invalid state. I thought an exception made sense here b/c a StyleBundle being created without at least one Style was exceptional in the system.
Of course, change came down the road during the rest of the project, and now it should be possible for a user to create a StyleBundle without Styles, but they should not be allowed to PERSIST a StyleBundle without Styles.
So now I'm looking at my guard clause and realizing that I can't have the exception thrown from the constructor anymore.
Moving forward, I have a Service/Application layer that my code-behinds interact with when they're working with StyleBundles. In my Service Layer, I have a StyleBundleService class, and that class exposes basic functionality to the UI... among them is "CreateStyleBundle".
It seems as if I'll have to have my Service Layer check to see if the StyleBundle does or does not have any Styles before it's persisted to the database, but something about this decision feels "wrong" to me.
Anyone run into a similar thing? Basically, the different between the state of an object being valid when "new'ed up" vs. the state of the same object when it comes to persistence?
Thanks!
Mike
I would add an IsValid method to your entity. This would check if the entity is currently in a valid state (in your case, check if there are styles).
This method can be called from your Repository to check if an entity may be persisted. You can add more rules to the IsValid method for specific entities and you can implement something like a collection of Validation errors is you want to throw a meaningful exception.
Expanding what Wouter said, plus handy BeforeSaving and BeforeDeleting methods:
public interface IDomainObject<T>
{
bool IsValid();
}
public interface IEntity<T> : IDomainObject<T>
{
}
public interface IAggregateRoot<T> : IEntity<T>
{
void BeforeSaving();
void BeforeDeleting();
}
public interface IAggregateRoot { //or simply IEntity depending on the model
bool IsValid();
}
public class StyleBundle : IAggregateRoot<T> {
return styles.Count() > 0
}
public class StyleBundleRepository : Repository<StyleBundle> {
}
public abstract class Repository<T> : IRepository<T> where T : class, IAggregateRoot<T> {
public T Save(T t)
{
t.BeforeSaving(); //for all AggregateRoots, maybe logging what the aggregate was like before the changes
if(!t.IsValid())
throw Exeception("Entity invalid");
EntityStore.Current.SaveChanges();
// "AfterSaving" here, i.e.: log how the entity looks after the update
}
}
Edit: I dont personally use the IsValid idea, I go with a full class of EntityValidationErrors where I can report back to the client what was wrong before attempting to save, things that shouldnt be null, shouldnt be empty (like your Styles etc)
There are multiple strategies:
Some developers prefer to create 2 methods in the entity itself, one called IsValid() which validates the entity in terms of business rules (general validation) and another one called IsValidForPersistence() which validates the entity for persistence.
Regarding IsValid() I prefer instead not to allow invalid state in the first place by validating all inputs, and to support invariants I use factory or builder.
you may check the link http://www.codethinked.com/thoughts-on-domain-validation-part-1
for some thoughts.
I know, this question is three years old, but seeing the current answer is something I like to respond to. We are talking about the domain data. Hence, there can't be a valid StyleBundle with 0 objects. I imagine, you have a frontend editor somewhere, were you create a "new" StyleBundle and have to add at least one style, before hitting the "save" button.
At this point in the frontend, you won't have a domain object. You may have a data transfer object, that will be send with a "CreateNewStyleBundle" command.
In my opinion, the domain object must be agnostic to persitance and should always be in a valid state. If you have to call a "IsValid" method, you circumvent the whole idea of having domain objects in the first place.
That's just my humble opinion.

MVC 3 passing entity as an Interface

I'm currently working on an MVC 3 project using Ninject as my DI, the business objects are stored in a separate assembly. I'm running into an issue with the controller parameters, when posting back for CRUD operations I'm getting the error "Cannot create an instance of an interface". I am aware that you can't create an instance of an interface, but it seems like the only way I can get around this is to use a custom model binder and pass the FormCollection through. This seems really messy and I want to keep as much type specific code out of the project as I can - hence interfaces everywhere and Ninject to DI the concretes. Not only does custom model binding seem messy - won't I also lose my DataAnnotations?
Some code to describe what I have:
public ActionResult Create()
{
// I'm thinking of using a factory pattern for this part
var objectToCreate = new ConcereteType();
return (objectToEdit);
}
[HttpPost]
public ActionResult Create(IRecord record)
{
// check model and pass to repository
if (ModelState.IsValue)
{
_repository.Create(record);
return View();
}
return View(record);
}
Has anyone run into this before? How did you get over it?
Thanks!
but it seems like the only way I can get around this is to use a custom model binder
A custom model binder is the correct way to go. And by the way you should use view models as action arguments, not domain models or interfaces.
Not only does custom model binding seem messy - won't I also lose my DataAnnotations?
I don't know why you think that a custom model binder would make things messy. For me it's a great way to separate mapping logic into a reusable class. And, no you will not lose DataAnnotations. They will work perfectly fine on the concrete instance that the custom model binder would return.
Data passed to controllers action are simply holders for values. There shouldn't be any logic in them so there is nothing to decouple from. You can use concrete types (e.g Record) instead of interface (IRecord)
I made the same simple mistake. Ninject injects parameters into your constructor, but you added parameters to the Index Controller action.
It should look like this:
public class HomeController : Controller
{
private IRecord _record;
public HomeController(IRecord record)
{
_record = record;
}
public ActionResult Index()
{
ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application. " +
_record .HelloWorld();
return View();
}
}
Make sense?

In Spring MVC 3, how do I bind an object to a query string when the query string parameters don't match up with the object fields?

A 3rd party is sending me part of the data to fill in my domain object via a query string. I need to partially fill in my domain object, and then have the user fill in the rest via a form. I don't have any control over the query string parameters coming in, so I can't change those, but I'd really like to be able to use Spring MVC's data binding abilities, rather than doing it by hand.
How can I do this?
To add some complication to this, some of the parameters will require extensive processing because they map to other objects (such as mapping to a user from just a name) that may not even exist yet and will need to be created. This aspect, I assume, can be handled using property editors. If I run into trouble with this, I will ask another question.
Once I have a partially filled domain object, passing it on to the edit view, etc. is no problem, but I don't know how to properly deal with the initial domain object population.
The only thing I have been able to come up with so far is to have an extra class that has it's properties named to match the inbound query parameters and a function to convert from this intermediary class to my domain class.
This seems like a lot of overhead though just to map between variable names.
Can you not just have the getter named differently from the setter, or have 2 getters and 2 setters if necessary?
private int spn;
// Standard getter/setter
public int getSpn() {
return spn;
}
public void setSpn(int spn) {
this.spn = spn;
}
// More descriptively named getter/setter
public int getShortParameterName() {
return spn;
}
public void setShortParameterName(int spn) {
this.spn = spn;
}
Maybe that is not standard bean convention, but surely would work?

Resources