Showing posts with label based. Show all posts
Showing posts with label based. Show all posts

Wednesday, March 28, 2012

AJAX based Web service authentication issue

Hi, I have created a webservice for putting overlays on googlemap. I am using scriptmanager to generate java proxy class. Everything works as expected as long as I use localhost in the url e.g.http://localhost/test.aspx orhttp://localhost/map.asmx/js but if I use the actual domain name then it don't work anymore e.g.http://www.test.com/test.aspx orhttp://www.test.com/map.asmx/js. In case of IE7 i get script error 'test is undefined' and in case of Firefox, I get authentication failed. The result is same whether I run it on the server or on the client. I have tried every possible thing that I can think of. Environment is Win 2003 and IIS 6.0. Framework 2.0 is enabled in the web services entensions. I am using windows integrated authentication and anonymous access is also enable. I am new to ajax world and trying hard for last 2 days to solve this problem. Please help me. Thanks a lot

Hi,

Can you directly browse to http://www.test.com/map.asmx/js. and does that download the Script Proxy ?

Also , can you take a look at the IIS Logs to understand the behavior on the server when you browse to the page ?

Go to Start --> Run -->Type in "LogFiles"

In the folder that opens up , go inside W3SVC1.

Take a look at the File exmmddyy.log and paste the lines that havemap.asmx/js. here.


Thanks for quick response. When I directly browse to .../js in IE7, i get 500 internal error whereas in case of Firefox, it prompts to download a file and the contents of the file are: "{"Message":"Authentication failed.","StackTrace":null,"ExceptionType":"System.InvalidOperationException"}".

No such folder "W3SVC1" exists under LogFiles ... only following folders are present there "Cluster, HTTPERR, ShutDown" and in there I am not able to find anything related to my issue.

Please let me know what next I should do? Thanks


Hi,

HttpPost andHttpGet for webservices is disabled by default in ASP.net 2.0

See if you can find the following snippet in your web.config , if it doesnt exist, add it under the <System.Web> Tag

<webServices>
<protocols>
<add name="HttpSoap1.2"/>
<add name="HttpSoap"/>
<add name="HttpPost"/> // uncomment this
<add name="HttpGet"/> // uncomment this
<add name="HttpPostLocalhost"/>
<add name="Documentation"/>
</protocols>
<soapExtensionTypes>
</soapExtensionTypes>
<soapExtensionReflectorTypes>
</soapExtensionReflectorTypes>
<soapExtensionImporterTypes>
</soapExtensionImporterTypes>
<wsdlHelpGenerator href="http://links.10026.com/?link=DefaultWsdlHelpGenerator.aspx"/>
<serviceDescriptionFormatExtensionTypes>
</serviceDescriptionFormatExtensionTypes>
</webServices>

Hope this helps


Read this KB article about Protocols and web services

HOW TO: Limit the Web Services Protocols that a Server Permits

http://support.microsoft.com/?id=815150


Yes, it was not there and I copied it under system.web tag but the issue is still there. There is also an <httpHandles> tag under system.web. I am pasting the lines from my web.config related to ajax. May be it will give further clue. Please let me know if u see something wrong there or what should I do next. Thanks a lot.

--------

<configSections>
<sectionGroupname="system.web.extensions"type="System.Web.Configuration.SystemWebExtensionsSectionGroup,System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,PublicKeyToken=31bf3856ad364e35">
<sectionGroupname="scripting" type="System.Web.Configuration.ScriptingSectionGroup,System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,PublicKeyToken=31bf3856ad364e35">
<sectionname="scriptResourceHandler"type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,PublicKeyToken=31bf3856ad364e35" requirePermission="false"allowDefinition="MachineToApplication" />
<sectionGroup name="webServices"type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,PublicKeyToken=31bf3856ad364e35">
<sectionname="jsonSerialization"type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,PublicKeyToken=31bf3856ad364e35" requirePermission="false"allowDefinition="Everywhere" />
<sectionname="profileService"type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,PublicKeyToken=31bf3856ad364e35" requirePermission="false"allowDefinition="MachineToApplication" />

<section name="authenticationService"type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,PublicKeyToken=31bf3856ad364e35" requirePermission="false"allowDefinition="MachineToApplication" />
</sectionGroup>
</sectionGroup>
</sectionGroup>
<sectionGroup name="applicationSettings"type="System.Configuration.ApplicationSettingsGroup, System,Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="wwwroot.Properties.Settings"type="System.Configuration.ClientSettingsSection, System,Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"requirePermission="false" />
</sectionGroup>
</configSections>

<system.web>

<httpHandlers>
<remove verb="*" path="*.asmx" />
<add verb="*" path="*.asmx" validate="false"type="System.Web.Script.Services.ScriptHandlerFactory,System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,PublicKeyToken=31bf3856ad364e35" />
<add verb="*"path="*_AppService.axd" validate="false"type="System.Web.Script.Services.ScriptHandlerFactory,System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,PublicKeyToken=31bf3856ad364e35" />
<addverb="GET,HEAD" path="ScriptResource.axd"type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions,Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"validate="false" />

</system.web>

<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules>
<add name="ScriptModule" preCondition="integratedMode"type="System.Web.Handlers.ScriptModule, System.Web.Extensions,Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</modules>
<handlers>
<remove name="WebServiceHandlerFactory-ISAPI-2.0" />
<add name="ScriptHandlerFactory" verb="*" path="*.asmx"preCondition="integratedMode"type="System.Web.Script.Services.ScriptHandlerFactory,System.Web.Extensions, Version=1.0.61025.0, Culture=neutral,PublicKeyToken=31bf3856ad364e35" />
<addname="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd"preCondition="integratedMode"type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<add name="ScriptResource" preCondition="integratedMode"verb="GET,HEAD" path="ScriptResource.axd"type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</handlers>
</system.webServer>

----------------


I have found the iis logfiles and the directory 'W3SVC1' ... this directory is present in another partition because of setting different path for logging from IIS console.

Below are the lines related to this webservice:

this is the line when called with the following url : http://localhost/WebServices/WSGoogleMaps.asmx

2007-02-22 17:06:54 127.0.0.1 GET /webservices/wsgooglemaps.asmx/js - 80 - 127.0.0.1 Mozilla/5.0+(Windows;+U;+Windows+NT+5.2;+en-US;+rv:1.8.1.1)+Gecko/20061204+Firefox/2.0.0.1 200 0 0

and this is the line when called with the following url: http://mytest.server.com/WebServices/WSGoogleMaps.asmx

