MVC 3 Remote Validation, problem with duplicate check in Edit view - asp.net-mvc-3

I am using remote validation to make sure that the email and username fields in a user class stop a user from entering a username and/or email that already exists within the database.
This works fine on the create view, however the obvious problem I run into in the edit view is that when I try save some changes for a given user - I get the same validation messages on the username and email saying that they already exist in the database! Therefore stopping me from editing anyone because their emails and usernames already exist.
I have been looking around and was surprised that I could not find a similar problem to mine. I have seen many examples of dupliate name/email/value validation on create pages but nothing on the inevitable problem that will arise in the Edit view.
Any hints/tips on a way around this would be greatly appreciated. Maybe there is a way to make the validation only work in the create view? Though ideally, I want the validation in the edit view, just excluding the user's own name and email in the validation checks.
Thanks in advance for any answers!

You should use view models. Those are classes which are specifically designed to meet the requirements of a view. Controller actions should take/pass only view models to views and never your domain models. So you will have two controller actions, one for inserting and one for editing, and two corresponding view models with their respective validation rules.

The way I've gotten around the problem is having 2 different validation methods; one takes a single argument (the user name) and one takes 2 arguments (the new user name, the original user name). The Edit method validates against the 2 argument method, where it looks for the new user name unless it matches the original user name.

Related

Why does Laravel group RESTful methods the way they do?

I'm brand new to Laravel and am working my way through the Laravel 6 from Scratch course over at Laracasts. The course is free but I can't afford a Laracasts membership so I can't ask questions there.
I've finished the first several sections of the course and am a little confused about some of the concepts around the whole RESTful idea. The instructor, who seems very good and experienced with Laravel, describes 7 methods that are going to be part of pretty much any CRUD (Create Read Update Delete) application (and most applications are CRUD in nature.) He says naming of these 7 methods should be consistent with this:
index - a list of all the resources in a collection e.g. all articles in a blog
show - display a specific resource from a collection e.g. a specific article in a blog
create - create a new instance of a resource e.g. add a new article to a blog
store - save a new instance of a resource to a data store like a database
edit - modify the contents of an existing resource e.g. change the title of an article
update - save the modified resource to a data store
destroy - remove a resource from a collection e.g. delete a blog article
I'm a little puzzled by this division of work into 7 separate methods. It seems to me that Create and Store belong together in a single method; ditto for Edit and Update. Creating a new record has two phases: displaying an empty form to gather up the data needed to construct a new article, then validating the data and storing it on the database. By the same token, changing an existing record consists of two phases: displaying the current data in a form and letting the user change what needs changing, then validating it and sending it to the database (or back to the user for corrections).
I would also argue that to be consistent with the approach they've used for create/store and edit/update, destroy should be divided into two methods, Destroy and Remove, where Destroy displays the full record that the user wants to remove with two buttons at the bottom: Delete and Cancel. Then, if the user clicks on Delete, they go to a Remove method that actually deletes the record f from the database.
I've been coding for a fair while and I've never seen a system where the user was allowed to delete any important record without first being shown the record and being asked if they're sure they want to delete it. Now, maybe that's fallen out of fashion and I didn't notice but it seems a pretty prudent thing to do.
So why are the methods what they are, at least as RESTful is implemented in Laravel?
It seems to me that Create and Store belong together in a single method
Well, Laravel generate all those methods thinking in a server-side rendered app. So in a SSR, before you store your data, you must be able to see a creation form.. that's why this create() function exists. The create(), normally, should return a view that will show the user the valid fields to create a resource, this is all done in a GET request. Then, when the users hit the "create"/"add" button, it will reach the store() method that will implement the logic to persist this data storing a new record in your database, this is done in a POST request.
The same goes for edit()/update().
I've been coding for a fair while and I've never seen a system where the user was allowed to delete any important record without first being shown the record and being asked if they're sure they want to delete it
That is because those validations are commonly implemented in the client-side, so, you do this with JS in your front-end, for validations of that kind you shouldn't hit the server.
So why are the methods what they are, at least as RESTful is implemented in Laravel?
Finally, for a RESTful API you don't need all of those methods. Just index, show, store, update and delete ones. If you just need this kind of methods in your controller, you could exclude the create/edit ones by adding the --api flag when creating your controller through Artisan. From the documentation:
API Resource Routes
// ...
To quickly generate an API resource controller that does not include the create or edit methods, use the --api switch when executing the make:controller command:
php artisan make:controller API/PhotoController --api

How to force Wicket "onchange" AJAX events to be triggered if fields fail validation conditions

