RegisterExpandoAttribute - Throwing Error - asp.net

Recently, I discovered that using: someControl.Attributes.Add("customAttr", "customVal") is not compatible with all web browsers. The recommended registration for custom attributes is:
Page.ClientScript.RegisterExpandoAttribute(someControl.ClientID, "customAttr", "customVal")
Okay, here's the problem. I am using a ListView to generate a custom control. In certain scenarios, the ListView must be refreshed/recreated. When this happens, and a ListView item attempts the register (in this case, re-register) the expando attribute, the page throws the following error:
An entry with the same key already exists.
Obviously RegisterExpandoAttribute() does not behave like the Page.Cache object where if a key already exists, the current value is overwritten. I can easily hack my way past this problem but I wonder if there is a more elegant solution to this. For example, there is no method like: Page.ClientScript.IsExpandoAttributeRegistered(...)
Any ideas?

If you're creating a custom control, try doing the RegisterExpandoAttribute call during the control PreRender. I was having issues with the attribute still being registered if the control had been removed and doing that fixed my issue. I would imagine that if you're calling RegisterExpandoAttribute in the PreRender for the control then it shouldn't be called more than once per page load.

Related

I get a NullReferenceException when I use FindControl to find controls in either master or content pages

I am trying to create reversible themes in ASP.NET. I can successfully change themes using a dropdown list, but I am running into problems changing SkinID's and generic HTML controls (which are all div's except for the body tag) programmatically. I moved all my attribute- and skin-changing code to the PreInit method of my Base Page. Now I get a NullReferenceException when I run the page. I thought this code was supposed to use the existing controls it is supposedly pointing to. What am I missing or doing wrong?
Here is my code:
The PreInit event is probably too early in the page lifecycle to look for controls with FindControl. You're also doing your declarations outside of the event. That may have something to do with your null reference as well. I'd see if you can change it to look later in the lifecycle. This may be helpful if you haven't already seen it: http://msdn.microsoft.com/en-us/library/ms178472.aspx

How can I check for code blocks in my controls collection in ASP.net?