2007-02-22 18:15:27 192.167.1.273 GET /WebServices/WSGoogleMaps.asmx/jsdebug - 80 - 132.136.112.84 Mozilla/4.0+(compatible;+MSIE+7.0;+Windows+NT+5.1;+InfoPath.2;+.NET+CLR+2.0.50727;+.NET+CLR+1.1.4322) 500 0 0

I have tried it on the server itself as well. If I use domainname then it is giving 500 internal error in IE7 or authentication failed in Firefox. This is the line when called from the server itself using domain name:

2007-02-22 16:41:04 192.167.1.273 GET /WebServices/WSGoogleMaps.asmx/jsdebug - 80 - 192.167.1.273 Mozilla/5.0+(Windows;+U;+Windows+NT+5.2;+en-US;+rv:1.8.1.1)+Gecko/20061204+Firefox/2.0.0.1 500 0 0

I simply don't understand that how same code on the same machine works with localhost in the url but gives error when called with domain name in the url. I am totally lost. Please help me solve it ... I need to solve it urgently. Thanks.


Hi there,

We are experiencing the same issue that seems to do with the domain name causing the authentication error in some environments. Did you ever get a resolution to this issue?

Ajax based Tab control.

Hi all,

I need a Menu control horizontally laid out at the top the screen on a master page as shown below.

Tab1 Tab2 Tab3 Tab4 Tab5

Each tab would navigate to a different page, Tab1 to Page1.aspx, Tab2 to Page2.aspx, ...Tabi to Pagei.aspx etc.

Is it possible to change between different tabs(pages) in a Ajaxy way(so that the user doesnt see the flicker or the progress bar at the bottom of browser on the task bar),

I see that UpdatePanel does not integrate well with asp:menu, and a I saw a couple of posts where people have used the CallBack feature of asp.net 2.0 to attain the effect. Is this the only solution?


Thanks for your time

try it.....

Master.aspx File

<%@. Master Language="C#" AutoEventWireup="true" CodeFile="MasterPage.master.cs" Inherits="MasterPage" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<link href="http://links.10026.com/?link=StyleSheet.css" rel="stylesheet" type="text/css" />
<title>Master Page ::</title>
</head>
<body>
<form id="form1" runat="server">
<table cellpadding="0" cellspacing="0" id="MasterContainer" width="100%">
<tr>
<td id="BannerContainer" align="left" colspan="2">
Tab Demo Site
</td>
</tr>
<tr>
<td id="ContentContainer" valign="top" style="height: 19px">
<table cellpadding="0" cellspacing="0" border="0" width="100%">
<tr>
<td colspan="2">
<table cellpadding="0" cellspacing="0" border="0" width="100%" class="TabMenuContainer">
<tr>
<td>
<asp:Menu CssClass="TabMenu" DataSourceID="TabMenuSitemap" HideSelectElements= "True" ID="Menu2" Orientation="Horizontal" runat="server">
<StaticSelectedStyle CssClass="TabMenuItemSelected" />
<StaticMenuItemStyle CssClass="TabMenuItem" />
<StaticMenuStyle CssClass="SiteStaticMenu" />
<StaticHoverStyle CssClass="TabMenuItemHover" />
<DataBindings>
<asp:MenuItemBinding DataMember="SiteMapNode" Depth="0"
NavigateUrlField="Url" TextField="Title" ToolTipField="Description" />
</DataBindings>
</asp:Menu>
</td>
<td class="TabMenuSpacer" width="100%"></td>
</tr>
</table>
</td>
</tr>
<tr>
<td width="100%" valign="top">
<div id="SiteContent">
<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
</div>
</td>
<td>
<div class="SiteContentSpacer"></div>
</td>
</tr>
</table>
</tr>
</table>
<asp:SiteMapDataSource ID="TabMenuSitemap" runat="server" ShowStartingNode="false" />
</form>
</body>
</html>

WEb.sitemap File

<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/ AspNet/SiteMap-File-1.0" >
<siteMapNode url="" title="" description="" roles="*">
<siteMapNode url="~/default.aspx" title="My WebPage" description="The Home Page" roles="*" />
<siteMapNode url="~/default2.aspx" title="My WebPage 1" description="The First Tab" roles="*" />
<siteMapNode url="~/default3.aspx" title="My WebPage 2" description="The Second Tab" roles="*" />
</siteMapNode>
</siteMap>

Smile

AJAX based shopping cart

i ve checked out several .net shopping carts available for integration. But found no one with the cool features of drag n drop and minimum post backs. We are in the age of ASP.NET AJAX thats why so much of post backs in traditional shopping carts irritates.

Did anyone developed such thing yet ??...

Hi,

I fail to reproduce the issue. Can you show me your code?


thanks for the reply. but i think you dint got my question..

i am just asking for some shopping cart component which i can integrate with my web site. The shopping carts available are all very slow (using a lot of post back calls). i want my online shop to have drag drop feature and minimum postbacks.

thanks

cheers :)


After searched the internet, I'm very sorry to tell you that I cann't privide you with a .net shopping carts cortrol matched your need.

Maybe you can develop it by yourself.

We are marking this issue as "Answered". If you have any new findings or concerns, please feel free to unmark the issue.

Thanks

i'm thinking of allowing my customers to be able to drag the item into the shop cart too. if i ever accomplish it, i will let you know ... it should not be that hard ... =)


I want some thing like this

http://www.telerik.com/demos/aspnet/Dock/Examples/ShoppingCart/DefaultCS.aspx

really cool... :)

ajax based page need to go to the top of the page....

Hi everyone ,,,

i have a page that contain update panel , that uses partial rendering ..

i need to go to the top of the page after postBack ... how do i do this ?

thnx ..


Why would you want a postback if you are using Update PanelSmile

The Update Panel and other partial rendering sections are solely meant for avoiding the page from going to the top for each and every action and retainng the scroll position.

Is there a specific reason you want the page to scroll up?


i need it because i have a gridview at the bottom of the page that i select a row from it ,

and i get an information about the row at the top of the page , if i have a lot of rows when i select a row i stay on the position of the row and the info is not display for

the user, the user need to scroll to the top of the page ..



Use this Peace of Code:
-------------------------------
<!--Add the following after the scriptmanager on your page:-->

 <script type="text/javascript">
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(EndRequestHandler);
function EndRequestHandler(sender, args) {
window.scrollTo(0,0);
}
</script>

--------------------------------

If that doesnt work for some reason, try this

Use HTML Bookmarks to achieve this without a Postback

1) Place HTML Bookmark <a name="top" >TOP</a> on Top of the Page