The specific case I've got in mind is as follows: an AjaxFormComponentUpdatingBehavior("onchange") is added to a TextField in a form. The behavior verifies the text for certain conditions (either the model object or the form component model, doesn't matter), based on which it might display a message (or hide it, if it has already been shown).
The problem is, there are also validators added to the TextField. One of the possible (and likely) scenarios consists of the user typing in, first, a value that causes the message to be displayed by the AJAX request. If, then, he/she types in a value that doesn't pass validation, the message should disappear, but it does not.
Apparently, either the onUpdate() method for the AJAX behavior is not called at all, or I am failing in my attempts to insert a check for non-validated entries (I have tried to test for both null values and empty strings, to no avail; I have no idea what exactly Wicket's validators do to models when data is invalid).
I am wondering if someone who actually understands validators (or AJAX, actually) has any ideas on where the problem could be.
I can post edit and post code if someone tells me this is not a general issue tying validators and AJAX, but most likely a programming mistake. I still believe the former and thus I'll refrain from posting code sections, in order to keep the discussion on an API/theoretical frame.
Thanks.
When using an AjaxFormComponentUpdatingBehavior, if any of the IValidators fail their validation, onError() will be called instead of onUpdate(). Wicket will effectively prevent invalid user input from reaching the IModels in your components, so the component's ModelObject will not be changed at all. The invalid input will probably remain available by means of getInput()/getConvertedInput() (not sure if it will in an AJAX scenario, it sure is in a traditional form submission).
However, take into account that IFormValidators are not executed when using this mechanism. If you've got any, you might be interested in overriding getUpdateModel() so that AjaxFormComponentUpdatingBehavior will not bring maybe-invalid user input into your IModels, and set modelobjects manually when you're certain user input is valid.
Regarding your specific case, you could perform all the required logic in onError() (or rely on Models that will grab data from somewhere else), and just add the components that need refreshing to the AjaxRequestTarget. This is probably what's missing in your scenario.

cakePHP - creating new user account, several problems

I have two tables, users and tokens.
Each user have a activated field and each token have the {id, token, user_id, created} fields.
The way the app should work is:
On the creation, the app will -
make sure that the activated field is empty (to avoid manipulations to the submitted data).
a token will be created in the tokens table.
On update, the app will -
NOT create a new token.
NOT allow an update of any kind to the activated field.
check if a new email has been submitted, and if so: will create a new token and set the activated field to false.
I know how to activate the account through the controller and how to setup the router for that.
What I need is mainly the model configuration.
For example:
I think that the token creation should be done in the afterSave method, so - how do I determine if the method is called by an update or by a create operation?
Thanks for any help
yossi you can also specify the fields that should be saved from the form though - a whitelist of fields it is ok to save in you $this->save() call. That way you can stop a hacker passing an ID in the request, and you should just set it in the controller yourself then with $this->Token->id = whatever you have, I would personally use saveField ('activated) in conjunction with this (just saves a single field!). Fat models is best if you can but get it working first then refactor it if you have got stuck. Better than wasting lots of time writing perfect first time.
You question is unclear. If you have a default value for a field, then why not set it in the database rather than doing something in aftersave? If you need to do something that should be done only in certain circumstances, then write a custom method in your model to perform the tasks you want either on creation or update.
Edit
So, if your record has an id, then you know it exists in the database. So, the simple thing to do is (in any method) check to see if the model has an id field and that it is not empty. If it's empty, then you know that you are creating a record and you can do x task. If it isn't, then do y task.
if(isset($modelData['ModelName']['id']) && !empty($modelData['ModelName']['id'])){
//This is an update
} else {
//This is a new record
}

CakePHP Auth Loads Too Many Session Variables

Using CakePHP2.0 Beta I managed to write a custom login handler for my existing database schema. All's well, except that upon logging in I printed out the session variables stored and what Cake's Auth component did is store the entire record from the "Member" table (where my usernames+hashes come from) in session. It is storing an array with data fields that are totally irrelevant to the session. For instance it stores the date the member was created, their address, etc. All pretty useless information for me as I basically only need their ID and maybe username, name, email address.
The offending lines for me are found in: /lib/Cake/Controller/Component/AuthComponent.php line 512. It states,
$this->Session->write(self::$sessionKey, $user);
So my custom authenticate component returns $user and it throws this whole thing into the session. Now, I don't want to go about editing in the core libraries because this project is definitely going to be upgraded when 2.0 comes out. Is there any way to store less information in sessions? I want to keep this whole thing more lightweight.
Possible solution: Change my custom authentication component to only return the fields I need into the $user variable. Are there any concerns about what data I should/shouldn't be returning?
I've solved the problem using my "possible solution". In /app/Controller/Component/auth/MyController.php, I changed the "ClassRegistry::init($userModel)->find" method to have a parameter for 'fields' where I specify only the fields I need. Works like a charm.

Trying for a special Active Record Model which works as a unique WORM registry

I am trying to create a Model of a pretty special kind.
I just call it Emails. Containing fields like:
address
send_count
blocked
It is a registry of email addresses. Every record in other models that contain an email address should have a reference to a record in this model. That way I can block/ban and email address globally in my app and flag it in other ways.
If it was not generally frowned upon, I'd say the address should work much like the primary key. I can only be set on create and then never updated and it must be unique.
My problems implementing this (with a normal primary key) is how to handle cased where Emails is updated/created as an associated model via nested attributes. This is the most common situation since the email addressed look just like any other field to the users of the application.
They might be editing their account form and happen to change their email address. Phone should notice this and "find_or_create" an instance of itself instead of updating the address. Updating the blocked property on the other hand should be allowed.
Am I getting the gist of it across? Can anyone give me some advice on how to make the Model behave like this?
I have tried some variations of using validations and callbacks but I can seem to "replace self" with another existing record. Just setting all attributes (incl. id) to those of the existing record does not really make things work fully.
Any ideas would be helpful.

Resources