I am working on a method in my base page that throws the "The Controls collection cannot be modified because the control contains code blocks" message (and it's true, some of my pages have code blocks in the control I am trying to modify).
Is there a way for me to programmatically determine if this is the case myself? I tried iterating through the controls collection, but it didn't seem to state anything that I could use.
As background: the method is adding an error message control whenever certain exceptions are thrown. What I am doing as a workaround is to add the error message to the parent of the previously targeted control, because the way that these pages are generally written. I'd like to keep the natural layout of the error message if possible, so I want to check for the trigger that indicates codeblocks are in play, and only then do my workaround.

How to Prevent PostBack Event Handler from Firing

I have a custom class (ServerSideValidator.vb) that validates user input on server side (it doesn't use any of the .NET built in validators, therefore Page.Validate() is not an option for me). I am calling the Validate() method on page.IsPostback event and the class performs without any problem
My issue is, when validation fails (returns false), I want to stop the postback event handler from firing, but load the page along with all the controls and user-input values in them. If I do, Response.End(), the page comes up blank. I can programmatically instruct the page to go to the previous page (original form before postback), but it loses all user-inputs.
I thought of creating a global boolean variable in the page code behind file and check the value before performing any postback method, but this approach takes away from my plan to provide all functionalities inside the class itself. The page object is being referenced to ServerSideValidator.
Seems like all the postback related properties/variables I come across inside Page class are 'Readonly' and I can't assign value(s) to control/prevent postback event from firing.
Any idiea on how I can accomplish this? Please let me know if you need further details
It's probably easier to post back to the same page every time and do your validation there, specifically on the page load event. If the validation fails, you're already on the correct page and don't have to go to a previous page. If the validation succeeds, then you can redirect to another page if you wish, in which case you probably don't need any data.
Edit: This isn't exactly what you asked for, but I have a feeling it will do what you want while fitting into the existing ASP.NET validation design. See http://www.dotnetcurry.com/ShowArticle.aspx?ID=197 and https://web.archive.org/web/20211020145934/https://www.4guysfromrolla.com/articles/073102-1.aspx
Basically, you create a custom class just like you have now, but inherit from BaseValidator. To follow your design, you can create an enum called ValidationType which has Alphabetic, Alphanumeric, etc. In your custom class, create a property called ValidationType that uses the ValidationType enum. Of course you have to add all the validation logic. Then in your aspx page, you can add your custom validator to the page and set ValidationType="Alphabetic", etc. with full IntelliSense support.
Since you use BaseValidator, all the regular validation techniques will work including Page.Validate(), Page.IsValid, etc. You can even create client-side validation JavaScript if you wish.
Having said this, someone has probably already done most of this for you.

How to force Flex validation when a container is displayed

I have a Flex 3 app with a view in a viewstack, and that view must only be created when requested. I have declared validators for each of the controls on the view and I have created a method called checkAllValid() which runs Validator.validateAll(). This works great when I'm actually using the controls (using the change or focusOut events), but how can I get checkAllValid() to run when the view is first displayed to the user, so that they are immediately shown what is invalid once the data is populated in the controls?
I have tried putting the call in various events on the view itself (e.g. creationComplete, updateComplete, show, activate, etc.) but it always shows the following error when I start the application:
'The source attribute must be specified when the property attribute is specified.'
I have also tried setting the creationPolicy on the view to "all" but this does not help.
Some of the validators are only enabled when the form is in a certain state, but I have eliminated that as being the potential problem by commenting out all of my validators except for this most simple one:
<mx:Array id="validators"><mx:StringValidator id="val_Address1" source="{Address1}" property="text" required="true" triggerEvent=""/></mx:Array>
The checkAllValid() method is as simple as follows:
private function checkAllValid():void{
var validationErrors: Array = Validator.validateAll(validators);
}
I have also tried calling the single validator directly rather than using validateAll and the result is the same.
Please help! There must be a way I can force the view to validate when it is shown....
(by the way it's in the Cairngorm MVC framework and I have data bound to the controls)
Got it! I added similar validators to another view and they worked fine. What was the difference? The method that called checkAllValid() was being called on the creationComplete event of an internal container - not the main view component.
So in the end it was nothing to do with the validation itself - just me not fully understanding the creation order.
I'll leave the question on here just in case someone encounters a similar problem with the creation order.

Dynamic Control loading at wrong time?

This one is a little... odd. Basically I have a form I'm building using ASP.NET Dynamic Data, which is going to utilize several custom field templates.
I've just added another field to the FormView, with it's own custom template, and the form is loading that control twice for no apparent reason. Worse yet, the first time it loads the template, the Row is not ready yet and I get the error message:
Databinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databound control
I'm accessing the Row variable in a LinqDataSource OnSelected event in order to get the child object...
Now for the wierd part: If I reorder the fields a little, the one causing the problem no longer gets loaded twice.
Any thoughts?
EDIT: I've noticed that Page_Load gets called on the first load (when Row throws an exception if you try to use it) but does NOT get called the second time around. If that helps any...
Right now managing it by just catching and ignoring the exception, but still a little worried that things will break if I don't find the real cause.
EDIT 2: I've traced the problem to using FindControl recursively to find other controls on the page. Apparently FindControl can cause the page lifecycle events (at least up to page_load) to fire... and this occurs before that page "should" be loading so it's dynamic data "stuff" isn't ready yet.
You aren't referring to something in Page_Load that is set in OnSelected, are you? Something like your row object. OnSelected is a postback event and occurs after Page_Load. It's the only thing I can think of that might cause your exception when the row is not ready.
Start commenting things out in your code behind until either everything is commented or your control no longer loads twice.
If it is still doing it, start unhooking things in the control itself. Eventually, you'll get to the actual issue.

Resources