2) Use Response.Redirect("PageURL#top) to go to the top of the page

Read more about Bookmark on this:
http://www.freewebmasterhelp.com/tutorials/html-basics/4

Shrinand Vyas

Ajax based navigation scheme

Hello,

I am trying to implement Ajax based navigation schema for a complex web application.

Basically, I will have a tree on the left. When item is clicked I want the content area on the page to load some content via Ajax (instead of refreshing the whole page).

I got somewhat far with having an update panel around content area and loading content via custom user controls (e.g. panel.Controls.Add(Page.LoadControl("blah.ascx")) ). However, I am running into some issues with this approach (for complex controls it appears this dynamic loading is breaking javascript etc). Can someone suggest any other mechanism one might use to implement this? Keep in mind, controls cannot be hardcoded on the page and need to come from an external file (e.g. the tree would load from xml file that specifies which controls correspond to which item on the tree).

Thanks

Unless I'm missing something, it sounds like you'd be better off using an IFRAME for your content area and just change it's .src with the navigation system.

ajax based masterpage

can any1 tell:

ajax based masterpage template i found in vs 2k8 but didn't get its purpose

i redirect from 1 page to another page of my site but don't wanna rerender/refresh contents of master page. i think this thing can do this but how not sure as i tried but it postback :) may b m wrong or doing wrong

Any time you go to a new page, even a page that has the same master as the current page you're on, you are going to have a full page refresh. Only partial page updates on the same page can be "hidden".

Ajax Based Login Control

How can I have ajax based login on my website home page ? How can I use built in login control in asp.net 2.0 to implement ajax ..

I want a login functionality as we use in gmail kindly guide me please

This really depends on how you do your login page. If you're login page is a seperate page (than the rest of your app), AJAX will only help you in that it will not "flick" when someone enter's wrong credentials.

However, if you have a "login" control that is added to a page if they're not logged in, you can use an AJAX callback to add that control do the page. You can use UpdatePanels if you need.


I have my login Control with in the page but i want to sent only that login form to server and remain rest page as it is ...how to do this pls guide


hello.
well, you do have some options here. for instance, you can use the client side validation services and build a simple form that will do just that.
http://www.asp.net/ajax/documentation/live/tutorials/UsingFormsAuthenticationTutorial.aspx

Ajax based custom control with web service

I want to create a simple reusable search pane control.

The idea is to have a textbox and a button. When you press the button you trigger an AJAX call to the server with the textbox value as parameter. The AJAX call then bridge the request to a web service that perform the database search an return a dataset. The dataset is then binded to a repeater in a updatepanel to display result. I've been using a WCF service for the web service.

This work fine if I host the textbox, the button and the result detail ascx file in a ASP.NET Ajax Enabled WebSite.

I try to move this part to a user web control, including the ascx files in resources. I hit the following problem: When I include the control (compiled assembly) in a ASP.Net Ajax Enabled Web site, the control display correctly but the AJAX call fail.

I think that the ScriptManagerProxy setting the AJAX service in my user control fails to find the path of the asmx ServerScript definition within the assembly.

Do you have any idea to make this work smoothly, ideally with only the assembly included in the website project?

Thanks in advance for your help

mavrj

Web user control is not only an assembly, which should include .ascx file and.ascx.cs or.ascx.vb file.There is only one asp:ScriptManager in a Ajax web form. I once tested a Ajax enabled web user control and placed it in a common web form.I found it worked fine. Can you post some codes here? We are going to test it.

Monday, March 26, 2012

Ajax authentication, custom membership; cannot use Session object

I'm using ajax 1.0 authentication but based on a custom sql membership service which is working 100% except that in the membership code the Session object (HttpContext.Current.Session) cannot be accessed which though is crucial because I user Session["UsersID"] for login based functions. Any ideas how this can be fixed?

Hello,

Would you give me more details (when, where you can't access session object) ?

I don't have any problems with Session object even with Ajax async call back??

May be your situation is different from mine!


yes is in the authentication function in my custom membership provider code;

publicoverridebool ValidateUser(string username,string password)

{

SqlConnection conn =newSqlConnection(connectionString);SqlCommand cmd =newSqlCommand("ValidateUser", conn);

cmd.CommandType =

CommandType.StoredProcedure;

cmd.Parameters.Add(

"@.Username",SqlDbType.VarChar, 12).Value = username;

cmd.Parameters.Add(

"@.Password",SqlDbType.VarChar, 12).Value = password;

cmd.Parameters.Add(

"@.IPNumber",SqlDbType.VarChar, 16).Value =HttpContext.Current.Request.UserHostAddress;SqlDataReader reader =null;try

{

conn.Open();

reader = cmd.ExecuteReader(

CommandBehavior.SingleRow);if (reader.Read() ==false)

{

returnfalse;

}

int _usersID =Convert.ToInt32(reader["UsersID"]);

HttpContext.Current.Session["UsersID"] = _usersID;

}

...


Hi Dabbi2000,

That's indeed very tempting to do. However, this construct will never work. The deal is that your code is executed by an http module that runs before the AcquireRequestState event. In other words: there is no session yet.

The best way to achieve what you want is to store your user id in the items collection of the current context and than move it from context to session in the PostAcquireRequestState event. So replace the last line of your example with:

HttpContext.Current.Items["UsersID"] = _usersID;

and then after the session state has been loaded (for example in PostAcquireRequestState)

HttpContext.Current.Session["UsersID"] = HttpContext.Current.Items["" UsersID"];
HttpContext.Current.Items.Remove("UsersID");

HTH,

-- Henkk


Henk,

that is an excellent solution! Unfortunately the Items container doesn't contain the UsersID when accessing from PostAcquireRequestState event. Using VS Debugger and Fiddler it simply seems to be lost somewhere between the authentication code and the PostAcquireRequestState event (the requesting assembly is "~/Authentication_JSON_AppService.axd"). Still there are other system variables in the Item like Is there some obvious explanation for that??


hmm not entirely correct, it isn't lost but what happens is that json authentication causes PostAcquireRequestState event BEFORE the membership validateuser() function is called?!!


Hi Dabbi2000,

I wanted to see for myself and, yes, you're right. What's going on ? In a normal postback (including async ones) the pipeline follows the chain of events I described in a previous post.

The problem is: I thought you were using the normal forms based authentication stuff in combination with an Ajax enabled app. However, you appear to be using the Sys.Services.AuthenticationService. Unfortunately (my bad, sorry) this is not a normal postback. It's uses the same infrastructure (ScriptHandler) as script services (as far as I can see, it is a script service dressed up as a resource). This means that indeed by the time you reach the endpoint (the authentication service backend) the PostAcquireSessionState event is long gone.

Fortunately, there are other events to subscribe to. But, unfortunately, if the PostAcquireSessionState is done and there is no session state, they most have turned sessions off for this service (and indeed the Session property in the HttpContext returns null).

Meaning, there is no way for you to use the Session object.

However, if the only thing you want to do is get to the current user id, the FormsAuthenticationModule (like all other builtin authentication modules) makes sure the currently logged on user is reflected in the Page.User property (or HttpContext.User for which Page.User is just a wrapper).

If you need to store more, the profile should still work. BUT only after you made a roundtrip to the authentication service and you successfuly authenticated. The authentication service calls into the FormsAuthentication class to perform authentication and returns an authentication cookie like normal, but unfortunately it forgets to set HttpContext.User like the builtin authentication modules would do (feature request ...). This means the profile module has no info to fly on and will do an anonymous profile while in the call chain of the authentication service.

HTH,

-- Henkk


I wrote a blog post about the problem:http://www.jeffzon.net/Blog/post/Session-enabled-authentication-service.aspx

The only thing we should do is to use the following authentication service class instead of the default one:

using System;using System.Web;using System.Web.Services;using System.Web.Services.Protocols;using System.Reflection;using System.Web.Script.Services;using System.Web.UI;using System.Web.Security;[WebService(Namespace ="http://tempuri.org/")][WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)][ScriptService]public class SessionEnabledAuthService : System.Web.Services.WebService{private static MethodInfo checkEnabledMethodInfo;static SessionEnabledAuthService() { Type authServiceType =typeof(ScriptManager).Assembly.GetType("System.Web.Security.AuthenticationService"); checkEnabledMethodInfo = authServiceType.GetMethod("CheckAuthenticationServicesEnabled", BindingFlags.NonPublic | BindingFlags.Static); }private static void CheckAuthenticationServicesEnabled(bool enforceSSL) { checkEnabledMethodInfo.Invoke(null,new object[] { HttpContext.Current, enforceSSL }); } [WebMethod(EnableSession =true)] [ScriptMethod]public bool Login(string userName,string password,bool createPersistentCookie) { CheckAuthenticationServicesEnabled(true);if (Membership.Provider.ValidateUser(userName, password)) { FormsAuthentication.SetAuthCookie(userName, createPersistentCookie);return true; }return false; } [WebMethod(EnableSession =true)] [ScriptMethod]public void Logout() { CheckAuthenticationServicesEnabled(false); FormsAuthentication.SignOut(); }}

Hi Jeff,

This of course would work, but a couple of remarks:

1) namespacehttp://tempuri.org/ is not very unique ;-) you'll want to change this into something that makes more sense

2) I wouldn't mark this service as basic profile compliant. In normal situations it doesn't even do SOAP (script services serialize JSON by default). And even when you call it using a normal proxy, it's main result is returned as a cookie (which is not basic profile compliant, although I don't think the builtin pipeline check catches that).

