I recall having to deal with this type of situation years ago and from what I can tell online, it really hasn't gotten any easier.
I have two possible scenarios. One, is where the user wants to see the number just input formatted with commas after exiting the input box. The other is where the user wants to actually enter the commas.
Both situations make validation and dealing with passing the data to the backend as a Decimal a bit more interesting. I realize this can be done through a variety of possibilities such as keyup/keydown/blur/focus events; modifying the jQuery validator with custom validation, etc. But this seems to imply a bunch of potential new functions and new places for things to go awry on different browsers. We've had tons of fun dealing with how these events, like blur/keyup react in different browsers and it can be a bit nightmarish.
Our current views use the HTML 5 . This facilitates validation and entry without a lot of coding. If possible, we'd like to keep using that type of input.
The user might also want to not be allowed to enter a decimal (for certain types of quantity inputs).
Also, the solution needs to work on both IE8 and Safari (for the iPad). Currently, we have a single view for all of our pages that happens to fit the iPad footprint.
Are there any elegant and simple solutions for dealing with this type of request?
Asp.Net MVC allows you to use jQuery unobtrusive validation which will take care of the heavy-lifting of cross-browser support for you.
You could decorate your view model property with a Remote attribute, which would then tell the browser validation scripts (again, without you having to write code) to call a controller/action for the field. Then, you create that controller/action and do your validation there (you can simple try to parse the number) and send back a message if things fail.
The reason I suggest this is simply for the reason that the remote validation is already a known, working thing and whatever you write on the server won't affect any client. You can be as fancy as you like in the validation without having to test JavaScript.
Here's an intro to remote validation - just don't be alarmed, there is a lot of text and the way the code is written makes it look more involved than it actually is.
Spin up a new project and you should have this going in under 15 minutes.
Best regards.
Edit
If you do want to go with a client-side solution, try something pre-built and community supported, such as autoNumeric.
Related
Being some random rails dev, and getting around all those backbone/underscore javascript stuff…
Backbone seems interesting, but in a functional point of view (I mean the way you can get your data back from the db and your page can be updated), I can't see any real good reason to move forward to backbone. I'm saying, compared to the RJS approach rails bring.
With backbone, more things happens on the client side; but can't see any fundamental difference besides this fact
Any backbone-evangelist's feedback appreciated
It's definitely going to be a matter of preference, but here's some rambling as to why you might want to go with something like Backbone over something like RJS.
RJS is great for when you just need to return code like $('#post_#{#post.id}').slideUp() or something like that. When you want the backend to be in control of the front-end directly. This does make sense for a lot of apps, for sure. But when you start getting into more complex stuff: change the post title, change the post body, change the post tags, change the post title in the 'recent posts' sidebar, etc. This can get difficult to maintain quick. If you change the markup subtly you can break all of your RJS. Also, using RJS, it's pretty difficult to change the whole page and keep the user sane (eg, you will break back buttons and generally stomp all over the state in the browser).
So, for bigger/more end-to-end applications, you can institute something like Backbone as a way to keep your code organized, and move the logic to handle the display of your data to the client. Some benefits:
You will put less load on your server, since the client will do a lot of rendering work.
You change some markup in a client side template, it's natural and simple to modify the corresponding Backbone.View if there are changes to make there, instead of at the bottom of potentially several controller actions in Rails.
You can easily handle navigation between multiple pages/states, and keep that logic on the client.
It's very easy and low-barrier to organize your javascript strictly into whatever makes sense for your app (eg, collections.js, models.js, views.js, or maybe app.js for smaller stuff, or maybe post_view.js, posts_collection.js... whatever you need)... again rather than having javascript spread into procedural chunks all over Rails.
If you have an application that lends itself well to being on a single page (eg, lots of shared elements like navigation/sidebars/etc between pages for example), then it's going to be a pretty good fit for something like Backbone.
Your Rails app can act more like an API which any number of front-ends can use - the Backbone one for the web, an iPhone app, and so on.
There are surely downsides, too. You have to write at least some of your application's view/controller logic in Java(/Coffee)Script, and you have to be careful, when you don't reload the page for long periods, not to cause memory leaks and javascript errors that can kill your app. When is it not about tradeoffs, right?
A high profile example of someone not using Backbone when it otherwise might have been considered a good idea can be found at this 37signals post about Basecamp Next (and the corresponding HN discussion).
Let me know if I can clarify anything here for you.
What is the preferred method (one that has minimal custom code and ideally is portable to planned future versions of MVC without extra widgets) to validate common datatypes (e.g. e-mail addresses, dates, phone numbers) at both the client and server?
MY RESEARCH
I'm going to list a few methods I've seen, approximately from worst to best (IMHO). I'm currently using the last method listed. I'll focus on e-mail validation in this post, to keep things clear.
REGEX AND/OR CUSTOM VALIDATION ATTRIBUTE
I know jQuery validate includes some common datatypes including e-mail, and additional plugins exist for download (e.g. integer, max words). So custom regex's here are not the right answer.
I know how to write a custom validator from scratch at server and client, and even to 'adapt' an existing client-side rule to a custom attribute when using the unobtrusive connector. http://bradwilson.typepad.com/blog/2010/10/mvc3-unobtrusive-validation.html
but it probably doesn't make sense for such a common type as e-mail address.
Nor, probably, to extend a regex rule, as per:
http://www.pagedesigners.co.nz/2011/02/asp-net-mvc-3-email-validation-with-unobtrusive-jquery-validation/
OVERRIDING STOCK DataType ATTRIBUTE VALIDATORS
.NET includes [System.ComponentModel.DataAnnotations.DataType(DataType.EmailAddress)]
This causes always-succeed validation at client or server, and is really only useful out-of-the-box for a tangential purpose of formatting display strings. Overriding the always-succeed validation is possible, as per:
http://weblogs.asp.net/srkirkland/archive/2011/02/15/adding-client-validation-to-dataannotations-datatype-attribute.aspx
MVC DATA VALIDATION EXTENSION (VIA NUGET)
A NuGet-downloadable validation extension was released several months ago, and I'm currently using it, but I was surprised to see that it did not leverage the existing DataAnnotations.DataType enum. It makes me wonder if there is some development divergence that I should be avoiding here.
http://weblogs.asp.net/srkirkland/archive/2011/02/23/introducing-data-annotations-extensions.aspx
Also, it doesn't include phone numbers or US phone numbers.
Any better method?
Have you know about ASP.NET MVC 3 Futures Validation attributes,
http://weblogs.asp.net/imranbaloch/archive/2011/02/05/new-validation-attributes-in-asp-net-mvc-3-future.aspx
Unless I'm missing something (which is very possible), it seems to me that custom validation has always violated DRY. In all the examples I've seen, even with the brand new Unobtrusive Client Validation introduced w/ MVC 3, we have to create .NET code for our server-side validation, and jQuery (or JavaScript code) for client-side validation.
I understand that there's no such thing as a .NET-to-jQuery translator that would facilitate DRY server/client validation, and I guess that would be the only way to have true DRY validation that works both server and client side.
But I would be perfectly content with having custom validation always performed on the server. The data needed to pass into custom validation (in my case) is usually limited to one or two fields, and the server-side logic is usually pretty quick, even if it has to hit the database.
Is there no OOTB mechanism for wiring up custom validation using attributes, then having your client side validation use Ajax to execute the validation server-side and respond to the client? Or, has someone come up with such a solution?
Or is it a matter of, in the end, the tradeoffs of repeating the custom validation is better than the issues introduced w/ always executing custom validation server side?
Thanks in advance.
AFAIK, there is nothing OOTB (Out Of The Box).
As for the tradeoffs - though violating DRY, you gain several things:
Immediate feedback to the user (improved usability)
No round tripping in case of validation errors (less load on server)
Of course, apart from violating DRY and opening yourself to those issue, you also end up with a larger payload to the client (extra javascript).
No one can tell you whether these tradeoffs are worth it - you need to decide what is right for your application, users and client.
OOTB: http://msdn.microsoft.com/en-us/library/system.web.mvc.remoteattribute(v=vs.98).aspx
You aren't really validating DRY here. The concept of DRY is a bit more nuanced than simple duplication of code. There are acceptable tradeoffs, especially when coupling concerns are taken into account.
When people ask this question, which is quite often if you search around, I usually refer them to the DDD concept of bounded concepts. Using [Remote] and forcing DRY when it comes to validation tends to bunch up tons of concerns in one place and merging the responsibilities of several layers. Business Logic vs. Persistence and Data Integrity Logic ( non nulls ).
#Darin Dmitrov says it pretty well in a lot of his answers he's made to this exact question. Validating that a required field is filled in is much different from making sure Sally has enough credit to make a purchase and should be treated much differently.
Client validation is best used for basic concerns and not be overloaded with more heavy operations. The impact on usability from client validation is really minimal. There is nothing "unusable" about posting a form and waiting for a refresh. It is more fluent but not anything that will make or break the success of your application.
I don't really share your concerns about violating the DRY principle in this case, but it looks like a couple other people have already discussed that.
However, your idea sounds a lot like the new remote validation feature that was added with MVC 3:
How To: Implement Remote Validation in MVC3
On the other hand, nothing is stopping you from having all of the built-in simple checks performed on the client side, and doing all of the heavy custom validation only when posting back to the server.
If I have a search box on my page I clearly do not want the user to input any code that may be dangerous.
However, I have a lot of data entry pages and each one needs to have ValidateInput(false) on the controllers.
I don't want to allow dangerous input, but I also don't want to handle this in each and every controller.
Is there a way that the default, and ugly, error .Net error message can be overwritten, or is there a uniform way of handling this across controllers.
EDIT
I think maybe I didn't ask the question correctly.
For every data entry page I have I have to turn of Input Validation. This becomes somewhat boring and cumbersome. Each time I accept input I need to HTMLEncode and then HTMLDecode later.
Is there a way to do this in one central place and automatically?
About output:
Here's an interesting post.
And another one from Steve Sanderson.
I just read that post some time ago - haven't tried myself.
Give some feedback how it turns out.
About input:
you could try to mess around with model binder and HtmlEncode values it takes.
ASP.NET and MVC don't allow HTML submissions by default. You have to actively enable this. See the ValidateInputAttribute for more information.
Also, even more important than not allowing HTML input is not displaying user submitted HTML when you create output. That's why all of the default generated views use Html.Encode, and why you should, too.
Update in response to edited question
Yes, it's possible (though probably not advisable) to turn off ValidateInput globally. Make a parent controller type, and put
[ValidateInput(false)]
...on the class.
Also, I don't recommend encoding input. If you allow users to input HTML, I'd store that as-is. Your web app might not be the only thing which queries your DB! In terms of filtering out "dangerous" HTML, that's extraordinarily difficult. I'd use a tested, third-party sanitization library.
I am sorry for possible misleading about the title, but I have no idea for a proper title.
Feel free to edit.
Anyway, I am using ASP.NET Web Forms, and maybe this isn't how web forms is intended to be used, but I like to construct and populate HTML elements manually. It gives me more control.
I don't use DataBinding and that kind of stuff. I use SqlConnection, SqlCommand and SqlDataReader, set SQL string etc. and read the data from the DataReader.
Old school if you like. :)
I do create WebControls so that I don't have to copy-paste every time I need some control, but mostly, I need WebControls to render as HTML so I can append that HTML into some other function that renders the final output with the control inside.
I know I can render a control with control.RenderControl(writer), but this can only be done in (pre)Render or RenderContents overrides.
For example.
I have a dal.cs file where is stored all static functions and voids that communicate with the database.
Functions mostly return string so that it can be appended into some other function to render the final result.
The reason I am doing like this is that I want to separate the coding from the HTML as much as I can so that I don't do <% while (dataReader.Read()) %> in HTML and display the data. I moved this into a CodeBehind.
I also use this functions to render in the HttpHandler for AJAX response.
That works perfectly, but when I want to add a control (ASP.NET Server control (.cs extension, not .ascx)) I don't know how to do that, so I see my self writing the same control as function that returns string or another function inside that control that returns string and replaces a job that would RenderContents do, so that I can call that function when I need control to be appended into a another string.
I know this may not be a very good practice.
As I see all the tutorials/videos about the ASP.NET MVC, I think it suite my needs as with the MVC you have to construct everything (or most of it) by your self, which I am already doing right now with web forms.
After this long intro, I want to ask how can I build my controls so I can use them as I mentioned (return string) or I have to forget about server controls and build the controls as functions and used them that way?
Is that even possible with ASP.NET Server Controls (.cs extension) or am I right when I said that I am not using it right.
To be clear, I am talking about how to properly use a web forms, but to avoid data binders because I want to construct everything by my self (render HTML in Code Behind).
Someone might think that I am appending strings like "some " + "string", which I am not. I am using StringBuilder for that so there's no slowness.
Every opinion is welcome.
You need to stop thinking in terms of "controls" and webforms. MVC is a completely different way of constructing applications.
I also hate the automatic renderers in WebForms, they produce horrible html that never makes any sense. However, you dont want to be writing your html in your codebehind and passing it around as strings, thats just nasty. Your presentation code is mixed in with your logic, AND youre writing HTML in c# strings!!!
So, MVC... Instead of "widgets" that do interacty things with codebehinds and postbacks, yours view ONLY display data and contain forms to allow you to post to the controllers.
Because of this, you can strongly type your views to a Type, and then access the data you pass to it from a controller via the Model property. The equivalent to UserControls are Partial Views (ViewUserControl) which can be used to modularise your rendering code for types. For example, you might make an Address partial to which you pass your Person's Address property every time you need it rendered. This way you aren't repeating html all over the place.
P.S. A single file for all your DAL?
I hope I never ever have to work on an app you wrote in this manner. If your application is string-heavy then something is wrong.
Agree with #sliderhouserules, the way you are using MVC framework is awful. You must forgot all your "old school" techniques.
You should never use SqlCommands, SqlReaders, etc. in the code of the pages. You should pass to the view only a model (e.g. View(bar)) and it will be better if you avoid usage of
ViewData["some magic string"] = bar
Every time when you will use "old school" technique 2 mans and 2 cats will be killed :).
Also it's better to use some ORM (Object-Relational Mapper) like Linq2sql, NHibernate, SubSonic, etc.
If you need in samples of good application design please look at SharpArchitecture. It has a very good architecture and implementation and may help a lot. It has one sample (with Northwind db) and one more sample will be added soon.
Also look at CodeCampServer. It has very good architecture too.
It's better to look at the code of these projects instead of looking videos because existing videos can't demonstrate good sample of architecture, just a simple usage of functionality.
About server controls, you may use them if they can be used without 'runat="server"', like PlaceHolder. And you may create them too, but you shouldn't load any data in them directly. If you don't want to copy-paste html you should review your code and you should refactor it. Every duplicated code should be moved to MasterPages of UserControls (ascx ones).
And once more, please spend some time to look at these samples. You'll save your nerves and time in the future when you'll need to update the app or fix something. At the first look they can be hard to understand but this is only at the first look.
Hope this helps.
#lopkiju, I think that the MVC pattern would serve you much better than your current WebForms solution if you want that much control over the output HTML.
You can use Web Forms this way as you already do, but it is not designed to be used this way, so it will be a pain.
More detail
In my opinion, read some articles about the Separation of Concerns (also known as SoC) principle. If you apply it correctly, it can save you many-many headaches when you'll debug your app, and also for those people who you work with (eg. those who may have to read or modify your source code).
My other tip for you is this:
You are right that you shouldn't do things like <% while (dataReader.Read()) %> in your View code. But perhaps there are better ways to make it more elegant than your current way.
I think you should consider using some sort of ORM for these purposes. (LINQ to SQL, or even NHibernate.) If you get it, it will be much simpler. So much that you may not want to use DataReaders directly again. :-)
What I recommend for you
Simply, read the NerdDinner tutorial, and build the samle app by yourself step-by-step.
After that, try to build a similar app that serves a different purpose by yourself while applying the same rules and design that you applied to the tutorial.
I'm pretty sure you have the expertise to do it, and after actually doing something with it, you can pretty much get the feel of it.
The tutorial also explains and includes the principles I mentioned above, which will be very much use to you.
If you want the ASP.NET MVC path, you can set up controls as ASCX and they will simply be tags filled by the controller. It may not be old school enough for you, however.
You can create your full UI in code behind, if you so desire. This can include creating the HTML in routines.
But, I would recommend, if you are sticking with ASP.NET, reconsidering the bind model over the DataReader.Read() and output + loop. It is not only old style, it is highly inefficient and hard to maintain.
ASP.NET MVC does create a much looser ASPX, as it is just a view. And there is a much greater separation of code and UI. But it will not fit with the old school model either.
Have you considered using micro-templates? Dave Ward has a good example of of a client side data repeater that is uses micro-templates for layout after making a call to a page method. This sounds like this is more in the spirit of what you are trying to accomplish and can still be integrated nicely with WebForms.
The side effect will be that you will not rely on passing around HTML and can isolate your presentation from your logic.