I'm trying to get some User Controls I'm writing to perform their own server-side validation, checking the database to ensure that certain criteria are valid. In one case the control doesn't even accept any input, it just displayed some information based on database state.
I know the ASP.Net has its own validation framework, and I'm keen not to re-invent the wheel. However, I'd like the controls to check whether they're valid themselves (that seems more object oriented to me), rather than having to create custom validators on every page on which I place the controls. I've had a quick look at the IValidator interface, but this seems to be targeted at Validators, rather than the controls themselves. It seems cleaner to me to have the control itself check the entered data (where appropriate) and database state and report whether or not it is valid.
Is this possible in ASP.Net without re-writing the whole of the ASP.Net validation framework, or am I just trying to go about this in completely the wrong way?
It turns out I was close with the IValidator stuff, just missing the link to the Page.Validators collection. Here's a fully worked example:
http://www.codeproject.com/KB/custom-controls/selfvalidatingtextbox.aspx
Hard to believe how much time I spent looking for this yesterday!
Related
I'm working on a WebForms application that consists of a number of pages and each page contains a form which the user fills out. Each form corresponds to a part of an entity meaning that the data from one page/form populates a part of the entity's fields or its child entities' fields.
As an example: a Person's name and birth data is filled out on first page, health status on second page, family information on third page etc.
The data should of course be valid before continuing to the next page. My customer doesn't want to deal with jQuery or Javascript so this is ruled out. What is "best practice" for implementing validation in this case?
Entity Framework 4 is being used and most of the GUI controls are implemented in HTML and not by WebForms controls.
If you're using custom HTML for your inputs, then you're probably going to have to use some custom code for your validation. In your server-side form handler you can validate the inputs and render the page back to the user if something was invalid. The input checking could be as simple as:
if (string.IsNullOrWhiteSpace(FormCollection["someRequiredInput"])
You can iterate through all of your inputs, check them according to business logic, and perhaps build a list of errors. Then after the input checking, if the list of errors isn't empty, render the page back to the user with the errors added to a placeholder of some kind. If the list is empty, continue processing the form post.
Even if JavaScript wasn't ruled out, you'd still want to perform server-side validation. Never assume that the client-side code worked as intended or was even executed at all. Client-side validation isn't a security measure, it's just a better user experience. Server-side validation is the only real validation.
(So you may still be able to add client-side validation for that added UX touch, and if the client does indeed disallow JavaScript then they wouldn't see that and would just use the server-side validation instead. This is sometimes referred to as "graceful degradation" where you design a web application to still fully function, albeit with slightly less UX goodness, when the user disables client-side technologies.)
My customer don't want to deal with jQuery och[sic] Javascript so this is ruled out.
Good. Javascript is the wrong place to enforce validation. Any validation you do with javascript is merely a performance optimization. The only acceptable place to truly validate data is on the server.
That out of the way, .Net includes some handy Validation controls you can use. One of those controls is a CustomValidator, that is very easy to override and provide your own server-side code to enforce whatever rules you want. If you're using webforms, these controls are an obvious choice.
Since you have a multi-paged approach, you may also want to look into the Wizard control.
When creating dynamic controls based on a data source of arbitrary and changing size, what is the official way to track exactly how many controls need to be rebuilt into the page's control collection after a Postback operation (i.e. on the server side during the ASP.NET page event lifecycle) specifically the point at which dynamic controls are supposed to be rebuilt? Where is the arity stored for retrieval and reconstruction usage?
By "official" I mean the Microsoft way of doing it. There exist hacks like Session storage, etc but I want to know the bonafide or at least Microsoft-recommended way. I've been unable to find a documentation page stating this information. Usually code samples work with a set of dynamic controls of known numbers. It's as if doing otherwise would be tougher.
Update: I'm not inquiring about user controls or static expression of declarative controls, but instead about dynamically injecting controls completely from code-behind, whether they be mine, 3rd-party or built-in ASP.NET controls.
This greatly depends on the problem at hand, and the type of controls you're recreating. Are they all simple text boxes or various different complex custom user controls. the main thing here is: if you want your dynamic control to regain state after a post-back, you have to re-create it in the Init phase of a page life-cycle.
Anyway. There's nothing like a Microsoft way or Microsoft recommended way basically. When you're dynamically adding several simple controls of the same type a hidden field with a count would do the trick, but when you have several complex controls other ways would have to be used. You could still hidden fields and save control's full type strings in them (ie. System.Web.UI.WebControls.TextBox) and re-instantiate them. But think of an even more complex example of putting various controls on different parts in the page... And initializing them to a specific state. That would be a bit more challenging. Hence no Microsoft way... The recommended way is to recreate in Init phase. And that's it.
Everything can be solved, but sometimes one took a wrong direction in the UI and things could be done easier using a different approach.
Additional explanation
This state-full technique of ViewState that Asp.net uses is considered the worse culprit with web developers in general. That's why Asp.net MVC developers think the new framework is bliss since its much more suited to the state-less HTTP protocol. Me being one of them. :D
ASP.NET has a number of nice features regarding making data input pages:
Adding input controls is easy (<asp:...).
The system automatically generates member variable for the controls.
Post-backs automatically populate the members variable with the returned values.
and some not so nice bits
post-backs seem to be tied to JavaScript for even the simplest of cases. For instance, with statically defined pages, using only basic controls, that are known at compile time.
My questions:
Is is possible to get the first list without the second?
What features does that JavaScript give the user?
What does that JavaScript actually do?
What is the technical reasons that it's used even in trivial cases?
As it happens my assumption were in error: See here
It really depends on the types of controls you are trying to use here -- the only ones that implement javascript are those that can't natively cause a postback (ie, an input/submit button are the only two that can). If you are using a LinkButton, ImageButton, or anything that you set "AutoPostBack = true" on will turn javascript on in order to cause a postback.
Other controls can also potentially use javascript if they are more advanced such as the Calendar. The technical reason for using javascript here is to provide automated postback when the controls require more advanced server interaction -- think about it, a link is meant to only ever be a link and if we're trying to make it operate as a button we have to force it to do just that through javascript interaction.
So that being said, yes you can definitely use ASP.NET without it having javascript you just have to avoid the controls that implement it by including functionality you couldn't possibly have without it. You can just as easily add HTML controls and add the runat="server" attribute and gain member variables to the control from code-behind.
Here's what came to my mind:
What features does that JavaScript give the user?
Client side validation.
What does that JavaScript actually do?
For exmaple, it ensures that the correct (server-side) event handlers are called, by setting the __EVENTTARGET hidden field.
Is is possible to get the first list without the second?
You can use normal HTML controls instead of the ASP.NET controls. Then on the server-side, you can read the control's values from the Form collection.
I assume you mean the javascript associated with an <asp:Button /> control, right?
In addition to the reasons mentioned by Fooberichu, the javascript can also help with ASP.NETs client side validation framework.
But I think it's primary use is to alert the framework what events it should fire on the postback in the page behind.
So if you had two buttons on the form, SaveButton and DeleteButton, the javascript helps the framework know whether it should execute the SaveButton_Click event or DeleteButton_Click event.
Hope this helps.
I have an ASP.NET page that is interacting with a business class. I want to continuously update controls on my page based on user entered values, e.g. update totals. The calculations are embedded in business logic but they're simple enough to reproduce elsewhere. I've thought of three ways to accomplish this:
Dynamically update the page using JavaScript. I don't want to do this because I don't want to risk floating point math problems where the values on the page don't match the values calculated by the business class (those properties are decimals).
Clear calculated fields on changes and force the user to click a re-calculate button. This is a poor user experience and wiring up JavaScript to ASP.NET controls is tedious.
Use an AJAX UpdatePanel, set data entry controls to autopostback, and handle the "changed" event for the control, e.g. TextChanged for TextBox.
The third method seems cleanest to me, provides a nice user experience, and allows me to interact directly with my business class that I've stored in session state.
My question is: Is this a good idea and/or a common practice? Are there better ways to accomplish this?
I haven't done ASP.NET work for a few years and I have a prejudice against autopostback[1]. I've looked at the size of the request and it's currently negligible at 1.5kB. The site will be low use but we may have a small number of users with dial-up connections.
And ASP.NET in general but times are tough.
Personally, I think UpdatePanel is too heavy. You could use jQuery along with an ASP.NET Web service function that outputs JSON.
You're correct in thinking the third option is your best. This is the kind of thing that AJAX is made for. Go for it.
I've been tasked with converting an existing ASP.NET site from using InProc session management to using the ASP.NET State Server.
Of course what this means is that anything stored in the Session must be serializable.
One of the most complicated pages in the app is currently storing an ASP.NET control collection to the Session. This is failing miserably because the controls cannot be serialized automatically.
Short of totally rewriting how the page works to prevent the need for storing the control collection in the Session, does anyone have a trick/solution for making the collection serializable?
Rewrite the page. You'll thank yourself later. There are sure to be other problems if the original "programmer" (and I use that term loosely here) thought it was a good idea to store a control hierarchy in session.
Don't store control collections in session state. Tess has a lot of articles about this, for example this one.
The first answer that comes to mind is to do a partial rewrite (I don't think there's going to be an easy answer to this). If it's a small number of control types, write your own controls that inherit from those controls and also implement ISerializable. Then, using search and replace, replace the page's controls with your versions. If you are using a large number of control types, you might spend more time extending the standard types than you would refactoring the page.
The work is going to be in the serialization and deserialization of the controls when you initialize them, to make sure you're capturing what you need (the TextBox values, the IsSelected, etc.).
This is obviously a hack, but if your priority really is not rewriting the functionality of that particuar page, this might work for you. Then, of course, you need to add this solution to the "technical debt" that your application is accruing, to make sure it's always on someone's radar to refactor at some point.