3) By using reflection to call into CheckAuthenticationServicesEnabled you now have to run full trust (you'll need SecurityPermissionFlags.UnmanagedCode). Which means you either have to run the webservice full trust, or you'll have to install an separate assembly in the GAC (or grant it full trust with a custom policy). You'd be better of implementing this yourself, because the only really interesting thing CheckAuthenticationServicesEnabled does for you is check if SSL is enabled, which you can easilty do yourself with HttpRequest.IsSecureConnection (the other part is checking if an enabled flag is set on AuthenticationService itself, but since you're implementing your own, you already know it's enabled ...)

4) just as a word of warning for those who want to use this construct in production: I rarely think it's a good idea to repeat builtin functionality (with a minor change). I guess the team had good reasons to disable sessions (they are chatty things anyway) and there's plenty of workarounds. I do think it is too bad they didn't setup HttpContext.User and Thread.CurrentPrincipal like the pipeline authentication modules do, but alas. Regardless, the problem of getting to the current user is solved in an entirely different way, so the original poster will not benefit from this service. He can simply look an Page.User and be done with it.

-- Henkk


hello,

your discussions are a little more advanced than my programming knowledge :) but I would like to comment on that solution of using Page.User. User.Identity stores the username which is very unpractical. Imagine all the tables where I have to refer rows to user e.g. forum posts. User names can be whole names, and in my web would contain icelandic letters and so I think they are very bad for primary keys. That is the reason for why I use Session["UsersID"] instead of the User object.


D'uh. Don't know what I was thinking, but you'll need reflectionPermissionFlags.MemberAccess. What I said about SecurityPermissionFlags.UnmanagedCode is complete and utter BS. The net result is the same though. You'll need full trust ...

-- Henkk


Great feedback, Henkk, I totoally agree with you.

Actually I just gave a prototoype of the solution - or more likely a work around. In this situation, if the poster really need to use session state in authentication, he can use the service class I wrote - remove the validation method will be enough.


Hi,

The mapping from identity.name to user id can be done in a variety of ways. There is a very elegant one that sticks out I think (this is my personal preference BTW), which has to do with the way membership providers work. The builtin membership providers can do a mapping of the current user onto a so called MembershipUser (just a class in the library). The membership user contains more info than your average principal (including password questions, email addresses, stuff like that). You can get to the membership user for the current user by calling Membership.GetUser().

Since you implement your own provider you get to fill this information yourself (in the GetUser(userName, userIsOnline) override on your custom membership provider). One of the bits of info in a membership user is a ProviderUserKey. This is an object that you can fill with whatever info you want. In your case, probably the user id. The standard SqlMembershipProvider stores a GUID in it, BTW.

Whenever you need to get to the current user id, just use Membership.GetUser().ProviderUserKey.

Be aware though that the mapping is not cached, so if it is expensive to get from current user name to current user id, you better cache the mapping (in the ASP.NET cache ...).

The beauty of the construct is that now all custom logic is in your membership provider ...

HTH,

-- Henkk


hope you guys are still watching this thread...

Henk's solution is tempting... it's a bit expensive for only retrieving an Int value but if it survives the AJAX authentication I'm ok with it! I'm no good at asp.net cache, how would I use that for this situation??


that is, how to make it specific to each user, I thought the cache object scope was application only?

Saturday, March 24, 2012

Ajax and Viewstate variables

Hello Everyone,

I wanted to keep a counter for the page, which will increment or decrement based on button clicks.

These buttons are kept in UpdatePanel so not page refresh happens.

I decided to use viewstate variable as counter, I am initializing that variable to 0 for the first call.

but I found that for every click I have to initialize the viewstate variable as it is not maintained across Ajax request calls,.

