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.
Related
I was browsing the typo3 core Forms framework documentation but with no relevant answer to my requirements which are:
The form has to be displayed in a frontend overlay.
The filling process involves multiple steps where the user would be able to go back and forth.
The form fields must still be editable by a redactor.
I'm not sure about how the form framework behaves, so far I remember I think that multiple steps are configurable from the backend module but I don't know if it sends request to the controller after each step or if it sends everything only on submit.
I have an idea about how to implement it though, it's based on this question how to get a typo3 form framework html via ajax. Which would just let me provide the whole html content to the frontender and let him split the whole form into steps. The separation would be based on the addition of some special tags via the editor that would surround the fields you want in each step.
What do you think about that approach?
The form framework proceeds each form step seperately. So without developing your own form runtime, you have to keep proceeding every step seperate.
I see two possibilities:
1. Send each form step from frontend to the form controller and replace the response (html form) in the frontend.
That is the fast and easy way, as you use the existing form runtime.
Prepare a page which returns the rendered form as html
Fetch this page by JavaScript
Send the form data back to the given form action
The form controller proceeds the form with all its validators, rules and finishers and returns the next step, previous step, the current step with existing errors or the finishers response on success
Replace your form in the frontend with the already rendered html response of the form framework
The advantage of this way: Less effort and you can rely on the already existing validators, as you get an already validated response.
The disadvantage of this way --> it is more difficult to implement frontend validation, as you have a mix between frontend and server side validation.
2. Make the form framework kind of headless and work json based
In my opinion the better approach, but with a lot more effort to take.
You have to extend / overwrite the controller and the form runtime. This allows you more flexibility in handling the form by JavaScript and e.g. return the errors in a json object. It makes life easier when you want the form render and handle with a JS framework like react or vue.
To your question:
What do you think about that approach?
If I got it right, you want to keep ONE form step in the backend, but let the editor divide this form step into multiple steps by adding tags? You can try, but I don't see any real advantage in keeping the original form steps and proceed every step by sending the step to the controller and handle the response (like mentioned in 1.)
Summary:
In the past, I was thinking a lot about handling forms by JavaScript and came to the conclusion:
Keep the form framework's behaviour completely untouched with server side processing or make it frontend driven, with an own runtime. All mixtures between client and server side rendering will sooner or later run into bigger problems or at least a high effort. The form framework is pretty complex with a lot of possibilities, hook driven behaviour, etc. From my experience, you have to know it pretty good to develop without loosing control. In smaller projects with just one or two basic forms, I would try to avoid special cases with lots of JS. In bigger projects (with more budget), I would definitely go with my second mentioned approach (currently, I'm developing vue.js based rendering and handling of the form frontend). But these are just my five cents...
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
Recently I faced an ugly problem in my project when I begin the design of a complex View which have to handle with many data sources. The purpose of the View is to show data related to the profile of a Customer but this profile it's made of:Basic Info, Project involved, financial data and contact info. All that data must be grouped in the same View and must be updatable. Additionally to this, in the right pane of the view, there are a few of widgets pointing to other sources not related with the customer information.
My approach to solve this was:
Create an hybrid model which it's a mixed of various models like: personalInfoModel, cutomerProjectModel, financialInfoModel, and contactInfoModel. By the way, I am using Microsoft entity framework, so every model here match with an entity one to one.
With this hybrid model, I make the connection to the main View (let's say CustomerView) so in the first line of the view code you can see something like:
<%# Page ..... Inherits="...MyProject.Models.hybridCustomerModel"
Inside the main view I use:
<% Html.RenderPartial("UC_BasicInfo"); %>
<% Html.RenderPartial("UC_ProjectInfo"); %>
<% Html.RenderPartial("UC_FinancialInfo"); %>
<% Html.RenderPartial("UC_ContactInfo"); %>
This is because I want to simplify things a bit by mean of user controls for rendering of the main View.
Every User Control (ยจ*.ascx), is pointing to the hybrid model so I can make the binding in the controls of the forms without problem.
In the controller the things looks a little disordered. For every *.ascx there is an action's Method handling the "post request". But the initial loading or Get request, is made inside the only action method which match with the View Name: CustomerView.
For the purpose of usability and responsiveness I use jquery to make the post request.
But the problem is that I need to make a lot of work Mapping the hybrid model with the plain model involved in the Post Request, because the DATA layer receives only the model which maps with every entity created by the Model.
Finally, I am using: <% Html.RenderAction() %> for the Widgets at the right pane of the view in order to get data out of the hybrid model I am using.
I wanted to ask you if there is some different and better approach in this case?
I think there are a couple of approaches you could use to simplify this.
Firstly instead of the hybrid view, why not make up a view-model class. This will contain your hybrid data, but will be a pure poco class. Its much safer to bind to, as you control what fields are exposed.
Having a controller method for each ascx is not such a bad thing, but if you prefer one, and to wrap the page in one Form, you can either use button type="submit" (rather than input type=submit) or javascript to tell which button was pressed and which bit of the posted viewdata to map back to your EF classes.
Another approach, and given that you have already taken a dependency on javascript, this is the one I would favour:
I'd attempt to decouple the page into the independent partials, give each one a pair of controller methods (Get and Post) and assemble the page by requesting each partial with Ajax type calls. Your sticking point here will depend on whether an update in one cascades into others : if the interdependence is fixed and acyclic this will be pretty easy to resolve otherwise you might need to develop some sort of light messaging framework - or just allow some types of update to trigger a full page refresh.
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.
I'm finding it hard to find out helpful information about ASP.NET MVC's validation HTML helpers - Html.Validate and Html.ValidateFor.
Has anyone worked with these methods? what are they for?
see this post for an answer
If there are situations where you
don't actually want a validation
message to visually appear for each
field (i.e. by using
Html.ValidationMessage), but would
rather allow a summary to be the sole
source of validation error messages
(i.e. by using
Html.ValidationSummary), you still
need some way to "trigger" the
validation to occur for the specific
fields you want it to.
This can be achieved by using the
Html.Validate/Html.ValidateFor<>
methods within your view. Those
helpers won't render anything, but
will simply register the specified
field for client-side validation.