What is the "best" way to handle entities validation in a Symfony3 REST application?
I know that I could use Form to do it and use its already existing validators (required, email type, repeat type, ...).
Might I also use the entity repository or another service to validate, serialize, unserialize my entities, thus having all the entity IN/OUT logic at the same place? But then how should I handle validation during both creation and update when data might not all be present?
Any thought?
Process the request through a Controller
Use a Form to process that request
Build custom validators or leverage existing on the FormClass
Using your controller (#1) handle PUT and POST and PATCH separately with unique actions.
Serialize/deserialize your request/response in the controller OR using a handler that the controller (#1, #4) hands the request off to.
Thanks for your inputs. I'll use the Doctrine Assert validators to handle the validation and the Symfony\Component\Validator\Validation class.
Regarding the Symfony3 documentation I think this is probably the best option.
https://symfony.com/doc/current/validation.html
another way, in my project, i not apply form for entity, maybe you need this way
Helper:
Base function :
Create action in controller
Update Action in controller
Related
As far as i understand it right JMSSerializerBundle's deserialisation does the same same as the symfony form component when a controller gets an post/put/patch request?
So either i create a symfony custom formType for e.g. an UserType and when i get a request i do something like $form->handleRequest($request) or i use JMSSerializerBundle to unserialize the request to a document/entity which gets finally stored.
Does anyone have experience with both methods? Currently i'm only familiar with the form way... Which one should i choose?
The Application i'm talking about is purely Restful, there are no twig html templates and FOSRestbundle is doing all the RESTful routing.
In our restfull API we usually use the Symfony Serializer component to handle the deserialization of entities, then the Symfony Validator component to ensure that the entities fulfill all the required conditions before pushing/updating them in database. Works pretty well, lighter than the form component.
Anyway The Form component would not be able to deserialize the json/xml so you'll have to use a serializer.
The benefit of the Symfony\Form component over the JMS Serializer is that the validation is done before deserialization which fits into PHP 7 strict typing. Example case - you pass an array instead of a string, JMS creates and object and the getter raises a \TypeError instead of a validation error from the validator.
It appears most of the WebAPI examples are returning some models (either domain models or particular view models).
When using domain models, we actually request more data than needed in the view from ajax calls, and then build our view models using JavaScript (assuming we are building a web app).
I tried using different view models for each page (view), which allow me to reduce the network footprint and return only the fields in need. But in the ApiController I would have too many GET methods. And it is impossible for us to predict the future need and build an API returning all kinds of view models.
I would like to mimic the Facebook Graph API and build a uri like:
http://... api/games/333?fields=id, name, price, imageUrl
And our user should be able to update the record with only these few fields.
A detailed description can be found in a google code blog entry: Making APIs Faster: Introducing Partial Response and Partial Update.
Some other posts here suggest this is beyond the current ability of ASP.NET WebAPI. Will ServiceStack or some other package help us achieve the goal?
Try this project: https://github.com/AnthonyCarl/ServiceStack.PartialResponse for the partial response side of the question
ServiceStack.PartialResponse.ServiceModel
Google Style Partial
Responses for ServiceStack.Net. Currently only the following Content
types are supported:
application/json
application/jsv
text/html
application/xml is NOT currently supported.
I wanted to implement this as a ServiceStack IPlugin, but I was unable
to figure out how to get the access I needed to the response DTO for
my approach. Currently, this is implemented as an IRequestContext
extension.
Providing Field Selectors
Field Selectors can be passed using the header or query string. By
default field selectors are combined form both. Duplicate field
selectors are reduced. The field selector is applied to all entries in
a list if the selector refers to a list.
There are a couple of options to implementing partial updates in ServiceStack. See this question about implementing PATCH requests for an approach that uses a request DTO with nullable values, and the PopulateWithNonDefaultValues and similar extension methods in ServiceStack, to take a PATCH-style request where the client can send any subset of fields in the request body. If a given field is not present in the request body, then that property of your domain object will not be updated.
If you really need to use a query string to specify the subset of fields that should be updated, then you can still use the approach described above, but add some code that first nulls out any values in the incoming request DTO object that are not named in the query string. Then you can again use PopulateWithNonDefaultValues to copy the remaining values to the domain object.
Also, to comment on another part of your post that is closely related to the recommendations I just gave:
When using domain models, we actually request more data than needed in the view from ajax calls...
Here is where a message-based design is helpful: model your request/response messages as separate DTO classes, instead of reusing and exposing your internal domain model objects. Among over benefits, you'll eliminate the problem of exposing unnecessary fields in your request/response models. Message-based design is one of the core concepts that drives ServiceStack's implementation. You could, though, achieve similar results with Web API or MVC. I highly recommend reading this article that discusses how this design works in ServiceStack.
You can use OData Protocol,look this example.
It's can use key:$select,$expand,$filter for search,select some fileds.
Most important,the ASP.NET WEB API has a SDK for support this.
When we are using EF (f.e.) via MVC, we can use ModelState.IsValid to detect a model can pass DataAnnotations metadata or not. But how can I use DataAnnotations metadata in a desktop (win-forms / wpf) application?
More:
In fact, I want to create an object same as ModelState (a dictionary that can save properties and messages associated with each). Then, wrap the DAL by a validation-layer, in VL use metadata to validate models, that the VL can be used in any project. I know I should use reflector, but I haven't any experience. Thanks to any help and suggestion.
If you are using EF 4.1/4.1 dbcontext, it has a built in validation API that can check Data Annotation rules as well as IValidatableObject.Validate. I'm not quite sure that I understand your goal, but if it is to have the validation in the data layer then you can just use what's built in. (Here's an overview http://msdn.microsoft.com/en-us/data/gg193959).
If you want your own validator that is separate from the data layer, then look at the System.ComponentModel.DataAnnotations namespace for methods and other logic you can leverage to do your own validation.
I need to allow users to submit a form value containing html in their text inputs. This is an internally-facing application so it's reasonably safe to do so. I have succesfully used the
[ValidateInput(false)]
attribute on the method in question, but this inhibits all model validation for the method/view model in question, but I only want to allow html in one of the TextBoxes and do not necessarily wish to write my own guard clauses for every other piece of model validation in the same method/view model, when I could would prefer to continue using Data Annotations for all of the other properties in the view model.
It's too bad I cannot apply the [ValidateInput(false)] to only a single property of my viewmodel. I would assume that I need to override mvc's default model validation, but I cannot find any documentation on how to do so. Every search yields results describing only how to write my own custom validation attributes, which isn't correct for the problem I'm trying to solve.
Thanks!
You would have to upgrade your aplication to ASP.NET MVC 3. There you have AllowHtmlAttribute, which you can use to disable input validation on property level. ASP.NET MVC 3 is backward compactible with ASP.NET MVC 2 so the upgrade should be easy.
Overview
I have a payment page where I allow the user to select a payment method, either credit card or check. I have a form for each of these payment methods. I did not want to create a separate page for each of these methods for UI purposes, so I use a [div] for each form and toggle their display with jQuery.
Problem
Each of the payment methods has its own set of validation rules. I want to be able to apply model validation to only the payment method that was selected and submitted by the user. In order to do validation, I am required to POST to the same controller action, so submitting to different actions is not an option.
Approaches
I have considered the following approaches:
Partial Validation based on incoming values, as described here: http://blog.stevensanderson.com/2010/02/19/partial-validation-in-aspnet-mvc-2/. My issue with this approach is the security implication, and as this is a relatively small app, I don't have a separate domain layer as the author of the article suggests.
Create separate models for each payment method, and then overload the controller [HttpPost] action with a different model parameter. I tried this but the compiler complains that the action is ambiguous, even though I have something like this
[HttpPost]
public ActionResult Pay(CreditCardPaymentModel model) {...}
[HttpPost]
public ActionResult Pay(CheckPaymentModel model) {...}
Use separate controller actions to handle the individual form posts and use TempData to set the validation messages and redirect back to the form page to display the messages. I really don't like this option as it feels clunky, and I don't like using TempData for anything other than simple messages.
I would welcome any suggestions on the best way to handle such a situation cleanly and efficiently.
I would go with option 2, as it gives you a nice, clean separation between payment models and concrete model classes (I always go for strongly typed solutions).
Option 2 will also be easy to unit test...
I'd go for the strategy 3.
When you toggle form views with jQuery you can also replace the post url of the form. This way it can easily be handled by different controller methods each with their own validation logic.
One other option (not the one I like) is to create a merged model for both payment option. Upon instantiation of that model you can probably easily distinguish what form was active. Or you can also set some hidden value with jQuery to indicate the active form view.
P.S. With #2 it is difficult to tell which model instantiation will work out until the framework attempts to instantiate one and if it fails another. This is not quite straightforward and the framework was not built to be that intelligent and bring some initiative into the process.