Is there any workaround for this?

Thanks in advance,

Nitin Pawar

Following works just fine for me...

<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true" /> <asp:UpdatePanel ID="UpdatePAnel1" runat="server"> <ContentTemplate> <asp:Label ID="lblClickCount" runat="server" Text="0" /> <asp:Button ID="Button1" Text="Add counter" runat="server" OnClick="Button1_Click" /> </ContentTemplate> </asp:UpdatePanel>
Protected Sub Button1_Click(ByVal senderAs Object,ByVal eAs System.EventArgs)Dim cntAs Integer = 0If Not ViewState("ClickCount")Is Nothing Then cnt =CInt(ViewState("ClickCount"))End If cnt += 1 lblClickCount.Text = cnt.ToString() ViewState("ClickCount") = cntEnd Sub

AJAX and the Querystring

Having a slight problem with Atlas/Ajax. I have an item page which displays items based on the item id being passed by querystring into the page. The querystring parm is useful for bookmarking the exact product to be displayed on the page and returning to it later. If people click on a "go to next item in item category" button on this page, they get the next item in the category displayed and the URL querystring item parm changes to that item number. I accomplish this with a Response.Redirect to the same page with the new querystring parm value, but I can't seem to do this with an Ajax setup because the redirect loads the page over again.

How do I keep the benefits of Ajax by having a client side refresh without reloading the page and alter the querystring to the new product number?

what u store in the query string could also be stored in the session object & the session object could be passed as a parameter to the database.


That's a good suggestion; but the issue would be the user coming back to the page at a later point, having changed the item id on the querystring via the show next item in category button. They may wander off; close their browser; destroying the session info and then want to return to their "bookmarked" page. Even if I kept the data in the DB for retrieval and could identify that customer coming in again, how would I know which product they were after? What if they bookmarked two different products originally. I wouldn't have the querystring information under AJAX to know that. I don't think I would want to show them "last product viewed" when they come back in.


write a small procedure to evaluate the query string when the user comes back.if there is a query string, pass that to the session & databind.so in any case, whether there is a session variable or not you would be able to databind.

hello.

well, i think that's not he problem he wants to solve. what he needs to do is to change the query string so that it identifies the current product but he doesn't want to perform a navigation when changing the query string.

hum...i really don't know if you'll be able to do that...try to look at the location object, though i really think this is only ie specific


Luis,

I think you described exactly what I want to do. I can do it server side with no issue using a redirect, but client side with AJAX is a problem, even though AJAX does a great job with client side refreshes on the page!


hello.

well, the problem is that what you're trying to do is not an ajax related thing. i mean, for the browser, the query string really isn't something that you can program against. it's just an url, so i think that changing it for adding or modifying a query string parameter will force the browser to navigate to a new url. if this is not a problem to you, then simply changing thw window.location property will do what you want from the client side. however, you should note that this is the same as loading a new page in the browser...

Ajax and querystring parameter

Hi,

I am developing a new application with Ajax.

I must create a new aspx page that have two mode: "view" or "modify" and show some products based on their ID.

In not Ajax context I use the query string with parameters to change the mode and the ID of products and it is very simple. I change the query string using Response.Redirect("same page + new paramaters")

With Ajax I think to use some session variables to manage the mode of page and ID of products...

Is the correct solution?

Since the view/modify is likely tied to the authenticated user, I'd suggest use encrypted ViewState variables to store the productid and page mode. It won't expire compared to the SessionState.


Ok, but I have the necessity to pass some values (modify/view, productId) to this page.

Is the viewstate accessible between pages?

If I store an object in viewstate and then there is a redirect to a new page, is the object value accessible from new page?

Thank you.


I am using the session to tranfer object between pages and then I use the viewstate for postpack in the same page.

I have a problem.

I click in a button and in onclick method I change viewstate "mode" value from "view" to "modify"...

When in the Page_Load event I test the value of viewstate mode, it is still "view" instead of "modify". The viewState value change only on next postback...i must click two times to change page modality from view to modifiy.

How can I resolve this problem?


Ok, I have inserted the check in the Page_PreRender method and now it is working fine.

I did not remember that any code that is dependent on a control event should be put into PreRender method.


If you need to keep variable value between pages, using sessionstate is one solution, keep in mind that session will expire. You can also use database to handle temporary data storage. A new feature in ASP.NET 2.0 is the postback to another page, read this article to see if it fits what you wanted:http://msdn2.microsoft.com/en-us/library/6c3yckfw.aspx

For viewstate, it only belong to the current page. The value will not be carried over to another page.

AJAX and Master Pages

I seem to be having some trouble using AJAX and the ControlToolkit with Master Pages.

Just to make sure, I created a new website based on the AJAXControlToolkit template.

and a simple default.aspx - it only has a scriptmanager, panel ( with some text in it), linkbutton and AnimationExtender.

it is set to show/hide the panel when the linkbutton is hovered on - this works as expected.

Then, I create a masterpage.master file and a new WebForm based on this master file.

using the same markup fro the default.aspx page, I get a page that looks the same as default.aspx

but does not show/hide the panel and has a Javascript error as follows:

Sys.ArgumentException:

AjaxControlToolkit.Animation.Animation.set_animationTarget requires the ID of a Sys.UI.DomElement or Sys.UI.Control.

No element or control could be found corresponding to 'Panel1'

Parameter name: id

It seems as though the controls are being renamed and I might need to change the TargetControlID on PageLoad or something.

Any ideas would be appreciated.

Mike

This is the difference between server ID and client ID. The .ClientID property of a control can be used to get its client ID and should help here.

Wednesday, March 21, 2012

Ajax and Dynamically created controls.

I have an app where I add images to a panel based on what a user selects from a drop down list. Under internet explorer and opera it works fine. but the html code generated in firefox and netscape is missing the events. When I debug with IE or OPERA as default browser in vs 2005 events are fired. When Netscape or Firefox are set as default events (for the images) are not fired. I looked at the code being generated by the server and there are no events in the html code for the images. Here is what I get.

<li class="zipitem"><input name="zipselect1$ziprepeater$ctl01$selectbtn"id="zipselect1_ziprepeater_ctl01_selectbtn"class="imagebtn"src="images/selectbtn.gif"alt="Select"style="border-width: 0px;"type="image"><span id="zipselect1_ziprepeater_ctl01_ziplbl">12836</span></li><li class="zipitem"><input name="zipselect1$ziprepeater$ctl02$selectbtn"id="zipselect1_ziprepeater_ctl02_selectbtn"class="imagebtn"src="images/selectbtn.gif"alt="Select"style="border-width: 0px;"type="image"><span id="zipselect1_ziprepeater_ctl02_ziplbl">12851</span></li>
<li class="zipitem"><input name="zipselect1$ziprepeater$ctl03$selectbtn"id="zipselect1_ziprepeater_ctl03_selectbtn"class="imagebtn"src="images/selectbtn.gif"alt="Select"style="border-width: 0px;"type="image"><span id="zipselect1_ziprepeater_ctl03_ziplbl">12852</span>
this is just a code scrap. The page looks fine in all browsers but the Mozilla browsers dont work. You should be able to click on the images which takes and adds the zipcodes the images represent into a gridview. As I said works in IE and Opera fine.
 
 
 

See this is Browser compatibility issue....

Can you post some code details so it will help..

Which version of Firefox you used...

I suggest try yo use latest version...


It is a browser issue? I thought asp.net server side created the code for each browser. Any way if I.E worked the way it should I would not need Ajax to solve this problem. It is the only browser of the four I have tested that causes the screen to flash when clicking on the images. of course I could have some setting wrong which IE requires that the others don't.

The follow code produces a number of images on the page. When an image is clicked it gets put into a data grid.

see first post for code scrap generated for mozilla browsers . As can be seen there there is no event code created for the images.

As for code here is html source

<%@. Control Language="c#" AutoEventWireup="false" Codebehind="zip_selector.ascx.cs" Inherits="active.UserControls.zip_selector" TargetSchema="http://schemas.microsoft.com/intellisense/ie5"%
<br>
<div id="div_selectedzip">
<asp:label runat="server" id="lblSelZip"> Set of Selected Zipcodes: </asp:label><asp:button id="btnRemoveAll" runat="server" text="Remove All" visible="False"></asp:button><asp:repeater id=selectedzip runat="server">
<headertemplate>
<ul style="list-style-type: none">
</headertemplate>
<itemtemplate>
<li class="selectedzipitem">
<asp:label id="Label2" runat="server"><%#DataBinder.Eval(Container.DataItem, "zip_code") %></asp:label>
<asp:linkbutton id="removelnk" runat="server" commandname='<%# DataBinder.Eval(Container.DataItem, "zip_code") %>'>Remove</asp:linkbutton
</li>
</itemtemplate>
</asp:repeater>
<div style="CLEAR: both"></div> <!-- This is to make Opera load correctly for fieldsets -->
</div>
<br>
<div id="div_cntyzip">
<div id="instructTxt"><p>Enter one or
more zip codes in the text box separated by commas. Or you can add to set of selected zip
codes from a county. If you are interested in one of the <a onclick="window.open('glossary.htm', 'Glossary', 'width=432,height=270,toolbar=0,scrollbars=1,screenX=200,screenY=200,left=200,top=200')" href="http://links.10026.com/?link=javascript:void(0)" >non-standard zipcodes</a>, type one or more of the
following values separated by commas: <b>invalid,
illegible, unreported, irregular, or private</b>.</p></div>
<asp:label id="zipErrMsg" runat="server" forecolor="Red" visible="False">* Error:</asp:label>
<span>Zip Code:</span><asp:textbox id=txtZip runat="server"></asp:textbox><asp:button id=btnSelectZip runat="server" text="Add to Set"></asp:button>
<asp:Button id="btnAddAllZip" runat="server" Text="All NYS Zipcodes"></asp:Button><br>
<div style="DISPLAY: inline; WIDTH: 70px; HEIGHT: 15px" ms_positioning="FlowLayout">OR</div><br
<span>Add to Set of Selected Zipcodes from County: </span><asp:dropdownlist id=cntyzipddl runat="server" autopostback="True"></asp:dropdownlist>
<asp:repeater id=ziprepeater runat="server" OnItemCommand="ziprepeater_ItemCommand1" >
<headertemplate>
<ul style="list-style-type: none">
</headertemplate>
<itemtemplate>
<li class="zipitem">
<asp:imagebutton id="selectbtn" runat="server" cssclass="imagebtn" alternatetext="Select" imageurl="../images/selectbtn.gif" commandargument='<%#DataBinder.Eval(Container.DataItem, "cnty_code") %>' commandname='<%#DataBinder.Eval(Container.DataItem, "zip_code") %>'></asp:imagebutton>
<asp:label id="ziplbl" runat="server"><%#DataBinder.Eval(Container.DataItem, "zip_code") %></asp:label>
</li>
</itemtemplate>
<footertemplate>
</ul>
<div class="spacer"> </div>
</footertemplate>
</asp:repeater>
<div style="CLEAR: both"></div> <!-- This is to make Opera load correctly for fieldsets -->
</div>
<br
here is code behind page in c#

namespace active.UserControls
{
using System;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using active.DataAccessLayer;
using active.Common;

/// <summary>
/// Summary description for zip_selector.
/// </summary>
public class zip_selector : System.Web.UI.UserControl
{
#region Properties
protected System.Web.UI.WebControls.Repeater ziprepeater;
protected System.Web.UI.WebControls.Repeater selectedzip;
protected System.Web.UI.WebControls.Label Label1;
protected System.Web.UI.WebControls.Label zipErrMsg;
protected System.Web.UI.WebControls.Label lblSelZip;
protected System.Web.UI.WebControls.TextBox txtZip;
protected System.Web.UI.WebControls.Button btnSelectZip;
protected System.Web.UI.WebControls.DropDownList cntyzipddl;
protected System.Web.UI.WebControls.Button btnRemoveAll;
protected System.Web.UI.WebControls.Button btnAddAllZip;
protected bool bBadZipFound=false;
private int MAXZIP;

private int MAXZIPCOUNT
{
get {return 300;}
set {MAXZIP = value;}
}

public bool All_ZIP_SELECTED
{
get
{
object o = ViewState["All_Zip_Selected"];
if (o == null)
return false;
else
return (bool)o;
}
set { ViewState["All_Zip_Selected"] = value; }
}

private string CountyCode
{
get
{
object o = ViewState["CountyCode"];
if (o == null)
return "00";
else
return o.ToString();
}
set { ViewState["CountyCode"] = value; }
}

public DataTable SelectedZipTable
{
get
{

DataTable t = ViewState["SelectedZip"] as DataTable;
if (t == null)
{
t=new DataTable("SelectedZip");
DataColumn dc = new DataColumn("zip_code",System.Type.GetType("System.String"));
DataRow dr = t.NewRow();
t.Columns.Add(dc);
dr["zip_code"] = "None Selected";
ViewState["SelectedZip"] = t;
}

return t;
}
set { ViewState["SelectedZip"] = value; }
}
public bool BadZipFound
{
get
{
return bBadZipFound;
}
}
public event EventHandler BubbleClick;
#endregion

#region Page Events
private void Page_Load(object sender, System.EventArgs e)
{
// Put user code to initialize the page here
zipErrMsg.Visible = false;
if (!Page.IsPostBack)
{
CountyList lstCounties = Lookups.Counties;

//Filter out the non-standard county codes. All nonstandard counties have a sort_order
//greater than 990.
DataView dv = lstCounties.Tables[0].DefaultView;
dv.RowFilter = "sort_order < 990";
//lstCnty.DataSource = lstCounties;
cntyzipddl.DataSource=dv;
cntyzipddl.DataMember = lstCounties.counties.TableName;
cntyzipddl.DataTextField = lstCounties.counties.cnty_nameColumn.ColumnName;
cntyzipddl.DataValueField = lstCounties.counties.cnty_codeColumn.ColumnName;
cntyzipddl.DataBind();

ListItem item= new ListItem("Select County","00");

cntyzipddl.Items.Insert(0,item);
cntyzipddl.SelectedValue = CountyCode;

BindZipRepeater();
BindSelectedZip();

}

}
protected override void OnPreRender(EventArgs e)
{
if (SelectedZipTable.Rows.Count > 0)
btnRemoveAll.Visible=true;
else btnRemoveAll.Visible=false;
base.OnPreRender (e);
}
#endregion

#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
this.cntyzipddl.SelectedIndexChanged +=new EventHandler(cntyzipddl_SelectedIndexChanged);
this.ziprepeater.ItemCommand +=new RepeaterCommandEventHandler(ziprepeater_ItemCommand);
this.selectedzip.ItemCommand +=new RepeaterCommandEventHandler(selectedzip_ItemCommand);
this.btnSelectZip.Click += new System.EventHandler(this.btnSelectZip_Click);
base.OnInit(e);
}

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.btnRemoveAll.Click += new System.EventHandler(this.btnRemoveAll_Click);
this.btnAddAllZip.Click += new System.EventHandler(this.btnAddAllZip_Click);
this.Load += new System.EventHandler(this.Page_Load);

}
#endregion

#region User Public Methods

/// <summary>
/// Binds the zip selector datagrid to the results from list of zip codes retrieved by county
/// </summary>
public void BindZipRepeater()
{
DataSet dsZipSelect;
string cnty_cd = CountyCode;
DataTable dt;

dsZipSelect = Lookups.GetZipByCnty(cnty_cd);
dt = dsZipSelect.Tables[0];

//Add the option of selecting all zip codes in county
if (CountyCode!="00")
{
DataRow dr = dt.NewRow();
dr[1]="All County Zip";
dt.Rows.Add(dr);
}
/*//Add the option of selecting all NY zip codes
dr = dt.NewRow();
dr[1]="All NY Zip";
dt.Rows.Add(dr);
*/
ziprepeater.DataSource = dsZipSelect;
ziprepeater.DataMember = "ZipSelect";
ziprepeater.DataBind();

}

public void BindSelectedZip()
{
selectedzip.DataSource = SelectedZipTable;
selectedzip.DataMember = "SelectedZip";
selectedzip.DataBind();

int selectedCount = SelectedZipTable.Rows.Count;
lblSelZip.Text = "Set of Selected Zip Codes (" + SelectedZipTable.Rows.Count + " of " + MAXZIPCOUNT + " Max): ";

}
#endregion

#region Private Methods
private void lstCnty_SelectedIndexChanged(object sender, EventArgs e)
{
ListControl lstCnty = sender as ListControl;
if (lstCnty != null)
{
CountyCode = lstCnty.SelectedValue;
BindZipRepeater();
}
}

private void cntyzipddl_SelectedIndexChanged(object sender, EventArgs e)
{
ListControl lstCnty = sender as ListControl;
if (lstCnty != null)
{
CountyCode = lstCnty.SelectedValue;
BindZipRepeater();
}
}

private void ziprepeater_ItemCommand(object source, RepeaterCommandEventArgs e)
{
OnBubbleClick(e);
string selectedZip = e.CommandName;
string selectedCnty = e.CommandArgument.ToString();
DataTable dt = SelectedZipTable;
zipErrMsg.Visible=false;
if (!All_ZIP_SELECTED)
{
//the zip is not already been added and the amount of selected zipcodes
//do not exceed MAXZIPCOUNT
if (dt.Rows.Count < MAXZIPCOUNT)
{
if (selectedZip == "All County Zip")
{
//Add all zips in the selected County
AddCountyZips();
}
else
{
AddSelectedZip(selectedZip);
}
}
else
{
zipErrMsg.Text = "You have exceeded the maximum of " + MAXZIPCOUNT.ToString() + " zip codes. Please narrow your search. <BR>";
zipErrMsg.Visible = true;
}
}
else
{
zipErrMsg.Text="All NYS zip codes have been selected. No need to add individual zipcode.<br>";
zipErrMsg.Visible=true;
}
}

private void selectedzip_ItemCommand(object source, RepeaterCommandEventArgs e)
{
string selectedZip = e.CommandName;
DataTable dt = SelectedZipTable;
string selectExpr = "zip_code ='" + selectedZip+"'";
DataRow[] foundRow = dt.Select(selectExpr);
zipErrMsg.Visible=false;

if (foundRow.Length >0)
{
dt.Rows.Remove(foundRow[0]);
if (selectedZip=="All NYS Zip")
{ All_ZIP_SELECTED = false;
}
BindSelectedZip();

}

}
//"Add to Set" button click method
private void btnSelectZip_Click(object sender, System.EventArgs e)
{
OnBubbleClick(e);
zipErrMsg.Visible=false;
//reset the select county table to avoid confusion
CountyCode="00";
cntyzipddl.SelectedValue = CountyCode;
BindZipRepeater();

if (!All_ZIP_SELECTED)
{
//parse and validate zip input string
string [] zips = zipinput_parser();
DataTable dt = SelectedZipTable;

//if valid zips are returned, add to Selected Zip table
if (zips != null)
{
foreach (string zip in zips)
{
//the zip is not already been added and the amount of selected zipcodes
//do not exceed MAXZIPCOUNT
if (dt.Rows.Count < MAXZIPCOUNT)
{
AddSelectedZip(zip);
}
else
{
zipErrMsg.Text = "You have exceeded the maximum of " + MAXZIPCOUNT.ToString() + " zip codes. Please narrow your search.<br>";
zipErrMsg.Visible = true;
break;
}
//blank out the zip textbox for another entry
txtZip.Text="";
} //end of foreach
} //end of if zip length==0

}
else
{
zipErrMsg.Text="All NYS zip codes have been selected. No need to add individual zipcode.<br>";
zipErrMsg.Visible=true;
}
}

public string[] zipinput_parser()
{
// split zip string between commas
string[] splitTxt = txtZip.Text.Split(new char[] {',',' '});
string validZips="";
string badZips="";
zipErrMsg.Text = "* Error: ";
zipErrMsg.Visible=false;
//check blank zip input
if (txtZip.Text == "")
{
zipErrMsg.Text += "Please enter a zip code value. <br>";
zipErrMsg.Visible = true;
}
else
{
string lowerZip;
//txtZip.Text = "";
foreach (string zip in splitTxt)
{
lowerZip = zip.ToLower();
lowerZip = lowerZip.Trim();
if (zip !="")
{
//check it is not one of the non-standard zip code values
if ((lowerZip != "private") &&(lowerZip != "invalid") && (lowerZip != "illegible") && (lowerZip != "unreported") && (lowerZip != "irregular"))
{ //zip code is invalid if zip is alpha or is not 5 digits long
if ((lowerZip.Length != 5)||!Validations.IsNumeric(lowerZip))
{
//zipErrMsg.Text = zipErrMsg.Text + lowerZip;
zipErrMsg.Visible = true;
//txtZip.Text = txtZip.Text + lowerZip + ",";
badZips= badZips + lowerZip + ",";
}
else validZips = validZips + lowerZip + ",";
}
else validZips = validZips + lowerZip + ",";
}
}
if (zipErrMsg.Visible)
{
bBadZipFound=true;
badZips = badZips.Remove(badZips.Length-1,1);
txtZip.Text=badZips;
zipErrMsg.Text = zipErrMsg.Text + badZips + " is not valid.";
if (validZips.Length>0)
{
zipErrMsg.Text += " Valid zips have been added to the selected zip table.";
}
zipErrMsg.Text += "<br>";
}
//remove last comma
if (validZips.Length>0) validZips = validZips.Remove(validZips.Length-1,1);
}
if (validZips =="")
return null;
else return validZips.Split(new char[] {','});

}

public string zipinput_parser(bool validateOnly)
{
// split zip string between commas
string[] splitTxt = txtZip.Text.Split(new char[] {',',' '});
string validZips="";
string badZips="";
zipErrMsg.Text = "* Error: ";
zipErrMsg.Visible=false;
//check blank zip input
if (txtZip.Text == "")
{
zipErrMsg.Text += "Please enter a zip code value. <br>";
zipErrMsg.Visible = true;
}
else
{
string lowerZip;
//txtZip.Text = "";
foreach (string zip in splitTxt)
{
lowerZip = zip.ToLower();
lowerZip = lowerZip.Trim();
if (zip !="")
{
//check it is not one of the non-standard zip code values
if ((lowerZip != "private") &&(lowerZip != "invalid") && (lowerZip != "illegible") && (lowerZip != "unreported") && (lowerZip != "irregular"))
{ //zip code is invalid if zip is alpha or is not 5 digits long
if ((lowerZip.Length != 5)||!Validations.IsNumeric(lowerZip))
{
//zipErrMsg.Text = zipErrMsg.Text + lowerZip;
zipErrMsg.Visible = true;
//txtZip.Text = txtZip.Text + lowerZip + ",";
badZips= badZips + lowerZip + ",";
}
else validZips = validZips + lowerZip + ",";
}
else validZips = validZips + lowerZip + ",";
}
}
if (zipErrMsg.Visible)
{
bBadZipFound=true;
badZips = badZips.Remove(badZips.Length-1,1);
zipErrMsg.Text = zipErrMsg.Text + badZips + " is not valid.";
zipErrMsg.Text += "<br>";
}
//remove last comma
if (validZips.Length>0) validZips = validZips.Remove(validZips.Length-1,1);
}
return validZips;

}
/// <summary>
/// Adds all the zip codes within a county
/// </summary>
private void AddCountyZips()
{
DataSet dsZipSelect;
string cnty_cd = CountyCode;
DataTable dt = SelectedZipTable;
DataTable cntyTable;
string zipCd;
int totalZip;

zipErrMsg.Visible=false;
dsZipSelect = Lookups.GetZipByCnty(cnty_cd);
cntyTable = dsZipSelect.Tables[0];
totalZip = dt.Rows.Count + cntyTable.Rows.Count;
if (totalZip < MAXZIPCOUNT)
{
foreach (DataRow aRow in cntyTable.Rows)
{
zipCd = aRow[1].ToString();
AddSelectedZip(zipCd);
}
}
else
{
zipErrMsg.Text = "You have exceeded the maximum of " + MAXZIPCOUNT.ToString() + " zip codes. Please narrow your search. <br>";
zipErrMsg.Visible = true;
}
}
private void AddSelectedZip(string zipcd)
{
DataTable dt = SelectedZipTable;
string selectExpr = "zip_code ='" + zipcd +"'";
DataRow[] foundRow = dt.Select(selectExpr);
if (foundRow.Length ==0)
{
DataRow dr = dt.NewRow();
dr[0]=zipcd;
dt.Rows.Add(dr);
BindSelectedZip();
}
}

private void btnRemoveAll_Click(object sender, System.EventArgs e)
{
SelectedZipTable.Clear();
zipErrMsg.Visible = false;
All_ZIP_SELECTED = false;
BindSelectedZip();
}

private void btnAddAllZip_Click(object sender, System.EventArgs e)
{
OnBubbleClick(e);
SelectedZipTable.Clear();
AddSelectedZip("All NYS Zip");
All_ZIP_SELECTED = true;
}
protected void OnBubbleClick(EventArgs e)
{
if(BubbleClick != null)
{
BubbleClick(this, e);
}
}
#endregion

protected void ziprepeater_ItemCommand1(object source, RepeaterCommandEventArgs e)
{

}

}
}

None of the click events for the images created on the fly fire as I said in first posting. You can see that the html generated by the server does not have any events.

AJAX and Database

I'm creating this ASP registration page and some of the dropdowns are based on the previous selection made. I was wondering if someone can provide an example how to accomplish that task...

Say I have 3 dropdowns :

First get populated with Page_Load and based on that selection second gets populated and based on second third gets populated.

Thanks,

Harsimrat

The ajax control toolkit contains a CascadingDropdown solution.

Check it out here:http://ajax.asp.net/ajaxtoolkit/CascadingDropDown/CascadingDropDown.aspx