summaryrefslogtreecommitdiffstats
path: root/samples/OpenIdProviderWebForms
diff options
context:
space:
mode:
Diffstat (limited to 'samples/OpenIdProviderWebForms')
-rw-r--r--samples/OpenIdProviderWebForms/.gitignore5
-rw-r--r--samples/OpenIdProviderWebForms/App_Data/.gitignore1
-rw-r--r--samples/OpenIdProviderWebForms/App_Data/Users.xml23
-rw-r--r--samples/OpenIdProviderWebForms/Code/CustomStore.cs89
-rw-r--r--samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.Designer.cs621
-rw-r--r--samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.xsc9
-rw-r--r--samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.xsd33
-rw-r--r--samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.xss12
-rw-r--r--samples/OpenIdProviderWebForms/Code/ReadOnlyXmlMembershipProvider.cs270
-rw-r--r--samples/OpenIdProviderWebForms/Code/TracePageAppender.cs13
-rw-r--r--samples/OpenIdProviderWebForms/Code/URLRewriter.cs61
-rw-r--r--samples/OpenIdProviderWebForms/Code/Util.cs56
-rw-r--r--samples/OpenIdProviderWebForms/Default.aspx53
-rw-r--r--samples/OpenIdProviderWebForms/Global.asax1
-rw-r--r--samples/OpenIdProviderWebForms/Global.asax.cs82
-rw-r--r--samples/OpenIdProviderWebForms/OpenIdProviderWebForms.csproj191
-rw-r--r--samples/OpenIdProviderWebForms/ProfileFields.ascx1024
-rw-r--r--samples/OpenIdProviderWebForms/ProfileFields.ascx.cs137
-rw-r--r--samples/OpenIdProviderWebForms/ProfileFields.ascx.designer.cs286
-rw-r--r--samples/OpenIdProviderWebForms/Properties/AssemblyInfo.cs35
-rw-r--r--samples/OpenIdProviderWebForms/Provider.ashx1
-rw-r--r--samples/OpenIdProviderWebForms/Provider.ashx.cs61
-rw-r--r--samples/OpenIdProviderWebForms/Site.Master20
-rw-r--r--samples/OpenIdProviderWebForms/TracePage.aspx16
-rw-r--r--samples/OpenIdProviderWebForms/TracePage.aspx.cs21
-rw-r--r--samples/OpenIdProviderWebForms/TracePage.aspx.designer.cs43
-rw-r--r--samples/OpenIdProviderWebForms/Web.config192
-rw-r--r--samples/OpenIdProviderWebForms/decide.aspx34
-rw-r--r--samples/OpenIdProviderWebForms/decide.aspx.cs75
-rw-r--r--samples/OpenIdProviderWebForms/decide.aspx.designer.cs70
-rw-r--r--samples/OpenIdProviderWebForms/favicon.icobin0 -> 318 bytes
-rw-r--r--samples/OpenIdProviderWebForms/images/dotnetopenid_tiny.gifbin0 -> 3548 bytes
-rw-r--r--samples/OpenIdProviderWebForms/login.aspx17
-rw-r--r--samples/OpenIdProviderWebForms/login.aspx.cs22
-rw-r--r--samples/OpenIdProviderWebForms/login.aspx.designer.cs25
-rw-r--r--samples/OpenIdProviderWebForms/op_xrds.aspx19
-rw-r--r--samples/OpenIdProviderWebForms/server.aspx53
-rw-r--r--samples/OpenIdProviderWebForms/server.aspx.cs18
-rw-r--r--samples/OpenIdProviderWebForms/server.aspx.designer.cs25
-rw-r--r--samples/OpenIdProviderWebForms/styles.css10
-rw-r--r--samples/OpenIdProviderWebForms/user.aspx17
-rw-r--r--samples/OpenIdProviderWebForms/user.aspx.cs33
-rw-r--r--samples/OpenIdProviderWebForms/user.aspx.designer.cs43
-rw-r--r--samples/OpenIdProviderWebForms/user_xrds.aspx24
44 files changed, 3841 insertions, 0 deletions
diff --git a/samples/OpenIdProviderWebForms/.gitignore b/samples/OpenIdProviderWebForms/.gitignore
new file mode 100644
index 0000000..b086a60
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/.gitignore
@@ -0,0 +1,5 @@
+Bin
+obj
+*.user
+*.log
+StyleCop.Cache
diff --git a/samples/OpenIdProviderWebForms/App_Data/.gitignore b/samples/OpenIdProviderWebForms/App_Data/.gitignore
new file mode 100644
index 0000000..cb89d8a
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/App_Data/.gitignore
@@ -0,0 +1 @@
+*.LDF
diff --git a/samples/OpenIdProviderWebForms/App_Data/Users.xml b/samples/OpenIdProviderWebForms/App_Data/Users.xml
new file mode 100644
index 0000000..cffe009
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/App_Data/Users.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<Users>
+ <User>
+ <UserName>bob</UserName>
+ <Password>test</Password>
+ </User>
+ <User>
+ <UserName>bob1</UserName>
+ <Password>test</Password>
+ </User>
+ <User>
+ <UserName>bob2</UserName>
+ <Password>test</Password>
+ </User>
+ <User>
+ <UserName>bob3</UserName>
+ <Password>test</Password>
+ </User>
+ <User>
+ <UserName>bob4</UserName>
+ <Password>test</Password>
+ </User>
+</Users>
diff --git a/samples/OpenIdProviderWebForms/Code/CustomStore.cs b/samples/OpenIdProviderWebForms/Code/CustomStore.cs
new file mode 100644
index 0000000..8031a59
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/Code/CustomStore.cs
@@ -0,0 +1,89 @@
+//-----------------------------------------------------------------------
+// <copyright file="CustomStore.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace OpenIdProviderWebForms.Code {
+ using System;
+ using System.Data;
+ using System.Globalization;
+ using System.Security.Cryptography;
+ using DotNetOpenAuth.OpenId;
+ using IProviderAssociationStore = DotNetOpenAuth.OpenId.IAssociationStore<DotNetOpenAuth.OpenId.AssociationRelyingPartyType>;
+
+ /// <summary>
+ /// This custom store serializes all elements to demonstrate peristent and/or shared storage.
+ /// This is common in a web farm, for example.
+ /// </summary>
+ /// <remarks>
+ /// This doesn't actually serialize anything to a persistent store, so restarting the web server
+ /// will still clear everything this store is supposed to remember.
+ /// But we "persist" all associations and nonces into a DataTable to demonstrate
+ /// that using a database is possible.
+ /// </remarks>
+ public class CustomStore : IProviderAssociationStore {
+ private static CustomStoreDataSet dataSet = new CustomStoreDataSet();
+
+ #region IAssociationStore<AssociationRelyingPartyType> Members
+
+ public void StoreAssociation(AssociationRelyingPartyType distinguishingFactor, Association assoc) {
+ var assocRow = dataSet.Association.NewAssociationRow();
+ assocRow.DistinguishingFactor = distinguishingFactor.ToString();
+ assocRow.Handle = assoc.Handle;
+ assocRow.Expires = assoc.Expires.ToLocalTime();
+ assocRow.PrivateData = assoc.SerializePrivateData();
+ dataSet.Association.AddAssociationRow(assocRow);
+ }
+
+ public Association GetAssociation(AssociationRelyingPartyType distinguishingFactor) {
+ // properly escape the URL to prevent injection attacks.
+ string value = distinguishingFactor.ToString();
+ string filter = string.Format(
+ CultureInfo.InvariantCulture,
+ "{0} = '{1}'",
+ dataSet.Association.DistinguishingFactorColumn.ColumnName,
+ value);
+ string sort = dataSet.Association.ExpiresColumn.ColumnName + " DESC";
+ DataView view = new DataView(dataSet.Association, filter, sort, DataViewRowState.CurrentRows);
+ if (view.Count == 0) {
+ return null;
+ }
+ var row = (CustomStoreDataSet.AssociationRow)view[0].Row;
+ return Association.Deserialize(row.Handle, row.Expires.ToUniversalTime(), row.PrivateData);
+ }
+
+ public Association GetAssociation(AssociationRelyingPartyType distinguishingFactor, string handle) {
+ var assocRow = dataSet.Association.FindByDistinguishingFactorHandle(distinguishingFactor.ToString(), handle);
+ return Association.Deserialize(assocRow.Handle, assocRow.Expires, assocRow.PrivateData);
+ }
+
+ public bool RemoveAssociation(AssociationRelyingPartyType distinguishingFactor, string handle) {
+ var row = dataSet.Association.FindByDistinguishingFactorHandle(distinguishingFactor.ToString(), handle);
+ if (row != null) {
+ dataSet.Association.RemoveAssociationRow(row);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public void ClearExpiredAssociations() {
+ this.removeExpiredRows(dataSet.Association, dataSet.Association.ExpiresColumn.ColumnName);
+ }
+
+ #endregion
+
+ private void removeExpiredRows(DataTable table, string expiredColumnName) {
+ string filter = string.Format(
+ CultureInfo.InvariantCulture,
+ "{0} < #{1}#",
+ expiredColumnName,
+ DateTime.Now);
+ DataView view = new DataView(table, filter, null, DataViewRowState.CurrentRows);
+ for (int i = view.Count - 1; i >= 0; i--) {
+ view.Delete(i);
+ }
+ }
+ }
+}
diff --git a/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.Designer.cs b/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.Designer.cs
new file mode 100644
index 0000000..58c20a9
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.Designer.cs
@@ -0,0 +1,621 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.3521
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+#pragma warning disable 1591
+
+namespace OpenIdProviderWebForms.Code {
+
+
+ /// <summary>
+ ///Represents a strongly typed in-memory cache of data.
+ ///</summary>
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "2.0.0.0")]
+ [global::System.Serializable()]
+ [global::System.ComponentModel.DesignerCategoryAttribute("code")]
+ [global::System.ComponentModel.ToolboxItem(true)]
+ [global::System.Xml.Serialization.XmlSchemaProviderAttribute("GetTypedDataSetSchema")]
+ [global::System.Xml.Serialization.XmlRootAttribute("CustomStoreDataSet")]
+ [global::System.ComponentModel.Design.HelpKeywordAttribute("vs.data.DataSet")]
+ public partial class CustomStoreDataSet : global::System.Data.DataSet {
+
+ private AssociationDataTable tableAssociation;
+
+ private global::System.Data.SchemaSerializationMode _schemaSerializationMode = global::System.Data.SchemaSerializationMode.IncludeSchema;
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public CustomStoreDataSet() {
+ this.BeginInit();
+ this.InitClass();
+ global::System.ComponentModel.CollectionChangeEventHandler schemaChangedHandler = new global::System.ComponentModel.CollectionChangeEventHandler(this.SchemaChanged);
+ base.Tables.CollectionChanged += schemaChangedHandler;
+ base.Relations.CollectionChanged += schemaChangedHandler;
+ this.EndInit();
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ protected CustomStoreDataSet(global::System.Runtime.Serialization.SerializationInfo info, global::System.Runtime.Serialization.StreamingContext context) :
+ base(info, context, false) {
+ if ((this.IsBinarySerialized(info, context) == true)) {
+ this.InitVars(false);
+ global::System.ComponentModel.CollectionChangeEventHandler schemaChangedHandler1 = new global::System.ComponentModel.CollectionChangeEventHandler(this.SchemaChanged);
+ this.Tables.CollectionChanged += schemaChangedHandler1;
+ this.Relations.CollectionChanged += schemaChangedHandler1;
+ return;
+ }
+ string strSchema = ((string)(info.GetValue("XmlSchema", typeof(string))));
+ if ((this.DetermineSchemaSerializationMode(info, context) == global::System.Data.SchemaSerializationMode.IncludeSchema)) {
+ global::System.Data.DataSet ds = new global::System.Data.DataSet();
+ ds.ReadXmlSchema(new global::System.Xml.XmlTextReader(new global::System.IO.StringReader(strSchema)));
+ if ((ds.Tables["Association"] != null)) {
+ base.Tables.Add(new AssociationDataTable(ds.Tables["Association"]));
+ }
+ this.DataSetName = ds.DataSetName;
+ this.Prefix = ds.Prefix;
+ this.Namespace = ds.Namespace;
+ this.Locale = ds.Locale;
+ this.CaseSensitive = ds.CaseSensitive;
+ this.EnforceConstraints = ds.EnforceConstraints;
+ this.Merge(ds, false, global::System.Data.MissingSchemaAction.Add);
+ this.InitVars();
+ }
+ else {
+ this.ReadXmlSchema(new global::System.Xml.XmlTextReader(new global::System.IO.StringReader(strSchema)));
+ }
+ this.GetSerializationData(info, context);
+ global::System.ComponentModel.CollectionChangeEventHandler schemaChangedHandler = new global::System.ComponentModel.CollectionChangeEventHandler(this.SchemaChanged);
+ base.Tables.CollectionChanged += schemaChangedHandler;
+ this.Relations.CollectionChanged += schemaChangedHandler;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.ComponentModel.Browsable(false)]
+ [global::System.ComponentModel.DesignerSerializationVisibility(global::System.ComponentModel.DesignerSerializationVisibility.Content)]
+ public AssociationDataTable Association {
+ get {
+ return this.tableAssociation;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.ComponentModel.BrowsableAttribute(true)]
+ [global::System.ComponentModel.DesignerSerializationVisibilityAttribute(global::System.ComponentModel.DesignerSerializationVisibility.Visible)]
+ public override global::System.Data.SchemaSerializationMode SchemaSerializationMode {
+ get {
+ return this._schemaSerializationMode;
+ }
+ set {
+ this._schemaSerializationMode = value;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.ComponentModel.DesignerSerializationVisibilityAttribute(global::System.ComponentModel.DesignerSerializationVisibility.Hidden)]
+ public new global::System.Data.DataTableCollection Tables {
+ get {
+ return base.Tables;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.ComponentModel.DesignerSerializationVisibilityAttribute(global::System.ComponentModel.DesignerSerializationVisibility.Hidden)]
+ public new global::System.Data.DataRelationCollection Relations {
+ get {
+ return base.Relations;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ protected override void InitializeDerivedDataSet() {
+ this.BeginInit();
+ this.InitClass();
+ this.EndInit();
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public override global::System.Data.DataSet Clone() {
+ CustomStoreDataSet cln = ((CustomStoreDataSet)(base.Clone()));
+ cln.InitVars();
+ cln.SchemaSerializationMode = this.SchemaSerializationMode;
+ return cln;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ protected override bool ShouldSerializeTables() {
+ return false;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ protected override bool ShouldSerializeRelations() {
+ return false;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ protected override void ReadXmlSerializable(global::System.Xml.XmlReader reader) {
+ if ((this.DetermineSchemaSerializationMode(reader) == global::System.Data.SchemaSerializationMode.IncludeSchema)) {
+ this.Reset();
+ global::System.Data.DataSet ds = new global::System.Data.DataSet();
+ ds.ReadXml(reader);
+ if ((ds.Tables["Association"] != null)) {
+ base.Tables.Add(new AssociationDataTable(ds.Tables["Association"]));
+ }
+ this.DataSetName = ds.DataSetName;
+ this.Prefix = ds.Prefix;
+ this.Namespace = ds.Namespace;
+ this.Locale = ds.Locale;
+ this.CaseSensitive = ds.CaseSensitive;
+ this.EnforceConstraints = ds.EnforceConstraints;
+ this.Merge(ds, false, global::System.Data.MissingSchemaAction.Add);
+ this.InitVars();
+ }
+ else {
+ this.ReadXml(reader);
+ this.InitVars();
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ protected override global::System.Xml.Schema.XmlSchema GetSchemaSerializable() {
+ global::System.IO.MemoryStream stream = new global::System.IO.MemoryStream();
+ this.WriteXmlSchema(new global::System.Xml.XmlTextWriter(stream, null));
+ stream.Position = 0;
+ return global::System.Xml.Schema.XmlSchema.Read(new global::System.Xml.XmlTextReader(stream), null);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ internal void InitVars() {
+ this.InitVars(true);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ internal void InitVars(bool initTable) {
+ this.tableAssociation = ((AssociationDataTable)(base.Tables["Association"]));
+ if ((initTable == true)) {
+ if ((this.tableAssociation != null)) {
+ this.tableAssociation.InitVars();
+ }
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ private void InitClass() {
+ this.DataSetName = "CustomStoreDataSet";
+ this.Prefix = "";
+ this.Namespace = "http://tempuri.org/CustomStoreDataSet.xsd";
+ this.EnforceConstraints = true;
+ this.SchemaSerializationMode = global::System.Data.SchemaSerializationMode.IncludeSchema;
+ this.tableAssociation = new AssociationDataTable();
+ base.Tables.Add(this.tableAssociation);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ private bool ShouldSerializeAssociation() {
+ return false;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ private void SchemaChanged(object sender, global::System.ComponentModel.CollectionChangeEventArgs e) {
+ if ((e.Action == global::System.ComponentModel.CollectionChangeAction.Remove)) {
+ this.InitVars();
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public static global::System.Xml.Schema.XmlSchemaComplexType GetTypedDataSetSchema(global::System.Xml.Schema.XmlSchemaSet xs) {
+ CustomStoreDataSet ds = new CustomStoreDataSet();
+ global::System.Xml.Schema.XmlSchemaComplexType type = new global::System.Xml.Schema.XmlSchemaComplexType();
+ global::System.Xml.Schema.XmlSchemaSequence sequence = new global::System.Xml.Schema.XmlSchemaSequence();
+ global::System.Xml.Schema.XmlSchemaAny any = new global::System.Xml.Schema.XmlSchemaAny();
+ any.Namespace = ds.Namespace;
+ sequence.Items.Add(any);
+ type.Particle = sequence;
+ global::System.Xml.Schema.XmlSchema dsSchema = ds.GetSchemaSerializable();
+ if (xs.Contains(dsSchema.TargetNamespace)) {
+ global::System.IO.MemoryStream s1 = new global::System.IO.MemoryStream();
+ global::System.IO.MemoryStream s2 = new global::System.IO.MemoryStream();
+ try {
+ global::System.Xml.Schema.XmlSchema schema = null;
+ dsSchema.Write(s1);
+ for (global::System.Collections.IEnumerator schemas = xs.Schemas(dsSchema.TargetNamespace).GetEnumerator(); schemas.MoveNext(); ) {
+ schema = ((global::System.Xml.Schema.XmlSchema)(schemas.Current));
+ s2.SetLength(0);
+ schema.Write(s2);
+ if ((s1.Length == s2.Length)) {
+ s1.Position = 0;
+ s2.Position = 0;
+ for (; ((s1.Position != s1.Length)
+ && (s1.ReadByte() == s2.ReadByte())); ) {
+ ;
+ }
+ if ((s1.Position == s1.Length)) {
+ return type;
+ }
+ }
+ }
+ }
+ finally {
+ if ((s1 != null)) {
+ s1.Close();
+ }
+ if ((s2 != null)) {
+ s2.Close();
+ }
+ }
+ }
+ xs.Add(dsSchema);
+ return type;
+ }
+
+ public delegate void AssociationRowChangeEventHandler(object sender, AssociationRowChangeEvent e);
+
+ /// <summary>
+ ///Represents the strongly named DataTable class.
+ ///</summary>
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "2.0.0.0")]
+ [global::System.Serializable()]
+ [global::System.Xml.Serialization.XmlSchemaProviderAttribute("GetTypedTableSchema")]
+ public partial class AssociationDataTable : global::System.Data.TypedTableBase<AssociationRow> {
+
+ private global::System.Data.DataColumn columnDistinguishingFactor;
+
+ private global::System.Data.DataColumn columnHandle;
+
+ private global::System.Data.DataColumn columnExpires;
+
+ private global::System.Data.DataColumn columnPrivateData;
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public AssociationDataTable() {
+ this.TableName = "Association";
+ this.BeginInit();
+ this.InitClass();
+ this.EndInit();
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ internal AssociationDataTable(global::System.Data.DataTable table) {
+ this.TableName = table.TableName;
+ if ((table.CaseSensitive != table.DataSet.CaseSensitive)) {
+ this.CaseSensitive = table.CaseSensitive;
+ }
+ if ((table.Locale.ToString() != table.DataSet.Locale.ToString())) {
+ this.Locale = table.Locale;
+ }
+ if ((table.Namespace != table.DataSet.Namespace)) {
+ this.Namespace = table.Namespace;
+ }
+ this.Prefix = table.Prefix;
+ this.MinimumCapacity = table.MinimumCapacity;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ protected AssociationDataTable(global::System.Runtime.Serialization.SerializationInfo info, global::System.Runtime.Serialization.StreamingContext context) :
+ base(info, context) {
+ this.InitVars();
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public global::System.Data.DataColumn DistinguishingFactorColumn {
+ get {
+ return this.columnDistinguishingFactor;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public global::System.Data.DataColumn HandleColumn {
+ get {
+ return this.columnHandle;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public global::System.Data.DataColumn ExpiresColumn {
+ get {
+ return this.columnExpires;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public global::System.Data.DataColumn PrivateDataColumn {
+ get {
+ return this.columnPrivateData;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.ComponentModel.Browsable(false)]
+ public int Count {
+ get {
+ return this.Rows.Count;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public AssociationRow this[int index] {
+ get {
+ return ((AssociationRow)(this.Rows[index]));
+ }
+ }
+
+ public event AssociationRowChangeEventHandler AssociationRowChanging;
+
+ public event AssociationRowChangeEventHandler AssociationRowChanged;
+
+ public event AssociationRowChangeEventHandler AssociationRowDeleting;
+
+ public event AssociationRowChangeEventHandler AssociationRowDeleted;
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public void AddAssociationRow(AssociationRow row) {
+ this.Rows.Add(row);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public AssociationRow AddAssociationRow(string DistinguishingFactor, string Handle, System.DateTime Expires, byte[] PrivateData) {
+ AssociationRow rowAssociationRow = ((AssociationRow)(this.NewRow()));
+ object[] columnValuesArray = new object[] {
+ DistinguishingFactor,
+ Handle,
+ Expires,
+ PrivateData};
+ rowAssociationRow.ItemArray = columnValuesArray;
+ this.Rows.Add(rowAssociationRow);
+ return rowAssociationRow;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public AssociationRow FindByDistinguishingFactorHandle(string DistinguishingFactor, string Handle) {
+ return ((AssociationRow)(this.Rows.Find(new object[] {
+ DistinguishingFactor,
+ Handle})));
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public override global::System.Data.DataTable Clone() {
+ AssociationDataTable cln = ((AssociationDataTable)(base.Clone()));
+ cln.InitVars();
+ return cln;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ protected override global::System.Data.DataTable CreateInstance() {
+ return new AssociationDataTable();
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ internal void InitVars() {
+ this.columnDistinguishingFactor = base.Columns["DistinguishingFactor"];
+ this.columnHandle = base.Columns["Handle"];
+ this.columnExpires = base.Columns["Expires"];
+ this.columnPrivateData = base.Columns["PrivateData"];
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ private void InitClass() {
+ this.columnDistinguishingFactor = new global::System.Data.DataColumn("DistinguishingFactor", typeof(string), null, global::System.Data.MappingType.Element);
+ base.Columns.Add(this.columnDistinguishingFactor);
+ this.columnHandle = new global::System.Data.DataColumn("Handle", typeof(string), null, global::System.Data.MappingType.Element);
+ base.Columns.Add(this.columnHandle);
+ this.columnExpires = new global::System.Data.DataColumn("Expires", typeof(global::System.DateTime), null, global::System.Data.MappingType.Element);
+ base.Columns.Add(this.columnExpires);
+ this.columnPrivateData = new global::System.Data.DataColumn("PrivateData", typeof(byte[]), null, global::System.Data.MappingType.Element);
+ base.Columns.Add(this.columnPrivateData);
+ this.Constraints.Add(new global::System.Data.UniqueConstraint("PrimaryKey", new global::System.Data.DataColumn[] {
+ this.columnDistinguishingFactor,
+ this.columnHandle}, true));
+ this.columnDistinguishingFactor.AllowDBNull = false;
+ this.columnHandle.AllowDBNull = false;
+ this.columnExpires.AllowDBNull = false;
+ this.columnPrivateData.AllowDBNull = false;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public AssociationRow NewAssociationRow() {
+ return ((AssociationRow)(this.NewRow()));
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ protected override global::System.Data.DataRow NewRowFromBuilder(global::System.Data.DataRowBuilder builder) {
+ return new AssociationRow(builder);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ protected override global::System.Type GetRowType() {
+ return typeof(AssociationRow);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ protected override void OnRowChanged(global::System.Data.DataRowChangeEventArgs e) {
+ base.OnRowChanged(e);
+ if ((this.AssociationRowChanged != null)) {
+ this.AssociationRowChanged(this, new AssociationRowChangeEvent(((AssociationRow)(e.Row)), e.Action));
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ protected override void OnRowChanging(global::System.Data.DataRowChangeEventArgs e) {
+ base.OnRowChanging(e);
+ if ((this.AssociationRowChanging != null)) {
+ this.AssociationRowChanging(this, new AssociationRowChangeEvent(((AssociationRow)(e.Row)), e.Action));
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ protected override void OnRowDeleted(global::System.Data.DataRowChangeEventArgs e) {
+ base.OnRowDeleted(e);
+ if ((this.AssociationRowDeleted != null)) {
+ this.AssociationRowDeleted(this, new AssociationRowChangeEvent(((AssociationRow)(e.Row)), e.Action));
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ protected override void OnRowDeleting(global::System.Data.DataRowChangeEventArgs e) {
+ base.OnRowDeleting(e);
+ if ((this.AssociationRowDeleting != null)) {
+ this.AssociationRowDeleting(this, new AssociationRowChangeEvent(((AssociationRow)(e.Row)), e.Action));
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public void RemoveAssociationRow(AssociationRow row) {
+ this.Rows.Remove(row);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public static global::System.Xml.Schema.XmlSchemaComplexType GetTypedTableSchema(global::System.Xml.Schema.XmlSchemaSet xs) {
+ global::System.Xml.Schema.XmlSchemaComplexType type = new global::System.Xml.Schema.XmlSchemaComplexType();
+ global::System.Xml.Schema.XmlSchemaSequence sequence = new global::System.Xml.Schema.XmlSchemaSequence();
+ CustomStoreDataSet ds = new CustomStoreDataSet();
+ global::System.Xml.Schema.XmlSchemaAny any1 = new global::System.Xml.Schema.XmlSchemaAny();
+ any1.Namespace = "http://www.w3.org/2001/XMLSchema";
+ any1.MinOccurs = new decimal(0);
+ any1.MaxOccurs = decimal.MaxValue;
+ any1.ProcessContents = global::System.Xml.Schema.XmlSchemaContentProcessing.Lax;
+ sequence.Items.Add(any1);
+ global::System.Xml.Schema.XmlSchemaAny any2 = new global::System.Xml.Schema.XmlSchemaAny();
+ any2.Namespace = "urn:schemas-microsoft-com:xml-diffgram-v1";
+ any2.MinOccurs = new decimal(1);
+ any2.ProcessContents = global::System.Xml.Schema.XmlSchemaContentProcessing.Lax;
+ sequence.Items.Add(any2);
+ global::System.Xml.Schema.XmlSchemaAttribute attribute1 = new global::System.Xml.Schema.XmlSchemaAttribute();
+ attribute1.Name = "namespace";
+ attribute1.FixedValue = ds.Namespace;
+ type.Attributes.Add(attribute1);
+ global::System.Xml.Schema.XmlSchemaAttribute attribute2 = new global::System.Xml.Schema.XmlSchemaAttribute();
+ attribute2.Name = "tableTypeName";
+ attribute2.FixedValue = "AssociationDataTable";
+ type.Attributes.Add(attribute2);
+ type.Particle = sequence;
+ global::System.Xml.Schema.XmlSchema dsSchema = ds.GetSchemaSerializable();
+ if (xs.Contains(dsSchema.TargetNamespace)) {
+ global::System.IO.MemoryStream s1 = new global::System.IO.MemoryStream();
+ global::System.IO.MemoryStream s2 = new global::System.IO.MemoryStream();
+ try {
+ global::System.Xml.Schema.XmlSchema schema = null;
+ dsSchema.Write(s1);
+ for (global::System.Collections.IEnumerator schemas = xs.Schemas(dsSchema.TargetNamespace).GetEnumerator(); schemas.MoveNext(); ) {
+ schema = ((global::System.Xml.Schema.XmlSchema)(schemas.Current));
+ s2.SetLength(0);
+ schema.Write(s2);
+ if ((s1.Length == s2.Length)) {
+ s1.Position = 0;
+ s2.Position = 0;
+ for (; ((s1.Position != s1.Length)
+ && (s1.ReadByte() == s2.ReadByte())); ) {
+ ;
+ }
+ if ((s1.Position == s1.Length)) {
+ return type;
+ }
+ }
+ }
+ }
+ finally {
+ if ((s1 != null)) {
+ s1.Close();
+ }
+ if ((s2 != null)) {
+ s2.Close();
+ }
+ }
+ }
+ xs.Add(dsSchema);
+ return type;
+ }
+ }
+
+ /// <summary>
+ ///Represents strongly named DataRow class.
+ ///</summary>
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "2.0.0.0")]
+ public partial class AssociationRow : global::System.Data.DataRow {
+
+ private AssociationDataTable tableAssociation;
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ internal AssociationRow(global::System.Data.DataRowBuilder rb) :
+ base(rb) {
+ this.tableAssociation = ((AssociationDataTable)(this.Table));
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public string DistinguishingFactor {
+ get {
+ return ((string)(this[this.tableAssociation.DistinguishingFactorColumn]));
+ }
+ set {
+ this[this.tableAssociation.DistinguishingFactorColumn] = value;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public string Handle {
+ get {
+ return ((string)(this[this.tableAssociation.HandleColumn]));
+ }
+ set {
+ this[this.tableAssociation.HandleColumn] = value;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public System.DateTime Expires {
+ get {
+ return ((global::System.DateTime)(this[this.tableAssociation.ExpiresColumn]));
+ }
+ set {
+ this[this.tableAssociation.ExpiresColumn] = value;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public byte[] PrivateData {
+ get {
+ return ((byte[])(this[this.tableAssociation.PrivateDataColumn]));
+ }
+ set {
+ this[this.tableAssociation.PrivateDataColumn] = value;
+ }
+ }
+ }
+
+ /// <summary>
+ ///Row event argument class
+ ///</summary>
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "2.0.0.0")]
+ public class AssociationRowChangeEvent : global::System.EventArgs {
+
+ private AssociationRow eventRow;
+
+ private global::System.Data.DataRowAction eventAction;
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public AssociationRowChangeEvent(AssociationRow row, global::System.Data.DataRowAction action) {
+ this.eventRow = row;
+ this.eventAction = action;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public AssociationRow Row {
+ get {
+ return this.eventRow;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public global::System.Data.DataRowAction Action {
+ get {
+ return this.eventAction;
+ }
+ }
+ }
+ }
+}
+
+#pragma warning restore 1591 \ No newline at end of file
diff --git a/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.xsc b/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.xsc
new file mode 100644
index 0000000..05b0199
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.xsc
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--<autogenerated>
+ This code was generated by a tool.
+ Changes to this file may cause incorrect behavior and will be lost if
+ the code is regenerated.
+</autogenerated>-->
+<DataSetUISetting Version="1.00" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
+ <TableUISettings />
+</DataSetUISetting> \ No newline at end of file
diff --git a/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.xsd b/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.xsd
new file mode 100644
index 0000000..63226bd
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.xsd
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema id="CustomStoreDataSet" targetNamespace="http://tempuri.org/CustomStoreDataSet.xsd" xmlns:mstns="http://tempuri.org/CustomStoreDataSet.xsd" xmlns="http://tempuri.org/CustomStoreDataSet.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:msprop="urn:schemas-microsoft-com:xml-msprop" attributeFormDefault="qualified" elementFormDefault="qualified">
+ <xs:annotation>
+ <xs:appinfo source="urn:schemas-microsoft-com:xml-msdatasource">
+ <DataSource DefaultConnectionIndex="0" FunctionsComponentName="QueriesTableAdapter" Modifier="AutoLayout, AnsiClass, Class, Public" SchemaSerializationMode="IncludeSchema" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
+ <Connections />
+ <Tables />
+ <Sources />
+ </DataSource>
+ </xs:appinfo>
+ </xs:annotation>
+ <xs:element name="CustomStoreDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true" msprop:Generator_UserDSName="CustomStoreDataSet" msprop:Generator_DataSetName="CustomStoreDataSet" msprop:EnableTableAdapterManager="true">
+ <xs:complexType>
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="Association" msprop:Generator_UserTableName="Association" msprop:Generator_RowDeletedName="AssociationRowDeleted" msprop:Generator_RowChangedName="AssociationRowChanged" msprop:Generator_RowClassName="AssociationRow" msprop:Generator_RowChangingName="AssociationRowChanging" msprop:Generator_RowEvArgName="AssociationRowChangeEvent" msprop:Generator_RowEvHandlerName="AssociationRowChangeEventHandler" msprop:Generator_TableClassName="AssociationDataTable" msprop:Generator_TableVarName="tableAssociation" msprop:Generator_RowDeletingName="AssociationRowDeleting" msprop:Generator_TablePropName="Association">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="DistinguishingFactor" msprop:Generator_UserColumnName="DistinguishingFactor" msprop:Generator_ColumnPropNameInRow="DistinguishingFactor" msprop:Generator_ColumnVarNameInTable="columnDistinguishingFactor" msprop:Generator_ColumnPropNameInTable="DistinguishingFactorColumn" type="xs:string" />
+ <xs:element name="Handle" msprop:Generator_UserColumnName="Handle" msprop:Generator_ColumnPropNameInRow="Handle" msprop:Generator_ColumnVarNameInTable="columnHandle" msprop:Generator_ColumnPropNameInTable="HandleColumn" type="xs:string" />
+ <xs:element name="Expires" msprop:Generator_UserColumnName="Expires" msprop:Generator_ColumnPropNameInRow="Expires" msprop:Generator_ColumnVarNameInTable="columnExpires" msprop:Generator_ColumnPropNameInTable="ExpiresColumn" type="xs:dateTime" />
+ <xs:element name="PrivateData" msprop:Generator_UserColumnName="PrivateData" msprop:Generator_ColumnPropNameInRow="PrivateData" msprop:Generator_ColumnVarNameInTable="columnPrivateData" msprop:Generator_ColumnPropNameInTable="PrivateDataColumn" type="xs:base64Binary" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:choice>
+ </xs:complexType>
+ <xs:unique name="PrimaryKey" msdata:PrimaryKey="true">
+ <xs:selector xpath=".//mstns:Association" />
+ <xs:field xpath="mstns:DistinguishingFactor" />
+ <xs:field xpath="mstns:Handle" />
+ </xs:unique>
+ </xs:element>
+</xs:schema> \ No newline at end of file
diff --git a/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.xss b/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.xss
new file mode 100644
index 0000000..0b3972e
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/Code/CustomStoreDataSet.xss
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--<autogenerated>
+ This code was generated by a tool to store the dataset designer's layout information.
+ Changes to this file may cause incorrect behavior and will be lost if
+ the code is regenerated.
+</autogenerated>-->
+<DiagramLayout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" ex:showrelationlabel="False" ViewPortX="0" ViewPortY="0" xmlns:ex="urn:schemas-microsoft-com:xml-msdatasource-layout-extended" xmlns="urn:schemas-microsoft-com:xml-msdatasource-layout">
+ <Shapes>
+ <Shape ID="DesignTable:Association" ZOrder="1" X="349" Y="83" Height="105" Width="154" AdapterExpanded="true" DataTableExpanded="true" OldAdapterHeight="0" OldDataTableHeight="0" SplitterPosition="101" />
+ </Shapes>
+ <Connectors />
+</DiagramLayout> \ No newline at end of file
diff --git a/samples/OpenIdProviderWebForms/Code/ReadOnlyXmlMembershipProvider.cs b/samples/OpenIdProviderWebForms/Code/ReadOnlyXmlMembershipProvider.cs
new file mode 100644
index 0000000..54db5c0
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/Code/ReadOnlyXmlMembershipProvider.cs
@@ -0,0 +1,270 @@
+namespace OpenIdProviderWebForms.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Collections.Specialized;
+ using System.Configuration.Provider;
+ using System.Security.Permissions;
+ using System.Web;
+ using System.Web.Hosting;
+ using System.Web.Security;
+ using System.Xml;
+
+ public class ReadOnlyXmlMembershipProvider : MembershipProvider {
+ private Dictionary<string, MembershipUser> users;
+ private string xmlFileName;
+
+ // MembershipProvider Properties
+ public override string ApplicationName {
+ get { throw new NotSupportedException(); }
+ set { throw new NotSupportedException(); }
+ }
+
+ public override bool EnablePasswordRetrieval {
+ get { return false; }
+ }
+
+ public override bool EnablePasswordReset {
+ get { return false; }
+ }
+
+ public override int MaxInvalidPasswordAttempts {
+ get { throw new NotSupportedException(); }
+ }
+
+ public override int MinRequiredNonAlphanumericCharacters {
+ get { throw new NotSupportedException(); }
+ }
+
+ public override int MinRequiredPasswordLength {
+ get { throw new NotSupportedException(); }
+ }
+
+ public override int PasswordAttemptWindow {
+ get { throw new NotSupportedException(); }
+ }
+
+ public override MembershipPasswordFormat PasswordFormat {
+ get { throw new NotSupportedException(); }
+ }
+
+ public override string PasswordStrengthRegularExpression {
+ get { throw new NotSupportedException(); }
+ }
+
+ public override bool RequiresQuestionAndAnswer {
+ get { throw new NotSupportedException(); }
+ }
+
+ public override bool RequiresUniqueEmail {
+ get { throw new NotSupportedException(); }
+ }
+
+ // MembershipProvider Methods
+ public override void Initialize(string name, NameValueCollection config) {
+ // Verify that config isn't null
+ if (config == null) {
+ throw new ArgumentNullException("config");
+ }
+
+ // Assign the provider a default name if it doesn't have one
+ if (string.IsNullOrEmpty(name)) {
+ name = "ReadOnlyXmlMembershipProvider";
+ }
+
+ // Add a default "description" attribute to config if the
+ // attribute doesn't exist or is empty
+ if (string.IsNullOrEmpty(config["description"])) {
+ config.Remove("description");
+ config.Add("description", "Read-only XML membership provider");
+ }
+
+ // Call the base class's Initialize method
+ base.Initialize(name, config);
+
+ // Initialize _XmlFileName and make sure the path
+ // is app-relative
+ string path = config["xmlFileName"];
+
+ if (string.IsNullOrEmpty(path)) {
+ path = "~/App_Data/Users.xml";
+ }
+
+ if (!VirtualPathUtility.IsAppRelative(path)) {
+ throw new ArgumentException("xmlFileName must be app-relative");
+ }
+
+ string fullyQualifiedPath = VirtualPathUtility.Combine(
+ VirtualPathUtility.AppendTrailingSlash(HttpRuntime.AppDomainAppVirtualPath),
+ path);
+
+ this.xmlFileName = HostingEnvironment.MapPath(fullyQualifiedPath);
+ config.Remove("xmlFileName");
+
+ // Make sure we have permission to read the XML data source and
+ // throw an exception if we don't
+ FileIOPermission permission = new FileIOPermission(FileIOPermissionAccess.Read, this.xmlFileName);
+ permission.Demand();
+
+ // Throw an exception if unrecognized attributes remain
+ if (config.Count > 0) {
+ string attr = config.GetKey(0);
+ if (!string.IsNullOrEmpty(attr)) {
+ throw new ProviderException("Unrecognized attribute: " + attr);
+ }
+ }
+ }
+
+ public override bool ValidateUser(string username, string password) {
+ // Validate input parameters
+ if (string.IsNullOrEmpty(username) ||
+ string.IsNullOrEmpty(password)) {
+ return false;
+ }
+
+ try {
+ // Make sure the data source has been loaded
+ this.ReadMembershipDataStore();
+
+ // Validate the user name and password
+ MembershipUser user;
+ if (this.users.TryGetValue(username, out user)) {
+ if (user.Comment == password) { // Case-sensitive
+ // NOTE: A read/write membership provider
+ // would update the user's LastLoginDate here.
+ // A fully featured provider would also fire
+ // an AuditMembershipAuthenticationSuccess
+ // Web event
+ return true;
+ }
+ }
+
+ // NOTE: A fully featured membership provider would
+ // fire an AuditMembershipAuthenticationFailure
+ // Web event here
+ return false;
+ } catch (Exception) {
+ return false;
+ }
+ }
+
+ public override MembershipUser GetUser(string username, bool userIsOnline) {
+ // Note: This implementation ignores userIsOnline
+
+ // Validate input parameters
+ if (string.IsNullOrEmpty(username)) {
+ return null;
+ }
+
+ // Make sure the data source has been loaded
+ this.ReadMembershipDataStore();
+
+ // Retrieve the user from the data source
+ MembershipUser user;
+ if (this.users.TryGetValue(username, out user)) {
+ return user;
+ }
+
+ return null;
+ }
+
+ public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords) {
+ // Note: This implementation ignores pageIndex and pageSize,
+ // and it doesn't sort the MembershipUser objects returned
+
+ // Make sure the data source has been loaded
+ this.ReadMembershipDataStore();
+
+ MembershipUserCollection users = new MembershipUserCollection();
+
+ foreach (KeyValuePair<string, MembershipUser> pair in this.users) {
+ users.Add(pair.Value);
+ }
+
+ totalRecords = users.Count;
+ return users;
+ }
+
+ public override int GetNumberOfUsersOnline() {
+ throw new NotSupportedException();
+ }
+
+ public override bool ChangePassword(string username, string oldPassword, string newPassword) {
+ throw new NotSupportedException();
+ }
+
+ public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer) {
+ throw new NotSupportedException();
+ }
+
+ public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status) {
+ throw new NotSupportedException();
+ }
+
+ public override bool DeleteUser(string username, bool deleteAllRelatedData) {
+ throw new NotSupportedException();
+ }
+
+ public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords) {
+ throw new NotSupportedException();
+ }
+
+ public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords) {
+ throw new NotSupportedException();
+ }
+
+ public override string GetPassword(string username, string answer) {
+ throw new NotSupportedException();
+ }
+
+ public override MembershipUser GetUser(object providerUserKey, bool userIsOnline) {
+ throw new NotSupportedException();
+ }
+
+ public override string GetUserNameByEmail(string email) {
+ throw new NotSupportedException();
+ }
+
+ public override string ResetPassword(string username, string answer) {
+ throw new NotSupportedException();
+ }
+
+ public override bool UnlockUser(string userName) {
+ throw new NotSupportedException();
+ }
+
+ public override void UpdateUser(MembershipUser user) {
+ throw new NotSupportedException();
+ }
+
+ // Helper method
+ private void ReadMembershipDataStore() {
+ lock (this) {
+ if (this.users == null) {
+ this.users = new Dictionary<string, MembershipUser>(16, StringComparer.InvariantCultureIgnoreCase);
+ XmlDocument doc = new XmlDocument();
+ doc.Load(this.xmlFileName);
+ XmlNodeList nodes = doc.GetElementsByTagName("User");
+
+ foreach (XmlNode node in nodes) {
+ MembershipUser user = new MembershipUser(
+ Name, // Provider name
+ node["UserName"].InnerText, // Username
+ null, // providerUserKey
+ null, // Email
+ string.Empty, // passwordQuestion
+ node["Password"].InnerText, // Comment
+ true, // isApproved
+ false, // isLockedOut
+ DateTime.Now, // creationDate
+ DateTime.Now, // lastLoginDate
+ DateTime.Now, // lastActivityDate
+ DateTime.Now, // lastPasswordChangedDate
+ new DateTime(1980, 1, 1)); // lastLockoutDate
+
+ this.users.Add(user.UserName, user);
+ }
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/samples/OpenIdProviderWebForms/Code/TracePageAppender.cs b/samples/OpenIdProviderWebForms/Code/TracePageAppender.cs
new file mode 100644
index 0000000..1bb7a34
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/Code/TracePageAppender.cs
@@ -0,0 +1,13 @@
+namespace OpenIdProviderWebForms.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Web;
+
+ public class TracePageAppender : log4net.Appender.AppenderSkeleton {
+ protected override void Append(log4net.Core.LoggingEvent loggingEvent) {
+ StringWriter sw = new StringWriter(Global.LogMessages);
+ Layout.Format(sw, loggingEvent);
+ }
+ }
+}
diff --git a/samples/OpenIdProviderWebForms/Code/URLRewriter.cs b/samples/OpenIdProviderWebForms/Code/URLRewriter.cs
new file mode 100644
index 0000000..daa4dea
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/Code/URLRewriter.cs
@@ -0,0 +1,61 @@
+namespace OpenIdProviderWebForms.Code {
+ using System.Configuration;
+ using System.Diagnostics;
+ using System.Text.RegularExpressions;
+ using System.Web;
+ using System.Xml;
+
+ // nicked from http://www.codeproject.com/aspnet/URLRewriter.asp
+ public class URLRewriter : IConfigurationSectionHandler {
+ public static log4net.ILog Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+
+ protected XmlNode rules = null;
+
+ protected URLRewriter() {
+ }
+
+ public static void Process() {
+ URLRewriter rewriter = (URLRewriter)ConfigurationManager.GetSection("urlrewrites");
+
+ string subst = rewriter.GetSubstitution(HttpContext.Current.Request.Path);
+
+ if (!string.IsNullOrEmpty(subst)) {
+ Logger.InfoFormat("Rewriting url '{0}' to '{1}' ", HttpContext.Current.Request.Path, subst);
+ HttpContext.Current.RewritePath(subst);
+ }
+ }
+
+ public string GetSubstitution(string path) {
+ foreach (XmlNode node in this.rules.SelectNodes("rule")) {
+ // get the url and rewrite nodes
+ XmlNode urlNode = node.SelectSingleNode("url");
+ XmlNode rewriteNode = node.SelectSingleNode("rewrite");
+
+ // check validity of the values
+ if (urlNode == null || string.IsNullOrEmpty(urlNode.InnerText)
+ || rewriteNode == null || string.IsNullOrEmpty(rewriteNode.InnerText)) {
+ Logger.Warn("Invalid urlrewrites rule discovered in web.config file.");
+ continue;
+ }
+
+ Regex reg = new Regex(urlNode.InnerText, RegexOptions.IgnoreCase);
+
+ // if match, return the substitution
+ Match match = reg.Match(path);
+ if (match.Success) {
+ return reg.Replace(path, rewriteNode.InnerText);
+ }
+ }
+
+ return null; // no rewrite
+ }
+
+ #region Implementation of IConfigurationSectionHandler
+ public object Create(object parent, object configContext, XmlNode section) {
+ this.rules = section;
+
+ return this;
+ }
+ #endregion
+ }
+} \ No newline at end of file
diff --git a/samples/OpenIdProviderWebForms/Code/Util.cs b/samples/OpenIdProviderWebForms/Code/Util.cs
new file mode 100644
index 0000000..5cec951
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/Code/Util.cs
@@ -0,0 +1,56 @@
+//-----------------------------------------------------------------------
+// <copyright file="Util.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace OpenIdProviderWebForms.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics;
+ using System.Net;
+ using System.Text;
+ using System.Web;
+ using DotNetOpenAuth.OpenId;
+ using DotNetOpenAuth.OpenId.Provider;
+
+ public class Util {
+ public static string ExtractUserName(Uri url) {
+ return url.Segments[url.Segments.Length - 1];
+ }
+
+ public static string ExtractUserName(Identifier identifier) {
+ return ExtractUserName(new Uri(identifier.ToString()));
+ }
+
+ public static Identifier BuildIdentityUrl() {
+ string username = HttpContext.Current.User.Identity.Name;
+
+ // be sure to normalize case the way the user's identity page does.
+ username = username.Substring(0, 1).ToUpperInvariant() + username.Substring(1).ToLowerInvariant();
+ return new Uri(HttpContext.Current.Request.Url, "/user/" + username);
+ }
+
+ internal static void ProcessAuthenticationChallenge(IAuthenticationRequest idrequest) {
+ if (idrequest.Immediate) {
+ if (idrequest.IsDirectedIdentity) {
+ if (HttpContext.Current.User.Identity.IsAuthenticated) {
+ idrequest.LocalIdentifier = Util.BuildIdentityUrl();
+ idrequest.IsAuthenticated = true;
+ } else {
+ idrequest.IsAuthenticated = false;
+ }
+ } else {
+ string userOwningOpenIdUrl = Util.ExtractUserName(idrequest.LocalIdentifier);
+
+ // NOTE: in a production provider site, you may want to only
+ // respond affirmatively if the user has already authorized this consumer
+ // to know the answer.
+ idrequest.IsAuthenticated = userOwningOpenIdUrl == HttpContext.Current.User.Identity.Name;
+ }
+ } else {
+ HttpContext.Current.Response.Redirect("~/decide.aspx", true);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/samples/OpenIdProviderWebForms/Default.aspx b/samples/OpenIdProviderWebForms/Default.aspx
new file mode 100644
index 0000000..a0cb02a
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/Default.aspx
@@ -0,0 +1,53 @@
+<%@ Page Language="C#" AutoEventWireup="true" MasterPageFile="~/Site.Master" %>
+
+<%@ Import Namespace="OpenIdProviderWebForms.Code" %>
+<%@ Import Namespace="DotNetOpenAuth.OpenId.Provider" %>
+<%@ Import Namespace="DotNetOpenAuth.Messaging" %>
+<%@ Register Assembly="DotNetOpenAuth" Namespace="DotNetOpenAuth.OpenId" TagPrefix="openid" %>
+<%@ Register Assembly="DotNetOpenAuth" Namespace="DotNetOpenAuth" TagPrefix="openauth" %>
+
+<script runat="server">
+ protected void sendAssertionButton_Click(object sender, EventArgs e) {
+ TextBox relyingPartySite = (TextBox)loginView.FindControl("relyingPartySite");
+ Uri providerEndpoint = new Uri(Request.Url, Page.ResolveUrl("~/server.aspx"));
+ OpenIdProvider op = new OpenIdProvider();
+ try {
+ op.PrepareUnsolicitedAssertion(providerEndpoint, relyingPartySite.Text, Util.BuildIdentityUrl(), Util.BuildIdentityUrl()).Send();
+ } catch (ProtocolException ex) {
+ Label errorLabel = (Label)loginView.FindControl("errorLabel");
+ errorLabel.Visible = true;
+ errorLabel.Text = ex.Message;
+ }
+ }
+</script>
+
+<asp:Content runat="server" ContentPlaceHolderID="head">
+ <openauth:XrdsPublisher runat="server" XrdsUrl="~/op_xrds.aspx" />
+</asp:Content>
+<asp:Content runat="server" ContentPlaceHolderID="Main">
+ <h2>Provider </h2>
+ <p>Welcome. This site doesn't do anything more than simple authentication of users.
+ Start the authentication process on the Relying Party sample site, or log in here
+ and send an unsolicited assertion. </p>
+ <asp:LoginView runat="server" ID="loginView">
+ <LoggedInTemplate>
+ <asp:Panel runat="server" DefaultButton="sendAssertionButton">
+ Since you're logged in, try sending an unsolicited assertion to an OpenID 2.0 relying
+ party site. Just type in the URL to the site's home page. This could be the sample
+ relying party web site.
+ <br />
+ <asp:TextBox runat="server" ID="relyingPartySite" Columns="40" />
+ <asp:Button runat="server" ID="sendAssertionButton" Text="Send assertion" OnClick="sendAssertionButton_Click" />
+ <asp:RequiredFieldValidator runat="server" ControlToValidate="relyingPartySite" Text="Specify relying party site first" />
+ <br />
+ An unsolicited assertion is a way to log in to a relying party site directly from
+ your OpenID Provider.
+ <p>
+ <asp:Label runat="server" EnableViewState="false" Visible="false" ID="errorLabel"
+ ForeColor="Red" />
+ </p>
+ </asp:Panel>
+ </LoggedInTemplate>
+ </asp:LoginView>
+ <asp:LoginStatus runat="server" />
+</asp:Content>
diff --git a/samples/OpenIdProviderWebForms/Global.asax b/samples/OpenIdProviderWebForms/Global.asax
new file mode 100644
index 0000000..a67f1b1
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/Global.asax
@@ -0,0 +1 @@
+<%@ Application Codebehind="Global.asax.cs" Inherits="OpenIdProviderWebForms.Global" Language="C#" %>
diff --git a/samples/OpenIdProviderWebForms/Global.asax.cs b/samples/OpenIdProviderWebForms/Global.asax.cs
new file mode 100644
index 0000000..89d9268
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/Global.asax.cs
@@ -0,0 +1,82 @@
+//-----------------------------------------------------------------------
+// <copyright file="Global.asax.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace OpenIdProviderWebForms {
+ using System;
+ using System.Collections.Specialized;
+ using System.IO;
+ using System.Text;
+ using System.Web;
+ using OpenIdProviderWebForms.Code;
+
+ public class Global : System.Web.HttpApplication {
+ public static log4net.ILog Logger = log4net.LogManager.GetLogger(typeof(Global));
+
+ internal static StringBuilder LogMessages = new StringBuilder();
+
+ public static string ToString(NameValueCollection collection) {
+ using (StringWriter sw = new StringWriter()) {
+ foreach (string key in collection.Keys) {
+ if (key.StartsWith("__")) {
+ continue; // skip
+ }
+ sw.WriteLine("{0} = '{1}'", key, collection[key]);
+ }
+ return sw.ToString();
+ }
+ }
+
+ protected void Application_Start(object sender, EventArgs e) {
+ log4net.Config.XmlConfigurator.Configure();
+ Logger.Info("Sample starting...");
+ }
+
+ protected void Application_End(object sender, EventArgs e) {
+ Logger.Info("Sample shutting down...");
+
+ // this would be automatic, but in partial trust scenarios it is not.
+ log4net.LogManager.Shutdown();
+ }
+
+ protected void Application_BeginRequest(object sender, EventArgs e) {
+ /*
+ * The URLRewriter was taken from http://www.codeproject.com/aspnet/URLRewriter.asp and modified slightly.
+ * It will read the config section called 'urlrewrites' from web.config and process each rule
+ * The rules are set of url transformations defined using regular expressions with support for substitutions (the ability to extract regex-matched portions of a string).
+ * There is only one rule currenty defined. It rewrites urls like: user/john ->user.aspx?username=john
+ */
+ //// System.Diagnostics.Debugger.Launch();
+ Logger.DebugFormat("Processing {0} on {1} ", this.Request.HttpMethod, this.stripQueryString(this.Request.Url));
+ if (Request.QueryString.Count > 0) {
+ Logger.DebugFormat("Querystring follows: \n{0}", ToString(Request.QueryString));
+ }
+ if (Request.Form.Count > 0) {
+ Logger.DebugFormat("Posted form follows: \n{0}", ToString(Request.Form));
+ }
+
+ URLRewriter.Process();
+ }
+
+ protected void Application_AuthenticateRequest(object sender, EventArgs e) {
+ Logger.DebugFormat("User {0} authenticated.", HttpContext.Current.User != null ? "IS" : "is NOT");
+ }
+
+ protected void Application_EndRequest(object sender, EventArgs e) {
+ }
+
+ protected void Application_Error(object sender, EventArgs e) {
+ Logger.ErrorFormat(
+ "An unhandled exception was raised. Details follow: {0}",
+ HttpContext.Current.Server.GetLastError());
+ }
+
+ private string stripQueryString(Uri uri) {
+ UriBuilder builder = new UriBuilder(uri);
+ builder.Query = null;
+ return builder.ToString();
+ }
+ }
+} \ No newline at end of file
diff --git a/samples/OpenIdProviderWebForms/OpenIdProviderWebForms.csproj b/samples/OpenIdProviderWebForms/OpenIdProviderWebForms.csproj
new file mode 100644
index 0000000..179f4f8
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/OpenIdProviderWebForms.csproj
@@ -0,0 +1,191 @@
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{2A59DE0A-B76A-4B42-9A33-04D34548353D}</ProjectGuid>
+ <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>OpenIdProviderWebForms</RootNamespace>
+ <AssemblyName>OpenIdProviderWebForms</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\</OutputPath>
+ <DefineConstants>DEBUG</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\..\lib\log4net.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data" />
+ <Reference Include="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Web" />
+ <Reference Include="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Web.Extensions.Design, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Xml" />
+ <Reference Include="System.Configuration" />
+ <Reference Include="System.Web.Services" />
+ <Reference Include="System.EnterpriseServices" />
+ <Reference Include="System.Web.Mobile" />
+ <Reference Include="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="App_Data\Users.xml" />
+ <Content Include="op_xrds.aspx" />
+ <Content Include="decide.aspx" />
+ <Content Include="Default.aspx" />
+ <Content Include="login.aspx" />
+ <Content Include="ProfileFields.ascx" />
+ <Content Include="server.aspx" />
+ <Content Include="user.aspx" />
+ <Content Include="Global.asax" />
+ <Content Include="Web.config" />
+ <Content Include="user_xrds.aspx" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Code\CustomStore.cs" />
+ <Compile Include="Code\CustomStoreDataSet.Designer.cs">
+ <DependentUpon>CustomStoreDataSet.xsd</DependentUpon>
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ </Compile>
+ <Compile Include="Code\ReadOnlyXmlMembershipProvider.cs" />
+ <Compile Include="Code\TracePageAppender.cs" />
+ <Compile Include="Code\URLRewriter.cs" />
+ <Compile Include="Code\Util.cs" />
+ <Compile Include="decide.aspx.cs">
+ <DependentUpon>decide.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="decide.aspx.designer.cs">
+ <DependentUpon>decide.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="Global.asax.cs">
+ <DependentUpon>Global.asax</DependentUpon>
+ </Compile>
+ <Compile Include="login.aspx.cs">
+ <DependentUpon>login.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="login.aspx.designer.cs">
+ <DependentUpon>login.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="ProfileFields.ascx.cs">
+ <DependentUpon>ProfileFields.ascx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="ProfileFields.ascx.designer.cs">
+ <DependentUpon>ProfileFields.ascx</DependentUpon>
+ </Compile>
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Provider.ashx.cs">
+ <DependentUpon>Provider.ashx</DependentUpon>
+ </Compile>
+ <Compile Include="server.aspx.cs">
+ <DependentUpon>server.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="server.aspx.designer.cs">
+ <DependentUpon>server.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="TracePage.aspx.cs">
+ <DependentUpon>TracePage.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="TracePage.aspx.designer.cs">
+ <DependentUpon>TracePage.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="user.aspx.cs">
+ <DependentUpon>user.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="user.aspx.designer.cs">
+ <DependentUpon>user.aspx</DependentUpon>
+ </Compile>
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="favicon.ico" />
+ <Content Include="images\dotnetopenid_tiny.gif" />
+ <Content Include="Site.Master" />
+ <Content Include="styles.css" />
+ <Content Include="TracePage.aspx" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Code\CustomStoreDataSet.xsc">
+ <DependentUpon>CustomStoreDataSet.xsd</DependentUpon>
+ </None>
+ <None Include="Code\CustomStoreDataSet.xsd">
+ <Generator>MSDataSetGenerator</Generator>
+ <LastGenOutput>CustomStoreDataSet.Designer.cs</LastGenOutput>
+ <SubType>Designer</SubType>
+ </None>
+ <None Include="Code\CustomStoreDataSet.xss">
+ <DependentUpon>CustomStoreDataSet.xsd</DependentUpon>
+ </None>
+ <Content Include="Provider.ashx" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\src\DotNetOpenAuth\DotNetOpenAuth.csproj">
+ <Project>{3191B653-F76D-4C1A-9A5A-347BC3AAAAB7}</Project>
+ <Name>DotNetOpenAuth</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+ <ProjectExtensions>
+ <VisualStudio>
+ <FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
+ <WebProjectProperties>
+ <UseIIS>False</UseIIS>
+ <AutoAssignPort>True</AutoAssignPort>
+ <DevelopmentServerPort>28597</DevelopmentServerPort>
+ <DevelopmentServerVPath>/</DevelopmentServerVPath>
+ <IISUrl>
+ </IISUrl>
+ <NTLMAuthentication>False</NTLMAuthentication>
+ <UseCustomServer>False</UseCustomServer>
+ <CustomServerUrl>
+ </CustomServerUrl>
+ <SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
+ </WebProjectProperties>
+ </FlavorProperties>
+ </VisualStudio>
+ </ProjectExtensions>
+</Project> \ No newline at end of file
diff --git a/samples/OpenIdProviderWebForms/ProfileFields.ascx b/samples/OpenIdProviderWebForms/ProfileFields.ascx
new file mode 100644
index 0000000..9f368d5
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/ProfileFields.ascx
@@ -0,0 +1,1024 @@
+<%@ Control Language="C#" AutoEventWireup="true" Inherits="OpenIdProviderWebForms.ProfileFields" CodeBehind="ProfileFields.ascx.cs" %>
+This consumer has requested the following fields from you<br />
+<table>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ <td>
+ <asp:HyperLink ID="privacyLink" runat="server" Text="Privacy Policy"
+ Target="_blank" />
+ </td>
+ </tr>
+ <tr runat="server" id="nicknameRow">
+ <td>
+ Nickname
+ <asp:Label ID="nicknameRequiredLabel" runat="server" Text="*" Visible="False"></asp:Label>
+ </td>
+ <td>
+ <asp:TextBox ID="nicknameTextBox" runat="server"></asp:TextBox>
+ </td>
+ </tr>
+ <tr runat="server" id="emailRow">
+ <td>
+ Email
+ <asp:Label ID="emailRequiredLabel" runat="server" Text="*" Visible="False"></asp:Label>
+ </td>
+ <td>
+ <asp:TextBox ID="emailTextBox" runat="server"></asp:TextBox>
+ </td>
+ </tr>
+ <tr runat="server" id="fullnameRow">
+ <td>
+ FullName
+ <asp:Label ID="fullnameRequiredLabel" runat="server" Text="*" Visible="False"></asp:Label>
+ </td>
+ <td>
+ <asp:TextBox ID="fullnameTextBox" runat="server"></asp:TextBox>
+ </td>
+ </tr>
+ <tr runat="server" id="dateOfBirthRow">
+ <td>
+ Date of Birth
+ <asp:Label ID="dobRequiredLabel" runat="server" Text="*" Visible="False"></asp:Label>
+ </td>
+ <td>
+ <asp:DropDownList ID="dobDayDropdownlist" runat="server">
+ <asp:ListItem></asp:ListItem>
+ <asp:ListItem>1</asp:ListItem>
+ <asp:ListItem>2</asp:ListItem>
+ <asp:ListItem>3</asp:ListItem>
+ <asp:ListItem>4</asp:ListItem>
+ <asp:ListItem>5</asp:ListItem>
+ <asp:ListItem>6</asp:ListItem>
+ <asp:ListItem>7</asp:ListItem>
+ <asp:ListItem>8</asp:ListItem>
+ <asp:ListItem>9</asp:ListItem>
+ <asp:ListItem>10</asp:ListItem>
+ <asp:ListItem>11</asp:ListItem>
+ <asp:ListItem>12</asp:ListItem>
+ <asp:ListItem>13</asp:ListItem>
+ <asp:ListItem>14</asp:ListItem>
+ <asp:ListItem>15</asp:ListItem>
+ <asp:ListItem>16</asp:ListItem>
+ <asp:ListItem>17</asp:ListItem>
+ <asp:ListItem>18</asp:ListItem>
+ <asp:ListItem>19</asp:ListItem>
+ <asp:ListItem>20</asp:ListItem>
+ <asp:ListItem>21</asp:ListItem>
+ <asp:ListItem>22</asp:ListItem>
+ <asp:ListItem>23</asp:ListItem>
+ <asp:ListItem>24</asp:ListItem>
+ <asp:ListItem>25</asp:ListItem>
+ <asp:ListItem>26</asp:ListItem>
+ <asp:ListItem>27</asp:ListItem>
+ <asp:ListItem>28</asp:ListItem>
+ <asp:ListItem>29</asp:ListItem>
+ <asp:ListItem>30</asp:ListItem>
+ <asp:ListItem>31</asp:ListItem>
+ </asp:DropDownList>
+ &nbsp;<asp:DropDownList ID="dobMonthDropdownlist" runat="server">
+ <asp:ListItem></asp:ListItem>
+ <asp:ListItem Value="1">January</asp:ListItem>
+ <asp:ListItem Value="2">February</asp:ListItem>
+ <asp:ListItem Value="3">March</asp:ListItem>
+ <asp:ListItem Value="4">April</asp:ListItem>
+ <asp:ListItem Value="5">May</asp:ListItem>
+ <asp:ListItem Value="6">June</asp:ListItem>
+ <asp:ListItem Value="7">July</asp:ListItem>
+ <asp:ListItem Value="8">August</asp:ListItem>
+ <asp:ListItem Value="9">September</asp:ListItem>
+ <asp:ListItem Value="10">October</asp:ListItem>
+ <asp:ListItem Value="11">November</asp:ListItem>
+ <asp:ListItem Value="12">December</asp:ListItem>
+ </asp:DropDownList>
+ &nbsp;
+ <asp:DropDownList ID="dobYearDropdownlist" runat="server">
+ <asp:ListItem></asp:ListItem>
+ <asp:ListItem>2009</asp:ListItem>
+ <asp:ListItem>2008</asp:ListItem>
+ <asp:ListItem>2007</asp:ListItem>
+ <asp:ListItem>2006</asp:ListItem>
+ <asp:ListItem>2005</asp:ListItem>
+ <asp:ListItem>2004</asp:ListItem>
+ <asp:ListItem>2003</asp:ListItem>
+ <asp:ListItem>2002</asp:ListItem>
+ <asp:ListItem>2001</asp:ListItem>
+ <asp:ListItem>2000</asp:ListItem>
+ <asp:ListItem>1999</asp:ListItem>
+ <asp:ListItem>1998</asp:ListItem>
+ <asp:ListItem>1997</asp:ListItem>
+ <asp:ListItem>1996</asp:ListItem>
+ <asp:ListItem>1995</asp:ListItem>
+ <asp:ListItem>1994</asp:ListItem>
+ <asp:ListItem>1993</asp:ListItem>
+ <asp:ListItem>1992</asp:ListItem>
+ <asp:ListItem>1991</asp:ListItem>
+ <asp:ListItem>1990</asp:ListItem>
+ <asp:ListItem>1989</asp:ListItem>
+ <asp:ListItem>1988</asp:ListItem>
+ <asp:ListItem>1987</asp:ListItem>
+ <asp:ListItem>1986</asp:ListItem>
+ <asp:ListItem>1985</asp:ListItem>
+ <asp:ListItem>1984</asp:ListItem>
+ <asp:ListItem>1983</asp:ListItem>
+ <asp:ListItem>1982</asp:ListItem>
+ <asp:ListItem>1981</asp:ListItem>
+ <asp:ListItem>1980</asp:ListItem>
+ <asp:ListItem>1979</asp:ListItem>
+ <asp:ListItem>1978</asp:ListItem>
+ <asp:ListItem>1977</asp:ListItem>
+ <asp:ListItem>1976</asp:ListItem>
+ <asp:ListItem>1975</asp:ListItem>
+ <asp:ListItem>1974</asp:ListItem>
+ <asp:ListItem>1973</asp:ListItem>
+ <asp:ListItem>1972</asp:ListItem>
+ <asp:ListItem>1971</asp:ListItem>
+ <asp:ListItem>1970</asp:ListItem>
+ <asp:ListItem>1969</asp:ListItem>
+ <asp:ListItem>1968</asp:ListItem>
+ <asp:ListItem>1967</asp:ListItem>
+ <asp:ListItem>1966</asp:ListItem>
+ <asp:ListItem>1965</asp:ListItem>
+ <asp:ListItem>1964</asp:ListItem>
+ <asp:ListItem>1963</asp:ListItem>
+ <asp:ListItem>1962</asp:ListItem>
+ <asp:ListItem>1961</asp:ListItem>
+ <asp:ListItem>1960</asp:ListItem>
+ <asp:ListItem>1959</asp:ListItem>
+ <asp:ListItem>1958</asp:ListItem>
+ <asp:ListItem>1957</asp:ListItem>
+ <asp:ListItem>1956</asp:ListItem>
+ <asp:ListItem>1955</asp:ListItem>
+ <asp:ListItem>1954</asp:ListItem>
+ <asp:ListItem>1953</asp:ListItem>
+ <asp:ListItem>1952</asp:ListItem>
+ <asp:ListItem>1951</asp:ListItem>
+ <asp:ListItem>1950</asp:ListItem>
+ <asp:ListItem>1949</asp:ListItem>
+ <asp:ListItem>1948</asp:ListItem>
+ <asp:ListItem>1947</asp:ListItem>
+ <asp:ListItem>1946</asp:ListItem>
+ <asp:ListItem>1945</asp:ListItem>
+ <asp:ListItem>1944</asp:ListItem>
+ <asp:ListItem>1943</asp:ListItem>
+ <asp:ListItem>1942</asp:ListItem>
+ <asp:ListItem>1941</asp:ListItem>
+ <asp:ListItem>1940</asp:ListItem>
+ <asp:ListItem>1939</asp:ListItem>
+ <asp:ListItem>1938</asp:ListItem>
+ <asp:ListItem>1937</asp:ListItem>
+ <asp:ListItem>1936</asp:ListItem>
+ <asp:ListItem>1935</asp:ListItem>
+ <asp:ListItem>1934</asp:ListItem>
+ <asp:ListItem>1933</asp:ListItem>
+ <asp:ListItem>1932</asp:ListItem>
+ <asp:ListItem>1931</asp:ListItem>
+ <asp:ListItem>1930</asp:ListItem>
+ <asp:ListItem>1929</asp:ListItem>
+ <asp:ListItem>1928</asp:ListItem>
+ <asp:ListItem>1927</asp:ListItem>
+ <asp:ListItem>1926</asp:ListItem>
+ <asp:ListItem>1925</asp:ListItem>
+ <asp:ListItem>1924</asp:ListItem>
+ <asp:ListItem>1923</asp:ListItem>
+ <asp:ListItem>1922</asp:ListItem>
+ <asp:ListItem>1921</asp:ListItem>
+ <asp:ListItem>1920</asp:ListItem>
+ </asp:DropDownList>
+ </td>
+ </tr>
+ <tr runat="server" id="genderRow">
+ <td>
+ Gender
+ <asp:Label ID="genderRequiredLabel" runat="server" Text="*" Visible="False"></asp:Label>
+ </td>
+ <td>
+ <asp:DropDownList ID="genderDropdownList" runat="server">
+ <asp:ListItem Selected="True"></asp:ListItem>
+ <asp:ListItem>Male</asp:ListItem>
+ <asp:ListItem>Female</asp:ListItem>
+ </asp:DropDownList>
+ </td>
+ </tr>
+ <tr runat="server" id="postcodeRow">
+ <td>
+ Post Code
+ <asp:Label ID="postcodeRequiredLabel" runat="server" Text="*" Visible="False"></asp:Label>
+ </td>
+ <td>
+ <asp:TextBox ID="postcodeTextBox" runat="server"></asp:TextBox>
+ </td>
+ </tr>
+ <tr runat="server" id="countryRow">
+ <td>
+ Country
+ <asp:Label ID="countryRequiredLabel" runat="server" Text="*" Visible="False"></asp:Label>
+ </td>
+ <td>
+ <asp:DropDownList ID="countryDropdownList" runat="server">
+ <asp:ListItem Value=""> </asp:ListItem>
+ <asp:ListItem Value="AF">AFGHANISTAN </asp:ListItem>
+ <asp:ListItem Value="AX">ÅLAND ISLANDS</asp:ListItem>
+ <asp:ListItem Value="AL">ALBANIA</asp:ListItem>
+ <asp:ListItem Value="DZ">ALGERIA</asp:ListItem>
+ <asp:ListItem Value="AS">AMERICAN SAMOA</asp:ListItem>
+ <asp:ListItem Value="AD">ANDORRA</asp:ListItem>
+ <asp:ListItem Value="AO">ANGOLA</asp:ListItem>
+ <asp:ListItem Value="AI">ANGUILLA</asp:ListItem>
+ <asp:ListItem Value="AQ">ANTARCTICA</asp:ListItem>
+ <asp:ListItem Value="AG">ANTIGUA AND BARBUDA</asp:ListItem>
+ <asp:ListItem Value="AR">ARGENTINA</asp:ListItem>
+ <asp:ListItem Value="AM">ARMENIA</asp:ListItem>
+ <asp:ListItem Value="AW">ARUBA</asp:ListItem>
+ <asp:ListItem Value="AU">AUSTRALIA</asp:ListItem>
+ <asp:ListItem Value="AT">AUSTRIA</asp:ListItem>
+ <asp:ListItem Value="AZ">AZERBAIJAN</asp:ListItem>
+ <asp:ListItem Value="BS">BAHAMAS</asp:ListItem>
+ <asp:ListItem Value="BH">BAHRAIN</asp:ListItem>
+ <asp:ListItem Value="BD">BANGLADESH</asp:ListItem>
+ <asp:ListItem Value="BB">BARBADOS</asp:ListItem>
+ <asp:ListItem Value="BY">BELARUS</asp:ListItem>
+ <asp:ListItem Value="BE">BELGIUM</asp:ListItem>
+ <asp:ListItem Value="BZ">BELIZE</asp:ListItem>
+ <asp:ListItem Value="BJ">BENIN</asp:ListItem>
+ <asp:ListItem Value="BM">BERMUDA</asp:ListItem>
+ <asp:ListItem Value="BT">BHUTAN</asp:ListItem>
+ <asp:ListItem Value="BO">BOLIVIA</asp:ListItem>
+ <asp:ListItem Value="BA">BOSNIA AND HERZEGOVINA</asp:ListItem>
+ <asp:ListItem Value="BW">BOTSWANA</asp:ListItem>
+ <asp:ListItem Value="BV">BOUVET ISLAND</asp:ListItem>
+ <asp:ListItem Value="BR">BRAZIL</asp:ListItem>
+ <asp:ListItem Value="IO">BRITISH INDIAN OCEAN TERRITORY</asp:ListItem>
+ <asp:ListItem Value="BN">BRUNEI DARUSSALAM</asp:ListItem>
+ <asp:ListItem Value="BG">BULGARIA</asp:ListItem>
+ <asp:ListItem Value="BF">BURKINA FASO</asp:ListItem>
+ <asp:ListItem Value="BI">BURUNDI</asp:ListItem>
+ <asp:ListItem Value="KH">CAMBODIA</asp:ListItem>
+ <asp:ListItem Value="CM">CAMEROON</asp:ListItem>
+ <asp:ListItem Value="CA">CANADA</asp:ListItem>
+ <asp:ListItem Value="CV">CAPE VERDE</asp:ListItem>
+ <asp:ListItem Value="KY">CAYMAN ISLANDS</asp:ListItem>
+ <asp:ListItem Value="CF">CENTRAL AFRICAN REPUBLIC</asp:ListItem>
+ <asp:ListItem Value="TD">CHAD</asp:ListItem>
+ <asp:ListItem Value="CL">CHILE</asp:ListItem>
+ <asp:ListItem Value="CN">CHINA</asp:ListItem>
+ <asp:ListItem Value="CX">CHRISTMAS ISLAND</asp:ListItem>
+ <asp:ListItem Value="CC">COCOS (KEELING) ISLANDS</asp:ListItem>
+ <asp:ListItem Value="CO">COLOMBIA</asp:ListItem>
+ <asp:ListItem Value="KM">COMOROS</asp:ListItem>
+ <asp:ListItem Value="CG">CONGO</asp:ListItem>
+ <asp:ListItem Value="CD">CONGO, THE DEMOCRATIC REPUBLIC OF THE</asp:ListItem>
+ <asp:ListItem Value="CK">COOK ISLANDS</asp:ListItem>
+ <asp:ListItem Value="CR">COSTA RICA</asp:ListItem>
+ <asp:ListItem Value="CI">CÔTE D'IVOIRE</asp:ListItem>
+ <asp:ListItem Value="HR">CROATIA</asp:ListItem>
+ <asp:ListItem Value="CU">CUBA</asp:ListItem>
+ <asp:ListItem Value="CY">CYPRUS</asp:ListItem>
+ <asp:ListItem Value="CZ">CZECH REPUBLIC</asp:ListItem>
+ <asp:ListItem Value="DK">DENMARK</asp:ListItem>
+ <asp:ListItem Value="DJ">DJIBOUTI</asp:ListItem>
+ <asp:ListItem Value="DM">DOMINICA</asp:ListItem>
+ <asp:ListItem Value="DO">DOMINICAN REPUBLIC</asp:ListItem>
+ <asp:ListItem Value="EC">ECUADOR</asp:ListItem>
+ <asp:ListItem Value="EG">EGYPT</asp:ListItem>
+ <asp:ListItem Value="SV">EL SALVADOR</asp:ListItem>
+ <asp:ListItem Value="GQ">EQUATORIAL GUINEA</asp:ListItem>
+ <asp:ListItem Value="ER">ERITREA</asp:ListItem>
+ <asp:ListItem Value="EE">ESTONIA</asp:ListItem>
+ <asp:ListItem Value="ET">ETHIOPIA</asp:ListItem>
+ <asp:ListItem Value="FK">FALKLAND ISLANDS (MALVINAS)</asp:ListItem>
+ <asp:ListItem Value="FO">FAROE ISLANDS</asp:ListItem>
+ <asp:ListItem Value="FJ">FIJI</asp:ListItem>
+ <asp:ListItem Value="FI">FINLAND</asp:ListItem>
+ <asp:ListItem Value="FR">FRANCE</asp:ListItem>
+ <asp:ListItem Value="GF">FRENCH GUIANA</asp:ListItem>
+ <asp:ListItem Value="PF">FRENCH POLYNESIA</asp:ListItem>
+ <asp:ListItem Value="TF">FRENCH SOUTHERN TERRITORIES</asp:ListItem>
+ <asp:ListItem Value="GA">GABON </asp:ListItem>
+ <asp:ListItem Value="GM">GAMBIA</asp:ListItem>
+ <asp:ListItem Value="GE">GEORGIA</asp:ListItem>
+ <asp:ListItem Value="DE">GERMANY</asp:ListItem>
+ <asp:ListItem Value="GH">GHANA</asp:ListItem>
+ <asp:ListItem Value="GI">GIBRALTAR</asp:ListItem>
+ <asp:ListItem Value="GR">GREECE</asp:ListItem>
+ <asp:ListItem Value="GL">GREENLAND</asp:ListItem>
+ <asp:ListItem Value="GD">GRENADA</asp:ListItem>
+ <asp:ListItem Value="GP">GUADELOUPE</asp:ListItem>
+ <asp:ListItem Value="GU">GUAM </asp:ListItem>
+ <asp:ListItem Value="GT">GUATEMALA</asp:ListItem>
+ <asp:ListItem Value="GG">GUERNSEY</asp:ListItem>
+ <asp:ListItem Value="GN">GUINEA</asp:ListItem>
+ <asp:ListItem Value="GW">GUINEA-BISSAU</asp:ListItem>
+ <asp:ListItem Value="GY">GUYANA</asp:ListItem>
+ <asp:ListItem Value="HT">HAITI</asp:ListItem>
+ <asp:ListItem Value="HM">HEARD ISLAND AND MCDONALD ISLANDS</asp:ListItem>
+ <asp:ListItem Value="VA">HOLY SEE (VATICAN CITY STATE)</asp:ListItem>
+ <asp:ListItem Value="HN">HONDURAS</asp:ListItem>
+ <asp:ListItem Value="HK">HONG KONG</asp:ListItem>
+ <asp:ListItem Value="HU">HUNGARY</asp:ListItem>
+ <asp:ListItem Value="IS">ICELAND</asp:ListItem>
+ <asp:ListItem Value="IN">INDIA</asp:ListItem>
+ <asp:ListItem Value="ID">INDONESIA</asp:ListItem>
+ <asp:ListItem Value="IR">IRAN, ISLAMIC REPUBLIC OF</asp:ListItem>
+ <asp:ListItem Value="IQ">IRAQ</asp:ListItem>
+ <asp:ListItem Value="IE">IRELAND</asp:ListItem>
+ <asp:ListItem Value="IM">ISLE OF MAN</asp:ListItem>
+ <asp:ListItem Value="IL">ISRAEL</asp:ListItem>
+ <asp:ListItem Value="IT">ITALY</asp:ListItem>
+ <asp:ListItem Value="JM">JAMAICA</asp:ListItem>
+ <asp:ListItem Value="JP">JAPAN</asp:ListItem>
+ <asp:ListItem Value="JE">JERSEY</asp:ListItem>
+ <asp:ListItem Value="JO">JORDAN</asp:ListItem>
+ <asp:ListItem Value="KZ">KAZAKHSTAN</asp:ListItem>
+ <asp:ListItem Value="KE">KENYA</asp:ListItem>
+ <asp:ListItem Value="KI">KIRIBATI</asp:ListItem>
+ <asp:ListItem Value="KP">KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF</asp:ListItem>
+ <asp:ListItem Value="KR">KOREA, REPUBLIC OF</asp:ListItem>
+ <asp:ListItem Value="KW">KUWAIT</asp:ListItem>
+ <asp:ListItem Value="KG">KYRGYZSTAN</asp:ListItem>
+ <asp:ListItem Value="LA">LAO PEOPLE'S DEMOCRATIC REPUBLIC </asp:ListItem>
+ <asp:ListItem Value="LV">LATVIA</asp:ListItem>
+ <asp:ListItem Value="LB">LEBANON</asp:ListItem>
+ <asp:ListItem Value="LS">LESOTHO</asp:ListItem>
+ <asp:ListItem Value="LR">LIBERIA</asp:ListItem>
+ <asp:ListItem Value="LY">LIBYAN ARAB JAMAHIRIYA</asp:ListItem>
+ <asp:ListItem Value="LI">LIECHTENSTEIN</asp:ListItem>
+ <asp:ListItem Value="LT">LITHUANIA</asp:ListItem>
+ <asp:ListItem Value="LU">LUXEMBOURG</asp:ListItem>
+ <asp:ListItem Value="MO">MACAO</asp:ListItem>
+ <asp:ListItem Value="MK">MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF</asp:ListItem>
+ <asp:ListItem Value="MG">MADAGASCAR</asp:ListItem>
+ <asp:ListItem Value="MW">MALAWI</asp:ListItem>
+ <asp:ListItem Value="MY">MALAYSIA</asp:ListItem>
+ <asp:ListItem Value="MV">MALDIVES</asp:ListItem>
+ <asp:ListItem Value="ML">MALI</asp:ListItem>
+ <asp:ListItem Value="MT">MALTA</asp:ListItem>
+ <asp:ListItem Value="MH">MARSHALL ISLANDS</asp:ListItem>
+ <asp:ListItem Value="MQ">MARTINIQUE</asp:ListItem>
+ <asp:ListItem Value="MR">MAURITANIA</asp:ListItem>
+ <asp:ListItem Value="MU">MAURITIUS</asp:ListItem>
+ <asp:ListItem Value="YT">MAYOTTE</asp:ListItem>
+ <asp:ListItem Value="MX">MEXICO</asp:ListItem>
+ <asp:ListItem Value="FM">MICRONESIA, FEDERATED STATES OF</asp:ListItem>
+ <asp:ListItem Value="MD">MOLDOVA, REPUBLIC OF</asp:ListItem>
+ <asp:ListItem Value="MC">MONACO</asp:ListItem>
+ <asp:ListItem Value="MN">MONGOLIA</asp:ListItem>
+ <asp:ListItem Value="ME">MONTENEGRO</asp:ListItem>
+ <asp:ListItem Value="MS">MONTSERRAT</asp:ListItem>
+ <asp:ListItem Value="MA">MOROCCO</asp:ListItem>
+ <asp:ListItem Value="MZ">MOZAMBIQUE</asp:ListItem>
+ <asp:ListItem Value="MM">MYANMAR</asp:ListItem>
+ <asp:ListItem Value="NA">NAMIBIA</asp:ListItem>
+ <asp:ListItem Value="NR">NAURU</asp:ListItem>
+ <asp:ListItem Value="NP">NEPAL</asp:ListItem>
+ <asp:ListItem Value="NL">NETHERLANDS</asp:ListItem>
+ <asp:ListItem Value="AN">NETHERLANDS ANTILLES</asp:ListItem>
+ <asp:ListItem Value="NC">NEW CALEDONIA</asp:ListItem>
+ <asp:ListItem Value="NZ">NEW ZEALAND</asp:ListItem>
+ <asp:ListItem Value="NI">NICARAGUA</asp:ListItem>
+ <asp:ListItem Value="NE">NIGER</asp:ListItem>
+ <asp:ListItem Value="NG">NIGERIA</asp:ListItem>
+ <asp:ListItem Value="NU">NIUE</asp:ListItem>
+ <asp:ListItem Value="NF">NORFOLK ISLAND</asp:ListItem>
+ <asp:ListItem Value="MP">NORTHERN MARIANA ISLANDS</asp:ListItem>
+ <asp:ListItem Value="NO">NORWAY</asp:ListItem>
+ <asp:ListItem Value="OM">OMAN</asp:ListItem>
+ <asp:ListItem Value="PK">PAKISTAN</asp:ListItem>
+ <asp:ListItem Value="PW">PALAU</asp:ListItem>
+ <asp:ListItem Value="PS">PALESTINIAN TERRITORY, OCCUPIED</asp:ListItem>
+ <asp:ListItem Value="PA">PANAMA</asp:ListItem>
+ <asp:ListItem Value="PG">PAPUA NEW GUINEA</asp:ListItem>
+ <asp:ListItem Value="PY">PARAGUAY</asp:ListItem>
+ <asp:ListItem Value="PE">PERU</asp:ListItem>
+ <asp:ListItem Value="PH">PHILIPPINES</asp:ListItem>
+ <asp:ListItem Value="PN">PITCAIRN</asp:ListItem>
+ <asp:ListItem Value="PL">POLAND</asp:ListItem>
+ <asp:ListItem Value="PT">PORTUGAL</asp:ListItem>
+ <asp:ListItem Value="PR">PUERTO RICO</asp:ListItem>
+ <asp:ListItem Value="QA">QATAR</asp:ListItem>
+ <asp:ListItem Value="RE">RÉUNION</asp:ListItem>
+ <asp:ListItem Value="RO">ROMANIA</asp:ListItem>
+ <asp:ListItem Value="RU">RUSSIAN FEDERATION</asp:ListItem>
+ <asp:ListItem Value="RW">RWANDA</asp:ListItem>
+ <asp:ListItem Value="SH">SAINT HELENA </asp:ListItem>
+ <asp:ListItem Value="KN">SAINT KITTS AND NEVIS</asp:ListItem>
+ <asp:ListItem Value="LC">SAINT LUCIA</asp:ListItem>
+ <asp:ListItem Value="PM">SAINT PIERRE AND MIQUELON</asp:ListItem>
+ <asp:ListItem Value="VC">SAINT VINCENT AND THE GRENADINES</asp:ListItem>
+ <asp:ListItem Value="WS">SAMOA</asp:ListItem>
+ <asp:ListItem Value="SM">SAN MARINO</asp:ListItem>
+ <asp:ListItem Value="ST">SAO TOME AND PRINCIPE</asp:ListItem>
+ <asp:ListItem Value="SA">SAUDI ARABIA</asp:ListItem>
+ <asp:ListItem Value="SN">SENEGAL</asp:ListItem>
+ <asp:ListItem Value="RS">SERBIA</asp:ListItem>
+ <asp:ListItem Value="SC">SEYCHELLES</asp:ListItem>
+ <asp:ListItem Value="SL">SIERRA LEONE</asp:ListItem>
+ <asp:ListItem Value="SG">SINGAPORE</asp:ListItem>
+ <asp:ListItem Value="SK">SLOVAKIA</asp:ListItem>
+ <asp:ListItem Value="SI">SLOVENIA</asp:ListItem>
+ <asp:ListItem Value="SB">SOLOMON ISLANDS</asp:ListItem>
+ <asp:ListItem Value="SO">SOMALIA</asp:ListItem>
+ <asp:ListItem Value="ZA">SOUTH AFRICA</asp:ListItem>
+ <asp:ListItem Value="GS">SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS</asp:ListItem>
+ <asp:ListItem Value="ES">SPAIN</asp:ListItem>
+ <asp:ListItem Value="LK">SRI LANKA</asp:ListItem>
+ <asp:ListItem Value="SD">SUDAN</asp:ListItem>
+ <asp:ListItem Value="SR">SURINAME</asp:ListItem>
+ <asp:ListItem Value="SJ">SVALBARD AND JAN MAYEN</asp:ListItem>
+ <asp:ListItem Value="SZ">SWAZILAND</asp:ListItem>
+ <asp:ListItem Value="SE">SWEDEN</asp:ListItem>
+ <asp:ListItem Value="CH">SWITZERLAND</asp:ListItem>
+ <asp:ListItem Value="SY">SYRIAN ARAB REPUBLIC</asp:ListItem>
+ <asp:ListItem Value="TW">TAIWAN, PROVINCE OF CHINA</asp:ListItem>
+ <asp:ListItem Value="TJ">TAJIKISTAN</asp:ListItem>
+ <asp:ListItem Value="TZ">TANZANIA, UNITED REPUBLIC OF</asp:ListItem>
+ <asp:ListItem Value="TH">THAILAND</asp:ListItem>
+ <asp:ListItem Value="TL">TIMOR-LESTE</asp:ListItem>
+ <asp:ListItem Value="TG">TOGO</asp:ListItem>
+ <asp:ListItem Value="TK">TOKELAU</asp:ListItem>
+ <asp:ListItem Value="TO">TONGA</asp:ListItem>
+ <asp:ListItem Value="TT">TRINIDAD AND TOBAGO</asp:ListItem>
+ <asp:ListItem Value="TN">TUNISIA</asp:ListItem>
+ <asp:ListItem Value="TR">TURKEY</asp:ListItem>
+ <asp:ListItem Value="TM">TURKMENISTAN</asp:ListItem>
+ <asp:ListItem Value="TC">TURKS AND CAICOS ISLANDS</asp:ListItem>
+ <asp:ListItem Value="TV">TUVALU</asp:ListItem>
+ <asp:ListItem Value="UG">UGANDA</asp:ListItem>
+ <asp:ListItem Value="UA">UKRAINE</asp:ListItem>
+ <asp:ListItem Value="AE">UNITED ARAB EMIRATES</asp:ListItem>
+ <asp:ListItem Value="GB">UNITED KINGDOM</asp:ListItem>
+ <asp:ListItem Value="US">UNITED STATES</asp:ListItem>
+ <asp:ListItem Value="UM">UNITED STATES MINOR OUTLYING ISLANDS</asp:ListItem>
+ <asp:ListItem Value="UY">URUGUAY</asp:ListItem>
+ <asp:ListItem Value="UZ">UZBEKISTAN</asp:ListItem>
+ <asp:ListItem Value="VU">VANUATU</asp:ListItem>
+ <asp:ListItem Value="VE">VENEZUELA</asp:ListItem>
+ <asp:ListItem Value="VN">VIET NAM</asp:ListItem>
+ <asp:ListItem Value="VG">VIRGIN ISLANDS, BRITISH</asp:ListItem>
+ <asp:ListItem Value="VI">VIRGIN ISLANDS, U.S.</asp:ListItem>
+ <asp:ListItem Value="WF">WALLIS AND FUTUNA</asp:ListItem>
+ <asp:ListItem Value="EH">WESTERN SAHARA</asp:ListItem>
+ <asp:ListItem Value="YE">YEMEN</asp:ListItem>
+ <asp:ListItem Value="ZM">ZAMBIA</asp:ListItem>
+ <asp:ListItem Value="ZW">ZIMBABWE</asp:ListItem>
+ </asp:DropDownList>
+ </td>
+ </tr>
+ <tr runat="server" id="languageRow">
+ <td>
+ Language
+ <asp:Label ID="languageRequiredLabel" runat="server" Text="*" Visible="False"></asp:Label>
+ </td>
+ <td>
+ <asp:DropDownList ID="languageDropdownList" runat="server">
+ <asp:ListItem Value=""></asp:ListItem>
+ <asp:ListItem Value="EN">English</asp:ListItem>
+ <asp:ListItem Value="AB">Abkhazian</asp:ListItem>
+ <asp:ListItem Value="AA">Afar</asp:ListItem>
+ <asp:ListItem Value="AF">Afrikaans</asp:ListItem>
+ <asp:ListItem Value="SQ">Albanian</asp:ListItem>
+ <asp:ListItem Value="AM">Amharic</asp:ListItem>
+ <asp:ListItem Value="AR">Arabic</asp:ListItem>
+ <asp:ListItem Value="HY">Armenian</asp:ListItem>
+ <asp:ListItem Value="AS">Assamese</asp:ListItem>
+ <asp:ListItem Value="AY">Aymara</asp:ListItem>
+ <asp:ListItem Value="AZ">Azerbaijani</asp:ListItem>
+ <asp:ListItem Value="BA">Bashkir</asp:ListItem>
+ <asp:ListItem Value="EU">Basque</asp:ListItem>
+ <asp:ListItem Value="BN">Bengali</asp:ListItem>
+ <asp:ListItem Value="DZ">Bhutani</asp:ListItem>
+ <asp:ListItem Value="BH">Bihari</asp:ListItem>
+ <asp:ListItem Value="BI">Bislama</asp:ListItem>
+ <asp:ListItem Value="BR">Breton</asp:ListItem>
+ <asp:ListItem Value="BG">Bulgarian</asp:ListItem>
+ <asp:ListItem Value="MY">Burmese</asp:ListItem>
+ <asp:ListItem Value="BE">Byelorussian</asp:ListItem>
+ <asp:ListItem Value="KM">Cambodian</asp:ListItem>
+ <asp:ListItem Value="CA">Catalan</asp:ListItem>
+ <asp:ListItem Value="ZH">Chinese</asp:ListItem>
+ <asp:ListItem Value="CO">Corsican</asp:ListItem>
+ <asp:ListItem Value="HR">Croatian</asp:ListItem>
+ <asp:ListItem Value="CS">Czech</asp:ListItem>
+ <asp:ListItem Value="DA">Danish</asp:ListItem>
+ <asp:ListItem Value="NL">Dutch</asp:ListItem>
+ <asp:ListItem Value="EO">Esperanto</asp:ListItem>
+ <asp:ListItem Value="ET">Estonian</asp:ListItem>
+ <asp:ListItem Value="FO">Faeroese</asp:ListItem>
+ <asp:ListItem Value="FJ">Fiji</asp:ListItem>
+ <asp:ListItem Value="FI">Finnish</asp:ListItem>
+ <asp:ListItem Value="FR">French</asp:ListItem>
+ <asp:ListItem Value="FY">Frisian</asp:ListItem>
+ <asp:ListItem Value="GD">Gaelic</asp:ListItem>
+ <asp:ListItem Value="GL">Galician</asp:ListItem>
+ <asp:ListItem Value="KA">Georgian</asp:ListItem>
+ <asp:ListItem Value="DE">German</asp:ListItem>
+ <asp:ListItem Value="EL">Greek</asp:ListItem>
+ <asp:ListItem Value="KL">Greenlandic</asp:ListItem>
+ <asp:ListItem Value="GN">Guarani</asp:ListItem>
+ <asp:ListItem Value="GU">Gujarati</asp:ListItem>
+ <asp:ListItem Value="HA">Hausa</asp:ListItem>
+ <asp:ListItem Value="IW">Hebrew</asp:ListItem>
+ <asp:ListItem Value="HI">Hindi</asp:ListItem>
+ <asp:ListItem Value="HU">Hungarian</asp:ListItem>
+ <asp:ListItem Value="IS">Icelandic</asp:ListItem>
+ <asp:ListItem Value="IN">Indonesian</asp:ListItem>
+ <asp:ListItem Value="IA">Interlingua</asp:ListItem>
+ <asp:ListItem Value="IE">Interlingue</asp:ListItem>
+ <asp:ListItem Value="IK">Inupiak</asp:ListItem>
+ <asp:ListItem Value="GA">Irish</asp:ListItem>
+ <asp:ListItem Value="IT">Italian</asp:ListItem>
+ <asp:ListItem Value="JA">Japanese</asp:ListItem>
+ <asp:ListItem Value="JW">Javanese</asp:ListItem>
+ <asp:ListItem Value="KN">Kannada</asp:ListItem>
+ <asp:ListItem Value="KS">Kashmiri</asp:ListItem>
+ <asp:ListItem Value="KK">Kazakh</asp:ListItem>
+ <asp:ListItem Value="RW">Kinyarwanda</asp:ListItem>
+ <asp:ListItem Value="KY">Kirghiz</asp:ListItem>
+ <asp:ListItem Value="RN">Kirundi</asp:ListItem>
+ <asp:ListItem Value="KO">Korean</asp:ListItem>
+ <asp:ListItem Value="KU">Kurdish</asp:ListItem>
+ <asp:ListItem Value="LO">Laothian</asp:ListItem>
+ <asp:ListItem Value="LA">Latin</asp:ListItem>
+ <asp:ListItem Value="LV">Latvian</asp:ListItem>
+ <asp:ListItem Value="LN">Lingala</asp:ListItem>
+ <asp:ListItem Value="LT">Lithuanian</asp:ListItem>
+ <asp:ListItem Value="MK">Macedonian</asp:ListItem>
+ <asp:ListItem Value="MG">Malagasy</asp:ListItem>
+ <asp:ListItem Value="MS">Malay</asp:ListItem>
+ <asp:ListItem Value="ML">Malayalam</asp:ListItem>
+ <asp:ListItem Value="MT">Maltese</asp:ListItem>
+ <asp:ListItem Value="MI">Maori</asp:ListItem>
+ <asp:ListItem Value="MR">Marathi</asp:ListItem>
+ <asp:ListItem Value="MO">Moldavian</asp:ListItem>
+ <asp:ListItem Value="MN">Mongolian</asp:ListItem>
+ <asp:ListItem Value="NA">Nauru</asp:ListItem>
+ <asp:ListItem Value="NE">Nepali</asp:ListItem>
+ <asp:ListItem Value="NO">Norwegian</asp:ListItem>
+ <asp:ListItem Value="OC">Occitan</asp:ListItem>
+ <asp:ListItem Value="OR">Oriya</asp:ListItem>
+ <asp:ListItem Value="OM">Oromo</asp:ListItem>
+ <asp:ListItem Value="PS">Pashto</asp:ListItem>
+ <asp:ListItem Value="FA">Persian</asp:ListItem>
+ <asp:ListItem Value="PL">Polish</asp:ListItem>
+ <asp:ListItem Value="PT">Portuguese</asp:ListItem>
+ <asp:ListItem Value="PA">Punjabi</asp:ListItem>
+ <asp:ListItem Value="QU">Quechua</asp:ListItem>
+ <asp:ListItem Value="RM">Rhaeto-Romance</asp:ListItem>
+ <asp:ListItem Value="RO">Romanian</asp:ListItem>
+ <asp:ListItem Value="RU">Russian</asp:ListItem>
+ <asp:ListItem Value="SM">Samoan</asp:ListItem>
+ <asp:ListItem Value="SG">Sangro</asp:ListItem>
+ <asp:ListItem Value="SA">Sanskrit</asp:ListItem>
+ <asp:ListItem Value="SR">Serbian</asp:ListItem>
+ <asp:ListItem Value="SH">Serbo-Croatian</asp:ListItem>
+ <asp:ListItem Value="ST">Sesotho</asp:ListItem>
+ <asp:ListItem Value="TN">Setswana</asp:ListItem>
+ <asp:ListItem Value="SN">Shona</asp:ListItem>
+ <asp:ListItem Value="SD">Sindhi</asp:ListItem>
+ <asp:ListItem Value="SI">Singhalese</asp:ListItem>
+ <asp:ListItem Value="SS">Siswati</asp:ListItem>
+ <asp:ListItem Value="SK">Slovak</asp:ListItem>
+ <asp:ListItem Value="SL">Slovenian</asp:ListItem>
+ <asp:ListItem Value="SO">Somali</asp:ListItem>
+ <asp:ListItem Value="ES">Spanish</asp:ListItem>
+ <asp:ListItem Value="SU">Sudanese</asp:ListItem>
+ <asp:ListItem Value="SW">Swahili</asp:ListItem>
+ <asp:ListItem Value="SV">Swedish</asp:ListItem>
+ <asp:ListItem Value="TL">Tagalog</asp:ListItem>
+ <asp:ListItem Value="TG">Tajik</asp:ListItem>
+ <asp:ListItem Value="TA">Tamil</asp:ListItem>
+ <asp:ListItem Value="TT">Tatar</asp:ListItem>
+ <asp:ListItem Value="TE">Telugu</asp:ListItem>
+ <asp:ListItem Value="TH">Thai</asp:ListItem>
+ <asp:ListItem Value="BO">Tibetan</asp:ListItem>
+ <asp:ListItem Value="TI">Tigrinya</asp:ListItem>
+ <asp:ListItem Value="TO">Tonga</asp:ListItem>
+ <asp:ListItem Value="TS">Tsonga</asp:ListItem>
+ <asp:ListItem Value="TR">Turkish</asp:ListItem>
+ <asp:ListItem Value="TK">Turkmen</asp:ListItem>
+ <asp:ListItem Value="TW">Twi</asp:ListItem>
+ <asp:ListItem Value="UK">Ukrainian</asp:ListItem>
+ <asp:ListItem Value="UR">Urdu</asp:ListItem>
+ <asp:ListItem Value="UZ">Uzbek</asp:ListItem>
+ <asp:ListItem Value="VI">Vietnamese</asp:ListItem>
+ <asp:ListItem Value="VO">Volapuk</asp:ListItem>
+ <asp:ListItem Value="CY">Welsh</asp:ListItem>
+ <asp:ListItem Value="WO">Wolof</asp:ListItem>
+ <asp:ListItem Value="XH">Xhosa</asp:ListItem>
+ <asp:ListItem Value="JI">Yiddish</asp:ListItem>
+ <asp:ListItem Value="YO">Yoruba</asp:ListItem>
+ <asp:ListItem Value="ZU">Zulu</asp:ListItem>
+ </asp:DropDownList>
+ </td>
+ </tr>
+ <tr runat="server" id="timezoneRow">
+ <td>
+ Timezone
+ <asp:Label ID="timezoneRequiredLabel" runat="server" Text="*" Visible="False"></asp:Label>
+ </td>
+ <td>
+ <asp:DropDownList runat="server" ID="timezoneDropdownList">
+ <asp:ListItem Value=""></asp:ListItem>
+ <asp:ListItem Value="Europe/London">Europe/London</asp:ListItem>
+ <asp:ListItem Value="Africa/Abidjan">Africa/Abidjan</asp:ListItem>
+ <asp:ListItem Value="Africa/Accra">Africa/Accra</asp:ListItem>
+ <asp:ListItem Value="Africa/Addis_Ababa">Africa/Addis_Ababa</asp:ListItem>
+ <asp:ListItem Value="Africa/Algiers">Africa/Algiers</asp:ListItem>
+ <asp:ListItem Value="Africa/Asmera">Africa/Asmera</asp:ListItem>
+ <asp:ListItem Value="Africa/Bamako">Africa/Bamako</asp:ListItem>
+ <asp:ListItem Value="Africa/Bangui">Africa/Bangui</asp:ListItem>
+ <asp:ListItem Value="Africa/Banjul">Africa/Banjul</asp:ListItem>
+ <asp:ListItem Value="Africa/Bissau">Africa/Bissau</asp:ListItem>
+ <asp:ListItem Value="Africa/Blantyre">Africa/Blantyre</asp:ListItem>
+ <asp:ListItem Value="Africa/Brazzaville">Africa/Brazzaville</asp:ListItem>
+ <asp:ListItem Value="Africa/Bujumbura">Africa/Bujumbura</asp:ListItem>
+ <asp:ListItem Value="Africa/Cairo">Africa/Cairo</asp:ListItem>
+ <asp:ListItem Value="Africa/Casablanca">Africa/Casablanca</asp:ListItem>
+ <asp:ListItem Value="Africa/Ceuta">Africa/Ceuta</asp:ListItem>
+ <asp:ListItem Value="Africa/Conakry">Africa/Conakry</asp:ListItem>
+ <asp:ListItem Value="Africa/Dakar">Africa/Dakar</asp:ListItem>
+ <asp:ListItem Value="Africa/Dar_es_Salaam">Africa/Dar_es_Salaam</asp:ListItem>
+ <asp:ListItem Value="Africa/Djibouti">Africa/Djibouti</asp:ListItem>
+ <asp:ListItem Value="Africa/Douala">Africa/Douala</asp:ListItem>
+ <asp:ListItem Value="Africa/El_Aaiun">Africa/El_Aaiun</asp:ListItem>
+ <asp:ListItem Value="Africa/Freetown">Africa/Freetown</asp:ListItem>
+ <asp:ListItem Value="Africa/Gaborone">Africa/Gaborone</asp:ListItem>
+ <asp:ListItem Value="Africa/Harare">Africa/Harare</asp:ListItem>
+ <asp:ListItem Value="Africa/Johannesburg">Africa/Johannesburg</asp:ListItem>
+ <asp:ListItem Value="Africa/Kampala">Africa/Kampala</asp:ListItem>
+ <asp:ListItem Value="Africa/Khartoum">Africa/Khartoum</asp:ListItem>
+ <asp:ListItem Value="Africa/Kigali">Africa/Kigali</asp:ListItem>
+ <asp:ListItem Value="Africa/Kinshasa">Africa/Kinshasa</asp:ListItem>
+ <asp:ListItem Value="Africa/Lagos">Africa/Lagos</asp:ListItem>
+ <asp:ListItem Value="Africa/Libreville">Africa/Libreville</asp:ListItem>
+ <asp:ListItem Value="Africa/Lome">Africa/Lome</asp:ListItem>
+ <asp:ListItem Value="Africa/Luanda">Africa/Luanda</asp:ListItem>
+ <asp:ListItem Value="Africa/Lubumbashi">Africa/Lubumbashi</asp:ListItem>
+ <asp:ListItem Value="Africa/Lusaka">Africa/Lusaka</asp:ListItem>
+ <asp:ListItem Value="Africa/Malabo">Africa/Malabo</asp:ListItem>
+ <asp:ListItem Value="Africa/Maputo">Africa/Maputo</asp:ListItem>
+ <asp:ListItem Value="Africa/Maseru">Africa/Maseru</asp:ListItem>
+ <asp:ListItem Value="Africa/Mbabane">Africa/Mbabane</asp:ListItem>
+ <asp:ListItem Value="Africa/Mogadishu">Africa/Mogadishu</asp:ListItem>
+ <asp:ListItem Value="Africa/Monrovia">Africa/Monrovia</asp:ListItem>
+ <asp:ListItem Value="Africa/Nairobi">Africa/Nairobi</asp:ListItem>
+ <asp:ListItem Value="Africa/Ndjamena">Africa/Ndjamena</asp:ListItem>
+ <asp:ListItem Value="Africa/Niamey">Africa/Niamey</asp:ListItem>
+ <asp:ListItem Value="Africa/Nouakchott">Africa/Nouakchott</asp:ListItem>
+ <asp:ListItem Value="Africa/Ouagadougou">Africa/Ouagadougou</asp:ListItem>
+ <asp:ListItem Value="Africa/Porto">Africa/Porto</asp:ListItem>
+ <asp:ListItem Value="Africa/Sao_Tome">Africa/Sao_Tome</asp:ListItem>
+ <asp:ListItem Value="Africa/Tripoli">Africa/Tripoli</asp:ListItem>
+ <asp:ListItem Value="Africa/Tunis">Africa/Tunis</asp:ListItem>
+ <asp:ListItem Value="Africa/Windhoek">Africa/Windhoek</asp:ListItem>
+ <asp:ListItem Value="America/Adak">America/Adak</asp:ListItem>
+ <asp:ListItem Value="America/Anchorage">America/Anchorage</asp:ListItem>
+ <asp:ListItem Value="America/Anguilla">America/Anguilla</asp:ListItem>
+ <asp:ListItem Value="America/Antigua">America/Antigua</asp:ListItem>
+ <asp:ListItem Value="America/Araguaina">America/Araguaina</asp:ListItem>
+ <asp:ListItem Value="America/Argentina/Buenos_Aires">America/Argentina/Buenos_Aires</asp:ListItem>
+ <asp:ListItem Value="America/Argentina/Catamarca">America/Argentina/Catamarca</asp:ListItem>
+ <asp:ListItem Value="America/Argentina/Cordoba">America/Argentina/Cordoba</asp:ListItem>
+ <asp:ListItem Value="America/Argentina/Jujuy">America/Argentina/Jujuy</asp:ListItem>
+ <asp:ListItem Value="America/Argentina/La_Rioja">America/Argentina/La_Rioja</asp:ListItem>
+ <asp:ListItem Value="America/Argentina/Mendoza">America/Argentina/Mendoza</asp:ListItem>
+ <asp:ListItem Value="America/Argentina/Rio_Gallegos">America/Argentina/Rio_Gallegos</asp:ListItem>
+ <asp:ListItem Value="America/Argentina/San_Juan">America/Argentina/San_Juan</asp:ListItem>
+ <asp:ListItem Value="America/Argentina/Tucuman">America/Argentina/Tucuman</asp:ListItem>
+ <asp:ListItem Value="America/Argentina/Ushuaia">America/Argentina/Ushuaia</asp:ListItem>
+ <asp:ListItem Value="America/Aruba">America/Aruba</asp:ListItem>
+ <asp:ListItem Value="America/Asuncion">America/Asuncion</asp:ListItem>
+ <asp:ListItem Value="America/Bahia">America/Bahia</asp:ListItem>
+ <asp:ListItem Value="America/Barbados">America/Barbados</asp:ListItem>
+ <asp:ListItem Value="America/Belem">America/Belem</asp:ListItem>
+ <asp:ListItem Value="America/Belize">America/Belize</asp:ListItem>
+ <asp:ListItem Value="America/Boa_Vista">America/Boa_Vista</asp:ListItem>
+ <asp:ListItem Value="America/Bogota">America/Bogota</asp:ListItem>
+ <asp:ListItem Value="America/Boise">America/Boise</asp:ListItem>
+ <asp:ListItem Value="America/Cambridge_Bay">America/Cambridge_Bay</asp:ListItem>
+ <asp:ListItem Value="America/Campo_Grande">America/Campo_Grande</asp:ListItem>
+ <asp:ListItem Value="America/Cancun">America/Cancun</asp:ListItem>
+ <asp:ListItem Value="America/Caracas">America/Caracas</asp:ListItem>
+ <asp:ListItem Value="America/Cayenne">America/Cayenne</asp:ListItem>
+ <asp:ListItem Value="America/Cayman">America/Cayman</asp:ListItem>
+ <asp:ListItem Value="America/Chicago">America/Chicago</asp:ListItem>
+ <asp:ListItem Value="America/Chihuahua">America/Chihuahua</asp:ListItem>
+ <asp:ListItem Value="America/Coral_Harbour">America/Coral_Harbour</asp:ListItem>
+ <asp:ListItem Value="America/Costa_Rica">America/Costa_Rica</asp:ListItem>
+ <asp:ListItem Value="America/Cuiaba">America/Cuiaba</asp:ListItem>
+ <asp:ListItem Value="America/Curacao">America/Curacao</asp:ListItem>
+ <asp:ListItem Value="America/Danmarkshavn">America/Danmarkshavn</asp:ListItem>
+ <asp:ListItem Value="America/Dawson">America/Dawson</asp:ListItem>
+ <asp:ListItem Value="America/Dawson_Creek">America/Dawson_Creek</asp:ListItem>
+ <asp:ListItem Value="America/Denver">America/Denver</asp:ListItem>
+ <asp:ListItem Value="America/Detroit">America/Detroit</asp:ListItem>
+ <asp:ListItem Value="America/Dominica">America/Dominica</asp:ListItem>
+ <asp:ListItem Value="America/Edmonton">America/Edmonton</asp:ListItem>
+ <asp:ListItem Value="America/Eirunepe">America/Eirunepe</asp:ListItem>
+ <asp:ListItem Value="America/El_Salvador">America/El_Salvador</asp:ListItem>
+ <asp:ListItem Value="America/Fortaleza">America/Fortaleza</asp:ListItem>
+ <asp:ListItem Value="America/Glace_Bay">America/Glace_Bay</asp:ListItem>
+ <asp:ListItem Value="America/Godthab">America/Godthab</asp:ListItem>
+ <asp:ListItem Value="America/Goose_Bay">America/Goose_Bay</asp:ListItem>
+ <asp:ListItem Value="America/Grand_Turk">America/Grand_Turk</asp:ListItem>
+ <asp:ListItem Value="America/Grenada">America/Grenada</asp:ListItem>
+ <asp:ListItem Value="America/Guadeloupe">America/Guadeloupe</asp:ListItem>
+ <asp:ListItem Value="America/Guatemala">America/Guatemala</asp:ListItem>
+ <asp:ListItem Value="America/Guayaquil">America/Guayaquil</asp:ListItem>
+ <asp:ListItem Value="America/Guyana">America/Guyana</asp:ListItem>
+ <asp:ListItem Value="America/Halifax">America/Halifax</asp:ListItem>
+ <asp:ListItem Value="America/Havana">America/Havana</asp:ListItem>
+ <asp:ListItem Value="America/Hermosillo">America/Hermosillo</asp:ListItem>
+ <asp:ListItem Value="America/Indiana/Indianapolis">America/Indiana/Indianapolis</asp:ListItem>
+ <asp:ListItem Value="America/Indiana/Knox">America/Indiana/Knox</asp:ListItem>
+ <asp:ListItem Value="America/Indiana/Marengo">America/Indiana/Marengo</asp:ListItem>
+ <asp:ListItem Value="America/Indiana/Petersburg">America/Indiana/Petersburg</asp:ListItem>
+ <asp:ListItem Value="America/Indiana/Vevay">America/Indiana/Vevay</asp:ListItem>
+ <asp:ListItem Value="America/Indiana/Vincennes">America/Indiana/Vincennes</asp:ListItem>
+ <asp:ListItem Value="America/Inuvik">America/Inuvik</asp:ListItem>
+ <asp:ListItem Value="America/Iqaluit">America/Iqaluit</asp:ListItem>
+ <asp:ListItem Value="America/Jamaica">America/Jamaica</asp:ListItem>
+ <asp:ListItem Value="America/Juneau">America/Juneau</asp:ListItem>
+ <asp:ListItem Value="America/Kentucky/Louisville">America/Kentucky/Louisville</asp:ListItem>
+ <asp:ListItem Value="America/Kentucky/Monticello">America/Kentucky/Monticello</asp:ListItem>
+ <asp:ListItem Value="America/La_Paz">America/La_Paz</asp:ListItem>
+ <asp:ListItem Value="America/Lima">America/Lima</asp:ListItem>
+ <asp:ListItem Value="America/Los_Angeles">America/Los_Angeles</asp:ListItem>
+ <asp:ListItem Value="America/Maceio">America/Maceio</asp:ListItem>
+ <asp:ListItem Value="America/Managua">America/Managua</asp:ListItem>
+ <asp:ListItem Value="America/Manaus">America/Manaus</asp:ListItem>
+ <asp:ListItem Value="America/Martinique">America/Martinique</asp:ListItem>
+ <asp:ListItem Value="America/Mazatlan">America/Mazatlan</asp:ListItem>
+ <asp:ListItem Value="America/Menominee">America/Menominee</asp:ListItem>
+ <asp:ListItem Value="America/Merida">America/Merida</asp:ListItem>
+ <asp:ListItem Value="America/Mexico_City">America/Mexico_City</asp:ListItem>
+ <asp:ListItem Value="America/Miquelon">America/Miquelon</asp:ListItem>
+ <asp:ListItem Value="America/Moncton">America/Moncton</asp:ListItem>
+ <asp:ListItem Value="America/Monterrey">America/Monterrey</asp:ListItem>
+ <asp:ListItem Value="America/Montevideo">America/Montevideo</asp:ListItem>
+ <asp:ListItem Value="America/Montreal">America/Montreal</asp:ListItem>
+ <asp:ListItem Value="America/Montserrat">America/Montserrat</asp:ListItem>
+ <asp:ListItem Value="America/Nassau">America/Nassau</asp:ListItem>
+ <asp:ListItem Value="America/New_York">America/New_York</asp:ListItem>
+ <asp:ListItem Value="America/Nipigon">America/Nipigon</asp:ListItem>
+ <asp:ListItem Value="America/Nome">America/Nome</asp:ListItem>
+ <asp:ListItem Value="America/Noronha">America/Noronha</asp:ListItem>
+ <asp:ListItem Value="America/North_Dakota/Center">America/North_Dakota/Center</asp:ListItem>
+ <asp:ListItem Value="America/Panama">America/Panama</asp:ListItem>
+ <asp:ListItem Value="America/Pangnirtung">America/Pangnirtung</asp:ListItem>
+ <asp:ListItem Value="America/Paramaribo">America/Paramaribo</asp:ListItem>
+ <asp:ListItem Value="America/Phoenix">America/Phoenix</asp:ListItem>
+ <asp:ListItem Value="America/Port">America/Port</asp:ListItem>
+ <asp:ListItem Value="America/Port_of_Spain">America/Port_of_Spain</asp:ListItem>
+ <asp:ListItem Value="America/Porto_Velho">America/Porto_Velho</asp:ListItem>
+ <asp:ListItem Value="America/Puerto_Rico">America/Puerto_Rico</asp:ListItem>
+ <asp:ListItem Value="America/Rainy_River">America/Rainy_River</asp:ListItem>
+ <asp:ListItem Value="America/Rankin_Inlet">America/Rankin_Inlet</asp:ListItem>
+ <asp:ListItem Value="America/Recife">America/Recife</asp:ListItem>
+ <asp:ListItem Value="America/Regina">America/Regina</asp:ListItem>
+ <asp:ListItem Value="America/Rio_Branco">America/Rio_Branco</asp:ListItem>
+ <asp:ListItem Value="America/Santiago">America/Santiago</asp:ListItem>
+ <asp:ListItem Value="America/Santo_Domingo">America/Santo_Domingo</asp:ListItem>
+ <asp:ListItem Value="America/Sao_Paulo">America/Sao_Paulo</asp:ListItem>
+ <asp:ListItem Value="America/Scoresbysund">America/Scoresbysund</asp:ListItem>
+ <asp:ListItem Value="America/Shiprock">America/Shiprock</asp:ListItem>
+ <asp:ListItem Value="America/St_Johns">America/St_Johns</asp:ListItem>
+ <asp:ListItem Value="America/St_Kitts">America/St_Kitts</asp:ListItem>
+ <asp:ListItem Value="America/St_Lucia">America/St_Lucia</asp:ListItem>
+ <asp:ListItem Value="America/St_Thomas">America/St_Thomas</asp:ListItem>
+ <asp:ListItem Value="America/St_Vincent">America/St_Vincent</asp:ListItem>
+ <asp:ListItem Value="America/Swift_Current">America/Swift_Current</asp:ListItem>
+ <asp:ListItem Value="America/Tegucigalpa">America/Tegucigalpa</asp:ListItem>
+ <asp:ListItem Value="America/Thule">America/Thule</asp:ListItem>
+ <asp:ListItem Value="America/Thunder_Bay">America/Thunder_Bay</asp:ListItem>
+ <asp:ListItem Value="America/Tijuana">America/Tijuana</asp:ListItem>
+ <asp:ListItem Value="America/Toronto">America/Toronto</asp:ListItem>
+ <asp:ListItem Value="America/Tortola">America/Tortola</asp:ListItem>
+ <asp:ListItem Value="America/Vancouver">America/Vancouver</asp:ListItem>
+ <asp:ListItem Value="America/Whitehorse">America/Whitehorse</asp:ListItem>
+ <asp:ListItem Value="America/Winnipeg">America/Winnipeg</asp:ListItem>
+ <asp:ListItem Value="America/Yakutat">America/Yakutat</asp:ListItem>
+ <asp:ListItem Value="America/Yellowknife">America/Yellowknife</asp:ListItem>
+ <asp:ListItem Value="Antarctica/Casey">Antarctica/Casey</asp:ListItem>
+ <asp:ListItem Value="Antarctica/Davis">Antarctica/Davis</asp:ListItem>
+ <asp:ListItem Value="Antarctica/DumontDUrville">Antarctica/DumontDUrville</asp:ListItem>
+ <asp:ListItem Value="Antarctica/Mawson">Antarctica/Mawson</asp:ListItem>
+ <asp:ListItem Value="Antarctica/McMurdo">Antarctica/McMurdo</asp:ListItem>
+ <asp:ListItem Value="Antarctica/Palmer">Antarctica/Palmer</asp:ListItem>
+ <asp:ListItem Value="Antarctica/Rothera">Antarctica/Rothera</asp:ListItem>
+ <asp:ListItem Value="Antarctica/South_Pole">Antarctica/South_Pole</asp:ListItem>
+ <asp:ListItem Value="Antarctica/Syowa">Antarctica/Syowa</asp:ListItem>
+ <asp:ListItem Value="Antarctica/Vostok">Antarctica/Vostok</asp:ListItem>
+ <asp:ListItem Value="Arctic/Longyearbyen">Arctic/Longyearbyen</asp:ListItem>
+ <asp:ListItem Value="Asia/Aden">Asia/Aden</asp:ListItem>
+ <asp:ListItem Value="Asia/Almaty">Asia/Almaty</asp:ListItem>
+ <asp:ListItem Value="Asia/Amman">Asia/Amman</asp:ListItem>
+ <asp:ListItem Value="Asia/Anadyr">Asia/Anadyr</asp:ListItem>
+ <asp:ListItem Value="Asia/Aqtau">Asia/Aqtau</asp:ListItem>
+ <asp:ListItem Value="Asia/Aqtobe">Asia/Aqtobe</asp:ListItem>
+ <asp:ListItem Value="Asia/Ashgabat">Asia/Ashgabat</asp:ListItem>
+ <asp:ListItem Value="Asia/Baghdad">Asia/Baghdad</asp:ListItem>
+ <asp:ListItem Value="Asia/Bahrain">Asia/Bahrain</asp:ListItem>
+ <asp:ListItem Value="Asia/Baku">Asia/Baku</asp:ListItem>
+ <asp:ListItem Value="Asia/Bangkok">Asia/Bangkok</asp:ListItem>
+ <asp:ListItem Value="Asia/Beirut">Asia/Beirut</asp:ListItem>
+ <asp:ListItem Value="Asia/Bishkek">Asia/Bishkek</asp:ListItem>
+ <asp:ListItem Value="Asia/Brunei">Asia/Brunei</asp:ListItem>
+ <asp:ListItem Value="Asia/Calcutta">Asia/Calcutta</asp:ListItem>
+ <asp:ListItem Value="Asia/Choibalsan">Asia/Choibalsan</asp:ListItem>
+ <asp:ListItem Value="Asia/Chongqing">Asia/Chongqing</asp:ListItem>
+ <asp:ListItem Value="Asia/Colombo">Asia/Colombo</asp:ListItem>
+ <asp:ListItem Value="Asia/Damascus">Asia/Damascus</asp:ListItem>
+ <asp:ListItem Value="Asia/Dhaka">Asia/Dhaka</asp:ListItem>
+ <asp:ListItem Value="Asia/Dili">Asia/Dili</asp:ListItem>
+ <asp:ListItem Value="Asia/Dubai">Asia/Dubai</asp:ListItem>
+ <asp:ListItem Value="Asia/Dushanbe">Asia/Dushanbe</asp:ListItem>
+ <asp:ListItem Value="Asia/Gaza">Asia/Gaza</asp:ListItem>
+ <asp:ListItem Value="Asia/Harbin">Asia/Harbin</asp:ListItem>
+ <asp:ListItem Value="Asia/Hong_Kong">Asia/Hong_Kong</asp:ListItem>
+ <asp:ListItem Value="Asia/Hovd">Asia/Hovd</asp:ListItem>
+ <asp:ListItem Value="Asia/Irkutsk">Asia/Irkutsk</asp:ListItem>
+ <asp:ListItem Value="Asia/Jakarta">Asia/Jakarta</asp:ListItem>
+ <asp:ListItem Value="Asia/Jayapura">Asia/Jayapura</asp:ListItem>
+ <asp:ListItem Value="Asia/Jerusalem">Asia/Jerusalem</asp:ListItem>
+ <asp:ListItem Value="Asia/Kabul">Asia/Kabul</asp:ListItem>
+ <asp:ListItem Value="Asia/Kamchatka">Asia/Kamchatka</asp:ListItem>
+ <asp:ListItem Value="Asia/Karachi">Asia/Karachi</asp:ListItem>
+ <asp:ListItem Value="Asia/Kashgar">Asia/Kashgar</asp:ListItem>
+ <asp:ListItem Value="Asia/Katmandu">Asia/Katmandu</asp:ListItem>
+ <asp:ListItem Value="Asia/Krasnoyarsk">Asia/Krasnoyarsk</asp:ListItem>
+ <asp:ListItem Value="Asia/Kuala_Lumpur">Asia/Kuala_Lumpur</asp:ListItem>
+ <asp:ListItem Value="Asia/Kuching">Asia/Kuching</asp:ListItem>
+ <asp:ListItem Value="Asia/Kuwait">Asia/Kuwait</asp:ListItem>
+ <asp:ListItem Value="Asia/Macau">Asia/Macau</asp:ListItem>
+ <asp:ListItem Value="Asia/Magadan">Asia/Magadan</asp:ListItem>
+ <asp:ListItem Value="Asia/Makassar">Asia/Makassar</asp:ListItem>
+ <asp:ListItem Value="Asia/Manila">Asia/Manila</asp:ListItem>
+ <asp:ListItem Value="Asia/Muscat">Asia/Muscat</asp:ListItem>
+ <asp:ListItem Value="Asia/Nicosia">Asia/Nicosia</asp:ListItem>
+ <asp:ListItem Value="Asia/Novosibirsk">Asia/Novosibirsk</asp:ListItem>
+ <asp:ListItem Value="Asia/Omsk">Asia/Omsk</asp:ListItem>
+ <asp:ListItem Value="Asia/Oral">Asia/Oral</asp:ListItem>
+ <asp:ListItem Value="Asia/Phnom_Penh">Asia/Phnom_Penh</asp:ListItem>
+ <asp:ListItem Value="Asia/Pontianak">Asia/Pontianak</asp:ListItem>
+ <asp:ListItem Value="Asia/Pyongyang">Asia/Pyongyang</asp:ListItem>
+ <asp:ListItem Value="Asia/Qatar">Asia/Qatar</asp:ListItem>
+ <asp:ListItem Value="Asia/Qyzylorda">Asia/Qyzylorda</asp:ListItem>
+ <asp:ListItem Value="Asia/Rangoon">Asia/Rangoon</asp:ListItem>
+ <asp:ListItem Value="Asia/Riyadh">Asia/Riyadh</asp:ListItem>
+ <asp:ListItem Value="Asia/Saigon">Asia/Saigon</asp:ListItem>
+ <asp:ListItem Value="Asia/Sakhalin">Asia/Sakhalin</asp:ListItem>
+ <asp:ListItem Value="Asia/Samarkand">Asia/Samarkand</asp:ListItem>
+ <asp:ListItem Value="Asia/Seoul">Asia/Seoul</asp:ListItem>
+ <asp:ListItem Value="Asia/Shanghai">Asia/Shanghai</asp:ListItem>
+ <asp:ListItem Value="Asia/Singapore">Asia/Singapore</asp:ListItem>
+ <asp:ListItem Value="Asia/Taipei">Asia/Taipei</asp:ListItem>
+ <asp:ListItem Value="Asia/Tashkent">Asia/Tashkent</asp:ListItem>
+ <asp:ListItem Value="Asia/Tbilisi">Asia/Tbilisi</asp:ListItem>
+ <asp:ListItem Value="Asia/Tehran">Asia/Tehran</asp:ListItem>
+ <asp:ListItem Value="Asia/Thimphu">Asia/Thimphu</asp:ListItem>
+ <asp:ListItem Value="Asia/Tokyo">Asia/Tokyo</asp:ListItem>
+ <asp:ListItem Value="Asia/Ulaanbaatar">Asia/Ulaanbaatar</asp:ListItem>
+ <asp:ListItem Value="Asia/Urumqi">Asia/Urumqi</asp:ListItem>
+ <asp:ListItem Value="Asia/Vientiane">Asia/Vientiane</asp:ListItem>
+ <asp:ListItem Value="Asia/Vladivostok">Asia/Vladivostok</asp:ListItem>
+ <asp:ListItem Value="Asia/Yakutsk">Asia/Yakutsk</asp:ListItem>
+ <asp:ListItem Value="Asia/Yekaterinburg">Asia/Yekaterinburg</asp:ListItem>
+ <asp:ListItem Value="Asia/Yerevan">Asia/Yerevan</asp:ListItem>
+ <asp:ListItem Value="Atlantic/Azores">Atlantic/Azores</asp:ListItem>
+ <asp:ListItem Value="Atlantic/Bermuda">Atlantic/Bermuda</asp:ListItem>
+ <asp:ListItem Value="Atlantic/Canary">Atlantic/Canary</asp:ListItem>
+ <asp:ListItem Value="Atlantic/Cape_Verde">Atlantic/Cape_Verde</asp:ListItem>
+ <asp:ListItem Value="Atlantic/Faeroe">Atlantic/Faeroe</asp:ListItem>
+ <asp:ListItem Value="Atlantic/Jan_Mayen">Atlantic/Jan_Mayen</asp:ListItem>
+ <asp:ListItem Value="Atlantic/Madeira">Atlantic/Madeira</asp:ListItem>
+ <asp:ListItem Value="Atlantic/Reykjavik">Atlantic/Reykjavik</asp:ListItem>
+ <asp:ListItem Value="Atlantic/South_Georgia">Atlantic/South_Georgia</asp:ListItem>
+ <asp:ListItem Value="Atlantic/St_Helena">Atlantic/St_Helena</asp:ListItem>
+ <asp:ListItem Value="Atlantic/Stanley">Atlantic/Stanley</asp:ListItem>
+ <asp:ListItem Value="Australia/Adelaide">Australia/Adelaide</asp:ListItem>
+ <asp:ListItem Value="Australia/Brisbane">Australia/Brisbane</asp:ListItem>
+ <asp:ListItem Value="Australia/Broken_Hill">Australia/Broken_Hill</asp:ListItem>
+ <asp:ListItem Value="Australia/Currie">Australia/Currie</asp:ListItem>
+ <asp:ListItem Value="Australia/Darwin">Australia/Darwin</asp:ListItem>
+ <asp:ListItem Value="Australia/Hobart">Australia/Hobart</asp:ListItem>
+ <asp:ListItem Value="Australia/Lindeman">Australia/Lindeman</asp:ListItem>
+ <asp:ListItem Value="Australia/Lord_Howe">Australia/Lord_Howe</asp:ListItem>
+ <asp:ListItem Value="Australia/Melbourne">Australia/Melbourne</asp:ListItem>
+ <asp:ListItem Value="Australia/Perth">Australia/Perth</asp:ListItem>
+ <asp:ListItem Value="Australia/Sydney">Australia/Sydney</asp:ListItem>
+ <asp:ListItem Value="Europe/Amsterdam">Europe/Amsterdam</asp:ListItem>
+ <asp:ListItem Value="Europe/Andorra">Europe/Andorra</asp:ListItem>
+ <asp:ListItem Value="Europe/Athens">Europe/Athens</asp:ListItem>
+ <asp:ListItem Value="Europe/Belgrade">Europe/Belgrade</asp:ListItem>
+ <asp:ListItem Value="Europe/Berlin">Europe/Berlin</asp:ListItem>
+ <asp:ListItem Value="Europe/Bratislava">Europe/Bratislava</asp:ListItem>
+ <asp:ListItem Value="Europe/Brussels">Europe/Brussels</asp:ListItem>
+ <asp:ListItem Value="Europe/Bucharest">Europe/Bucharest</asp:ListItem>
+ <asp:ListItem Value="Europe/Budapest">Europe/Budapest</asp:ListItem>
+ <asp:ListItem Value="Europe/Chisinau">Europe/Chisinau</asp:ListItem>
+ <asp:ListItem Value="Europe/Copenhagen">Europe/Copenhagen</asp:ListItem>
+ <asp:ListItem Value="Europe/Dublin">Europe/Dublin</asp:ListItem>
+ <asp:ListItem Value="Europe/Gibraltar">Europe/Gibraltar</asp:ListItem>
+ <asp:ListItem Value="Europe/Helsinki">Europe/Helsinki</asp:ListItem>
+ <asp:ListItem Value="Europe/Istanbul">Europe/Istanbul</asp:ListItem>
+ <asp:ListItem Value="Europe/Kaliningrad">Europe/Kaliningrad</asp:ListItem>
+ <asp:ListItem Value="Europe/Kiev">Europe/Kiev</asp:ListItem>
+ <asp:ListItem Value="Europe/Lisbon">Europe/Lisbon</asp:ListItem>
+ <asp:ListItem Value="Europe/Ljubljana">Europe/Ljubljana</asp:ListItem>
+ <asp:ListItem Value="Europe/Luxembourg">Europe/Luxembourg</asp:ListItem>
+ <asp:ListItem Value="Europe/Madrid">Europe/Madrid</asp:ListItem>
+ <asp:ListItem Value="Europe/Malta">Europe/Malta</asp:ListItem>
+ <asp:ListItem Value="Europe/Mariehamn">Europe/Mariehamn</asp:ListItem>
+ <asp:ListItem Value="Europe/Minsk">Europe/Minsk</asp:ListItem>
+ <asp:ListItem Value="Europe/Monaco">Europe/Monaco</asp:ListItem>
+ <asp:ListItem Value="Europe/Moscow">Europe/Moscow</asp:ListItem>
+ <asp:ListItem Value="Europe/Oslo">Europe/Oslo</asp:ListItem>
+ <asp:ListItem Value="Europe/Paris">Europe/Paris</asp:ListItem>
+ <asp:ListItem Value="Europe/Prague">Europe/Prague</asp:ListItem>
+ <asp:ListItem Value="Europe/Riga">Europe/Riga</asp:ListItem>
+ <asp:ListItem Value="Europe/Rome">Europe/Rome</asp:ListItem>
+ <asp:ListItem Value="Europe/Samara">Europe/Samara</asp:ListItem>
+ <asp:ListItem Value="Europe/San_Marino">Europe/San_Marino</asp:ListItem>
+ <asp:ListItem Value="Europe/Sarajevo">Europe/Sarajevo</asp:ListItem>
+ <asp:ListItem Value="Europe/Simferopol">Europe/Simferopol</asp:ListItem>
+ <asp:ListItem Value="Europe/Skopje">Europe/Skopje</asp:ListItem>
+ <asp:ListItem Value="Europe/Sofia">Europe/Sofia</asp:ListItem>
+ <asp:ListItem Value="Europe/Stockholm">Europe/Stockholm</asp:ListItem>
+ <asp:ListItem Value="Europe/Tallinn">Europe/Tallinn</asp:ListItem>
+ <asp:ListItem Value="Europe/Tirane">Europe/Tirane</asp:ListItem>
+ <asp:ListItem Value="Europe/Uzhgorod">Europe/Uzhgorod</asp:ListItem>
+ <asp:ListItem Value="Europe/Vaduz">Europe/Vaduz</asp:ListItem>
+ <asp:ListItem Value="Europe/Vatican">Europe/Vatican</asp:ListItem>
+ <asp:ListItem Value="Europe/Vienna">Europe/Vienna</asp:ListItem>
+ <asp:ListItem Value="Europe/Vilnius">Europe/Vilnius</asp:ListItem>
+ <asp:ListItem Value="Europe/Warsaw">Europe/Warsaw</asp:ListItem>
+ <asp:ListItem Value="Europe/Zagreb">Europe/Zagreb</asp:ListItem>
+ <asp:ListItem Value="Europe/Zaporozhye">Europe/Zaporozhye</asp:ListItem>
+ <asp:ListItem Value="Europe/Zurich">Europe/Zurich</asp:ListItem>
+ <asp:ListItem Value="Indian/Antananarivo">Indian/Antananarivo</asp:ListItem>
+ <asp:ListItem Value="Indian/Chagos">Indian/Chagos</asp:ListItem>
+ <asp:ListItem Value="Indian/Christmas">Indian/Christmas</asp:ListItem>
+ <asp:ListItem Value="Indian/Cocos">Indian/Cocos</asp:ListItem>
+ <asp:ListItem Value="Indian/Comoro">Indian/Comoro</asp:ListItem>
+ <asp:ListItem Value="Indian/Kerguelen">Indian/Kerguelen</asp:ListItem>
+ <asp:ListItem Value="Indian/Mahe">Indian/Mahe</asp:ListItem>
+ <asp:ListItem Value="Indian/Maldives">Indian/Maldives</asp:ListItem>
+ <asp:ListItem Value="Indian/Mauritius">Indian/Mauritius</asp:ListItem>
+ <asp:ListItem Value="Indian/Mayotte">Indian/Mayotte</asp:ListItem>
+ <asp:ListItem Value="Indian/Reunion">Indian/Reunion</asp:ListItem>
+ <asp:ListItem Value="Pacific/Apia">Pacific/Apia</asp:ListItem>
+ <asp:ListItem Value="Pacific/Auckland">Pacific/Auckland</asp:ListItem>
+ <asp:ListItem Value="Pacific/Chatham">Pacific/Chatham</asp:ListItem>
+ <asp:ListItem Value="Pacific/Easter">Pacific/Easter</asp:ListItem>
+ <asp:ListItem Value="Pacific/Efate">Pacific/Efate</asp:ListItem>
+ <asp:ListItem Value="Pacific/Enderbury">Pacific/Enderbury</asp:ListItem>
+ <asp:ListItem Value="Pacific/Fakaofo">Pacific/Fakaofo</asp:ListItem>
+ <asp:ListItem Value="Pacific/Fiji">Pacific/Fiji</asp:ListItem>
+ <asp:ListItem Value="Pacific/Funafuti">Pacific/Funafuti</asp:ListItem>
+ <asp:ListItem Value="Pacific/Galapagos">Pacific/Galapagos</asp:ListItem>
+ <asp:ListItem Value="Pacific/Gambier">Pacific/Gambier</asp:ListItem>
+ <asp:ListItem Value="Pacific/Guadalcanal">Pacific/Guadalcanal</asp:ListItem>
+ <asp:ListItem Value="Pacific/Guam">Pacific/Guam</asp:ListItem>
+ <asp:ListItem Value="Pacific/Honolulu">Pacific/Honolulu</asp:ListItem>
+ <asp:ListItem Value="Pacific/Johnston">Pacific/Johnston</asp:ListItem>
+ <asp:ListItem Value="Pacific/Kiritimati">Pacific/Kiritimati</asp:ListItem>
+ <asp:ListItem Value="Pacific/Kosrae">Pacific/Kosrae</asp:ListItem>
+ <asp:ListItem Value="Pacific/Kwajalein">Pacific/Kwajalein</asp:ListItem>
+ <asp:ListItem Value="Pacific/Majuro">Pacific/Majuro</asp:ListItem>
+ <asp:ListItem Value="Pacific/Marquesas">Pacific/Marquesas</asp:ListItem>
+ <asp:ListItem Value="Pacific/Midway">Pacific/Midway</asp:ListItem>
+ <asp:ListItem Value="Pacific/Nauru">Pacific/Nauru</asp:ListItem>
+ <asp:ListItem Value="Pacific/Niue">Pacific/Niue</asp:ListItem>
+ <asp:ListItem Value="Pacific/Norfolk">Pacific/Norfolk</asp:ListItem>
+ <asp:ListItem Value="Pacific/Noumea">Pacific/Noumea</asp:ListItem>
+ <asp:ListItem Value="Pacific/Pago_Pago">Pacific/Pago_Pago</asp:ListItem>
+ <asp:ListItem Value="Pacific/Palau">Pacific/Palau</asp:ListItem>
+ <asp:ListItem Value="Pacific/Pitcairn">Pacific/Pitcairn</asp:ListItem>
+ <asp:ListItem Value="Pacific/Ponape">Pacific/Ponape</asp:ListItem>
+ <asp:ListItem Value="Pacific/Port_Moresby">Pacific/Port_Moresby</asp:ListItem>
+ <asp:ListItem Value="Pacific/Rarotonga">Pacific/Rarotonga</asp:ListItem>
+ <asp:ListItem Value="Pacific/Saipan">Pacific/Saipan</asp:ListItem>
+ <asp:ListItem Value="Pacific/Tahiti">Pacific/Tahiti</asp:ListItem>
+ <asp:ListItem Value="Pacific/Tarawa">Pacific/Tarawa</asp:ListItem>
+ <asp:ListItem Value="Pacific/Tongatapu">Pacific/Tongatapu</asp:ListItem>
+ <asp:ListItem Value="Pacific/Truk">Pacific/Truk</asp:ListItem>
+ <asp:ListItem Value="Pacific/Wake">Pacific/Wake</asp:ListItem>
+ <asp:ListItem Value="Pacific/Wallis">Pacific/Wallis</asp:ListItem>
+ </asp:DropDownList>
+ &nbsp;
+ </td>
+ </tr>
+ <tr>
+ <td>
+ </td>
+ <td>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ Note: Fields marked with a * are required by the consumer
+ </td>
+ </tr>
+</table>
diff --git a/samples/OpenIdProviderWebForms/ProfileFields.ascx.cs b/samples/OpenIdProviderWebForms/ProfileFields.ascx.cs
new file mode 100644
index 0000000..893830f
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/ProfileFields.ascx.cs
@@ -0,0 +1,137 @@
+namespace OpenIdProviderWebForms {
+ using System;
+ using DotNetOpenAuth.OpenId.Extensions;
+ using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration;
+
+ /// <summary>
+ /// Handles the collection of the simple registration fields.
+ /// Only mandatory or optional fields are displayed. Mandatory fields have a '*' next to them.
+ /// No validation occurs here.
+ /// </summary>
+ public partial class ProfileFields : System.Web.UI.UserControl {
+ public bool DoesAnyFieldHaveAValue {
+ get {
+ return !((this.DateOfBirth == null)
+ && string.IsNullOrEmpty(this.countryDropdownList.SelectedValue)
+ && string.IsNullOrEmpty(this.emailTextBox.Text)
+ && string.IsNullOrEmpty(this.fullnameTextBox.Text)
+ && (this.Gender == null)
+ && string.IsNullOrEmpty(this.languageDropdownList.SelectedValue)
+ && string.IsNullOrEmpty(this.nicknameTextBox.Text)
+ && string.IsNullOrEmpty(this.postcodeTextBox.Text)
+ && string.IsNullOrEmpty(this.timezoneDropdownList.SelectedValue));
+ }
+ }
+
+ public DateTime? DateOfBirth {
+ get {
+ try {
+ int day = Convert.ToInt32(this.dobDayDropdownlist.SelectedValue);
+ int month = Convert.ToInt32(this.dobMonthDropdownlist.SelectedValue);
+ int year = Convert.ToInt32(this.dobYearDropdownlist.SelectedValue);
+ DateTime newDate = new DateTime(year, month, day);
+ return newDate;
+ } catch (Exception) {
+ return null;
+ }
+ }
+
+ set {
+ if (value.HasValue) {
+ this.dobDayDropdownlist.SelectedValue = value.Value.Day.ToString();
+ this.dobMonthDropdownlist.SelectedValue = value.Value.Month.ToString();
+ this.dobYearDropdownlist.SelectedValue = value.Value.Year.ToString();
+ } else {
+ this.dobDayDropdownlist.SelectedValue = string.Empty;
+ this.dobMonthDropdownlist.SelectedValue = string.Empty;
+ this.dobYearDropdownlist.SelectedValue = string.Empty;
+ }
+ }
+ }
+
+ public Gender? Gender {
+ get {
+ if (this.genderDropdownList.SelectedValue == "Male") {
+ return DotNetOpenAuth.OpenId.Extensions.SimpleRegistration.Gender.Male;
+ }
+ if (this.genderDropdownList.SelectedValue == "Female") {
+ return DotNetOpenAuth.OpenId.Extensions.SimpleRegistration.Gender.Female;
+ }
+ return null;
+ }
+
+ set {
+ if (value.HasValue) {
+ this.genderDropdownList.SelectedValue = value.Value.ToString();
+ } else {
+ this.genderDropdownList.SelectedIndex = -1;
+ }
+ }
+ }
+
+ public void SetRequiredFieldsFromRequest(ClaimsRequest requestFields) {
+ if (requestFields.PolicyUrl != null) {
+ this.privacyLink.NavigateUrl = requestFields.PolicyUrl.AbsoluteUri;
+ } else {
+ this.privacyLink.Visible = false;
+ }
+
+ this.dobRequiredLabel.Visible = (requestFields.BirthDate == DemandLevel.Require);
+ this.countryRequiredLabel.Visible = (requestFields.Country == DemandLevel.Require);
+ this.emailRequiredLabel.Visible = (requestFields.Email == DemandLevel.Require);
+ this.fullnameRequiredLabel.Visible = (requestFields.FullName == DemandLevel.Require);
+ this.genderRequiredLabel.Visible = (requestFields.Gender == DemandLevel.Require);
+ this.languageRequiredLabel.Visible = (requestFields.Language == DemandLevel.Require);
+ this.nicknameRequiredLabel.Visible = (requestFields.Nickname == DemandLevel.Require);
+ this.postcodeRequiredLabel.Visible = (requestFields.PostalCode == DemandLevel.Require);
+ this.timezoneRequiredLabel.Visible = (requestFields.TimeZone == DemandLevel.Require);
+
+ this.dateOfBirthRow.Visible = !(requestFields.BirthDate == DemandLevel.NoRequest);
+ this.countryRow.Visible = !(requestFields.Country == DemandLevel.NoRequest);
+ this.emailRow.Visible = !(requestFields.Email == DemandLevel.NoRequest);
+ this.fullnameRow.Visible = !(requestFields.FullName == DemandLevel.NoRequest);
+ this.genderRow.Visible = !(requestFields.Gender == DemandLevel.NoRequest);
+ this.languageRow.Visible = !(requestFields.Language == DemandLevel.NoRequest);
+ this.nicknameRow.Visible = !(requestFields.Nickname == DemandLevel.NoRequest);
+ this.postcodeRow.Visible = !(requestFields.PostalCode == DemandLevel.NoRequest);
+ this.timezoneRow.Visible = !(requestFields.TimeZone == DemandLevel.NoRequest);
+ }
+
+ public ClaimsResponse GetOpenIdProfileFields(ClaimsRequest request) {
+ if (request == null) {
+ throw new ArgumentNullException("request");
+ }
+
+ ClaimsResponse fields = request.CreateResponse();
+ fields.BirthDate = this.DateOfBirth;
+ fields.Country = this.countryDropdownList.SelectedValue;
+ fields.Email = this.emailTextBox.Text;
+ fields.FullName = this.fullnameTextBox.Text;
+ fields.Gender = this.Gender;
+ fields.Language = this.languageDropdownList.SelectedValue;
+ fields.Nickname = this.nicknameTextBox.Text;
+ fields.PostalCode = this.postcodeTextBox.Text;
+ fields.TimeZone = this.timezoneDropdownList.SelectedValue;
+ return fields;
+ }
+
+ public void SetOpenIdProfileFields(ClaimsResponse value) {
+ if (value == null) {
+ throw new ArgumentNullException("value");
+ }
+
+ this.DateOfBirth = value.BirthDate;
+ this.countryDropdownList.SelectedValue = value.Country;
+ this.emailTextBox.Text = value.Email;
+ this.fullnameTextBox.Text = value.FullName;
+ this.Gender = value.Gender;
+ this.languageDropdownList.SelectedValue = value.Language;
+ this.nicknameTextBox.Text = value.Nickname;
+ this.postcodeTextBox.Text = value.PostalCode;
+ this.timezoneDropdownList.SelectedValue = value.TimeZone;
+ }
+
+ protected void Page_Load(object sender, EventArgs e) {
+ }
+ }
+} \ No newline at end of file
diff --git a/samples/OpenIdProviderWebForms/ProfileFields.ascx.designer.cs b/samples/OpenIdProviderWebForms/ProfileFields.ascx.designer.cs
new file mode 100644
index 0000000..e546539
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/ProfileFields.ascx.designer.cs
@@ -0,0 +1,286 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.3521
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OpenIdProviderWebForms {
+
+
+ public partial class ProfileFields {
+
+ /// <summary>
+ /// privacyLink control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.HyperLink privacyLink;
+
+ /// <summary>
+ /// nicknameRow control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.HtmlControls.HtmlTableRow nicknameRow;
+
+ /// <summary>
+ /// nicknameRequiredLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label nicknameRequiredLabel;
+
+ /// <summary>
+ /// nicknameTextBox control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.TextBox nicknameTextBox;
+
+ /// <summary>
+ /// emailRow control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.HtmlControls.HtmlTableRow emailRow;
+
+ /// <summary>
+ /// emailRequiredLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label emailRequiredLabel;
+
+ /// <summary>
+ /// emailTextBox control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.TextBox emailTextBox;
+
+ /// <summary>
+ /// fullnameRow control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.HtmlControls.HtmlTableRow fullnameRow;
+
+ /// <summary>
+ /// fullnameRequiredLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label fullnameRequiredLabel;
+
+ /// <summary>
+ /// fullnameTextBox control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.TextBox fullnameTextBox;
+
+ /// <summary>
+ /// dateOfBirthRow control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.HtmlControls.HtmlTableRow dateOfBirthRow;
+
+ /// <summary>
+ /// dobRequiredLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label dobRequiredLabel;
+
+ /// <summary>
+ /// dobDayDropdownlist control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.DropDownList dobDayDropdownlist;
+
+ /// <summary>
+ /// dobMonthDropdownlist control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.DropDownList dobMonthDropdownlist;
+
+ /// <summary>
+ /// dobYearDropdownlist control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.DropDownList dobYearDropdownlist;
+
+ /// <summary>
+ /// genderRow control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.HtmlControls.HtmlTableRow genderRow;
+
+ /// <summary>
+ /// genderRequiredLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label genderRequiredLabel;
+
+ /// <summary>
+ /// genderDropdownList control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.DropDownList genderDropdownList;
+
+ /// <summary>
+ /// postcodeRow control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.HtmlControls.HtmlTableRow postcodeRow;
+
+ /// <summary>
+ /// postcodeRequiredLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label postcodeRequiredLabel;
+
+ /// <summary>
+ /// postcodeTextBox control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.TextBox postcodeTextBox;
+
+ /// <summary>
+ /// countryRow control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.HtmlControls.HtmlTableRow countryRow;
+
+ /// <summary>
+ /// countryRequiredLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label countryRequiredLabel;
+
+ /// <summary>
+ /// countryDropdownList control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.DropDownList countryDropdownList;
+
+ /// <summary>
+ /// languageRow control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.HtmlControls.HtmlTableRow languageRow;
+
+ /// <summary>
+ /// languageRequiredLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label languageRequiredLabel;
+
+ /// <summary>
+ /// languageDropdownList control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.DropDownList languageDropdownList;
+
+ /// <summary>
+ /// timezoneRow control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.HtmlControls.HtmlTableRow timezoneRow;
+
+ /// <summary>
+ /// timezoneRequiredLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label timezoneRequiredLabel;
+
+ /// <summary>
+ /// timezoneDropdownList control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.DropDownList timezoneDropdownList;
+ }
+}
diff --git a/samples/OpenIdProviderWebForms/Properties/AssemblyInfo.cs b/samples/OpenIdProviderWebForms/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..42b2126
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/Properties/AssemblyInfo.cs
@@ -0,0 +1,35 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("OpenIdProviderWebForms sample")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ProviderPortal")]
+[assembly: AssemblyCopyright("Copyright © 2008")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("3d5900ae-111a-45be-96b3-d9e4606ca793")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/samples/OpenIdProviderWebForms/Provider.ashx b/samples/OpenIdProviderWebForms/Provider.ashx
new file mode 100644
index 0000000..aa90b8f
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/Provider.ashx
@@ -0,0 +1 @@
+<%@ WebHandler Language="C#" CodeBehind="Provider.ashx.cs" Class="OpenIdProviderWebForms.Provider" %>
diff --git a/samples/OpenIdProviderWebForms/Provider.ashx.cs b/samples/OpenIdProviderWebForms/Provider.ashx.cs
new file mode 100644
index 0000000..5257a5d
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/Provider.ashx.cs
@@ -0,0 +1,61 @@
+namespace OpenIdProviderWebForms {
+ using System.Web;
+ using System.Web.SessionState;
+ using DotNetOpenAuth.OpenId.Provider;
+
+ /// <summary>
+ /// A fast OpenID message handler that responds to OpenID messages
+ /// directed at the Provider.
+ /// </summary>
+ /// <remarks>
+ /// This performs the same function as server.aspx, which uses the ProviderEndpoint
+ /// control to reduce the amount of source code in the web site. A typical Provider
+ /// site will have EITHER this .ashx handler OR the .aspx page -- NOT both.
+ /// </remarks>
+ public class Provider : IHttpHandler, IRequiresSessionState {
+ public bool IsReusable {
+ get { return true; }
+ }
+
+ public void ProcessRequest(HttpContext context) {
+ OpenIdProvider provider = new OpenIdProvider();
+ IRequest request = provider.GetRequest();
+ if (request != null) {
+ // Some OpenID requests are automatable and can be responded to immediately.
+ if (!request.IsResponseReady) {
+ // But authentication requests cannot be responded to until something on
+ // this site decides whether to approve or disapprove the authentication.
+ var idrequest = (IAuthenticationRequest)request;
+
+ // We store the authentication request in the user's session so that
+ // redirects and user prompts can appear and eventually some page can decide
+ // to respond to the OpenID authentication request either affirmatively or
+ // negatively.
+ ProviderEndpoint.PendingAuthenticationRequest = idrequest;
+
+ // We delegate that approval process to our utility method that we share
+ // with our other Provider sample page server.aspx.
+ Code.Util.ProcessAuthenticationChallenge(idrequest);
+
+ // As part of authentication approval, the user may need to authenticate
+ // to this Provider and/or decide whether to allow the requesting RP site
+ // to log this user in. If any UI needs to be presented to the user,
+ // the previous call to ProcessAuthenticationChallenge MAY not return
+ // due to a redirect to some ASPX page.
+ } else {
+ // Some other automatable OpenID request is coming down, so clear
+ // any previously session stored authentication request that might be
+ // stored for this user.
+ ProviderEndpoint.PendingAuthenticationRequest = null;
+ }
+
+ // Whether this was an automated message or an authentication message,
+ // if there is a response ready to send back immediately, do so.
+ if (request.IsResponseReady) {
+ request.Response.Send();
+ ProviderEndpoint.PendingAuthenticationRequest = null;
+ }
+ }
+ }
+ }
+}
diff --git a/samples/OpenIdProviderWebForms/Site.Master b/samples/OpenIdProviderWebForms/Site.Master
new file mode 100644
index 0000000..c7aa510
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/Site.Master
@@ -0,0 +1,20 @@
+<%@ Master Language="C#" AutoEventWireup="true" %>
+
+<!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 id="Head1" runat="server">
+ <title>OpenID Provider, by DotNetOpenId</title>
+ <link href="/styles.css" rel="stylesheet" type="text/css" />
+ <asp:ContentPlaceHolder ID="head" runat="server" />
+</head>
+<body>
+ <form id="form1" runat="server">
+ <div><a href="http://dotnetopenid.googlecode.com">
+ <img runat="server" src="~/images/dotnetopenid_tiny.gif" title="Jump to the project web site."
+ alt="DotNetOpenId" border='0' /></a> </div>
+ <div>
+ <asp:ContentPlaceHolder ID="Main" runat="server" />
+ </div>
+ </form>
+</body>
+</html>
diff --git a/samples/OpenIdProviderWebForms/TracePage.aspx b/samples/OpenIdProviderWebForms/TracePage.aspx
new file mode 100644
index 0000000..615b445
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/TracePage.aspx
@@ -0,0 +1,16 @@
+<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="TracePage.aspx.cs" Inherits="OpenIdProviderWebForms.TracePage" %>
+
+<!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">
+ <title></title>
+</head>
+<body>
+ <form id="form1" runat="server">
+ <p align="right">
+ <asp:Button runat="server" Text="Clear log" ID="clearLogButton" OnClick="clearLogButton_Click" />
+ </p>
+ <pre><asp:PlaceHolder runat="server" ID="placeHolder1" /></pre>
+ </form>
+</body>
+</html>
diff --git a/samples/OpenIdProviderWebForms/TracePage.aspx.cs b/samples/OpenIdProviderWebForms/TracePage.aspx.cs
new file mode 100644
index 0000000..5dcb18f
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/TracePage.aspx.cs
@@ -0,0 +1,21 @@
+namespace OpenIdProviderWebForms {
+ using System;
+ using System.Collections.Generic;
+ using System.Web;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+ using OpenIdProviderWebForms.Code;
+
+ public partial class TracePage : System.Web.UI.Page {
+ protected void Page_Load(object sender, EventArgs e) {
+ this.placeHolder1.Controls.Add(new Label { Text = Global.LogMessages.ToString() });
+ }
+
+ protected void clearLogButton_Click(object sender, EventArgs e) {
+ Global.LogMessages.Length = 0;
+
+ // clear the page immediately, and allow for F5 without a Postback warning.
+ Response.Redirect(Request.Url.AbsoluteUri);
+ }
+ }
+} \ No newline at end of file
diff --git a/samples/OpenIdProviderWebForms/TracePage.aspx.designer.cs b/samples/OpenIdProviderWebForms/TracePage.aspx.designer.cs
new file mode 100644
index 0000000..6760f9b
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/TracePage.aspx.designer.cs
@@ -0,0 +1,43 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.3521
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OpenIdProviderWebForms {
+
+
+ public partial class TracePage {
+
+ /// <summary>
+ /// form1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.HtmlControls.HtmlForm form1;
+
+ /// <summary>
+ /// clearLogButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button clearLogButton;
+
+ /// <summary>
+ /// placeHolder1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.PlaceHolder placeHolder1;
+ }
+}
diff --git a/samples/OpenIdProviderWebForms/Web.config b/samples/OpenIdProviderWebForms/Web.config
new file mode 100644
index 0000000..598e4bf
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/Web.config
@@ -0,0 +1,192 @@
+<?xml version="1.0"?>
+<!--
+ Note: As an alternative to hand editing this file you can use the
+ web admin tool to configure settings for your application. Use
+ the Website->Asp.Net Configuration option in Visual Studio.
+ A full list of settings and comments can be found in
+ machine.config.comments usually located in
+ \Windows\Microsoft.Net\Framework\v2.x\Config
+-->
+<configuration>
+ <configSections>
+ <section name="uri" type="System.Configuration.UriSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
+ <section name="urlrewrites" type="OpenIdProviderWebForms.Code.URLRewriter" requirePermission="false"/>
+ <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler" requirePermission="false"/>
+ <section name="dotNetOpenAuth" type="DotNetOpenAuth.Configuration.DotNetOpenAuthSection" requirePermission="false" allowLocation="true"/>
+ <sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
+ <sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
+ <section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
+ <sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
+ <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>
+ <section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
+ <section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
+ <section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
+ </sectionGroup>
+ </sectionGroup>
+ </sectionGroup>
+ </configSections>
+ <!-- this is an optional configuration section where aspects of dotnetopenid can be customized -->
+ <dotNetOpenAuth>
+ <openid>
+ <provider>
+ <!-- Uncomment the following to activate the sample custom store. -->
+ <!--<store type="OpenIdProviderWebForms.Code.CustomStore, OpenIdProviderWebForms" />-->
+ </provider>
+ </openid>
+ <messaging>
+ <untrustedWebRequest>
+ <whitelistHosts>
+ <!-- since this is a sample, and will often be used with localhost -->
+ <add name="localhost"/>
+ </whitelistHosts>
+ </untrustedWebRequest>
+ </messaging>
+ </dotNetOpenAuth>
+ <!-- The uri section is necessary to turn on .NET 3.5 support for IDN (international domain names),
+ which is necessary for OpenID urls with unicode characters in the domain/host name. -->
+ <uri>
+ <idn enabled="All"/>
+ <iriParsing enabled="true"/>
+ </uri>
+ <connectionStrings/>
+ <!--
+ Original version created by Richard Birkby (2002-02-22, http://www.codeproject.com/aspnet/URLRewriter.asp)
+ Maps from old website to new website using Regular Expressions
+ rule/url - old website url (Regular Expression)
+ rule/rewrite - new website replacement expression
+ Of two or more rules which match a given request, the first will always take precedance.
+ -->
+ <urlrewrites>
+ <rule>
+ <!-- This rewrites urls like: user/john ->user.aspx?username=john-->
+ <url>/user/(.*)</url>
+ <rewrite>/user.aspx?username=$1</rewrite>
+ </rule>
+ </urlrewrites>
+ <system.web>
+ <!--
+ Set compilation debug="true" to insert debugging
+ symbols into the compiled page. Because this
+ affects performance, set this value to true only
+ during development.
+ -->
+ <compilation debug="true">
+ <assemblies>
+ <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
+ <add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+ <add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
+ <add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
+ </assemblies>
+ </compilation>
+ <sessionState mode="InProc" cookieless="false"/>
+ <membership defaultProvider="AspNetReadOnlyXmlMembershipProvider">
+ <providers>
+ <clear/>
+ <add name="AspNetReadOnlyXmlMembershipProvider" type="OpenIdProviderWebForms.Code.ReadOnlyXmlMembershipProvider" description="Read-only XML membership provider" xmlFileName="~/App_Data/Users.xml"/>
+ </providers>
+ </membership>
+ <authentication mode="Forms">
+ <forms name="ProviderSession"/>
+ <!-- named cookie prevents conflicts with other samples -->
+ </authentication>
+ <customErrors mode="RemoteOnly"/>
+ <!-- Trust level discussion:
+ Full: everything works
+ High: TRACE compilation symbol must NOT be defined
+ Medium/Low: doesn't work on default machine.config, because WebPermission.Connect is denied.
+ -->
+ <trust level="High" originUrl=""/>
+ <pages>
+ <controls>
+ <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+ <add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+ </controls>
+ </pages>
+ <httpHandlers>
+ <remove verb="*" path="*.asmx"/>
+ <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+ <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+ <add verb="GET,HEAD" path="ScriptResource.axd" validate="false" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+ </httpHandlers>
+ <httpModules>
+ <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+ </httpModules>
+ </system.web>
+ <location path="decide.aspx">
+ <system.web>
+ <authorization>
+ <deny users="?"/>
+ </authorization>
+ </system.web>
+ </location>
+ <!-- log4net is a 3rd party (free) logger library that dotnetopenid will use if present but does not require. -->
+ <log4net>
+ <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
+ <file value="Provider.log"/>
+ <appendToFile value="true"/>
+ <rollingStyle value="Size"/>
+ <maxSizeRollBackups value="10"/>
+ <maximumFileSize value="100KB"/>
+ <staticLogFileName value="true"/>
+ <layout type="log4net.Layout.PatternLayout">
+ <conversionPattern value="%date (GMT%date{%z}) [%thread] %-5level %logger - %message%newline"/>
+ </layout>
+ </appender>
+ <appender name="TracePageAppender" type="ProviderPortal.Code.TracePageAppender, ProviderPortal">
+ <layout type="log4net.Layout.PatternLayout">
+ <conversionPattern value="%date (GMT%date{%z}) [%thread] %-5level %logger - %message%newline"/>
+ </layout>
+ </appender>
+ <!-- Setup the root category, add the appenders and set the default level -->
+ <root>
+ <level value="INFO"/>
+ <!--<appender-ref ref="RollingFileAppender" />-->
+ <appender-ref ref="TracePageAppender"/>
+ </root>
+ <!-- Specify the level for some specific categories -->
+ <logger name="DotNetOpenId">
+ <level value="ALL"/>
+ </logger>
+ </log4net>
+ <system.codedom>
+ <compilers>
+ <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CSharp.CSharpCodeProvider,System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" warningLevel="4">
+ <providerOption name="CompilerVersion" value="v3.5"/>
+ <providerOption name="WarnAsError" value="false"/>
+ </compiler>
+ <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.VisualBasic.VBCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" warningLevel="4">
+ <providerOption name="CompilerVersion" value="v3.5"/>
+ <providerOption name="OptionInfer" value="true"/>
+ <providerOption name="WarnAsError" value="false"/>
+ </compiler>
+ </compilers>
+ </system.codedom>
+ <system.webServer>
+ <validation validateIntegratedModeConfiguration="false"/>
+ <modules>
+ <remove name="ScriptModule"/>
+ <add name="ScriptModule" preCondition="managedHandler" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+ </modules>
+ <handlers>
+ <remove name="WebServiceHandlerFactory-Integrated"/>
+ <remove name="ScriptHandlerFactory"/>
+ <remove name="ScriptHandlerFactoryAppServices"/>
+ <remove name="ScriptResource"/>
+ <add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+ <add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+ <add name="ScriptResource" verb="GET,HEAD" path="ScriptResource.axd" preCondition="integratedMode" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+ </handlers>
+ </system.webServer>
+ <runtime>
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+ <dependentAssembly>
+ <assemblyIdentity name="System.Web.Extensions" publicKeyToken="31bf3856ad364e35"/>
+ <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Web.Extensions.Design" publicKeyToken="31bf3856ad364e35"/>
+ <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
+ </dependentAssembly>
+ </assemblyBinding>
+ </runtime>
+</configuration>
diff --git a/samples/OpenIdProviderWebForms/decide.aspx b/samples/OpenIdProviderWebForms/decide.aspx
new file mode 100644
index 0000000..54c2f01
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/decide.aspx
@@ -0,0 +1,34 @@
+<%@ Page Language="C#" AutoEventWireup="true" Inherits="OpenIdProviderWebForms.decide" CodeBehind="decide.aspx.cs" MasterPageFile="~/Site.Master" %>
+
+<%@ Register Src="ProfileFields.ascx" TagName="ProfileFields" TagPrefix="uc1" %>
+<asp:Content runat="server" ContentPlaceHolderID="Main">
+ <p>
+ A site has asked to authenticate that you own the identifier below.&nbsp; You should
+ only do this if you wish to log in to the site given by the Realm.</p>
+ <p>
+ This site
+ <asp:Label ID="relyingPartyVerificationResultLabel" runat="server"
+ Font-Bold="True" Text="failed" /> verification. </p>
+ <table>
+ <tr>
+ <td>
+ Identifier: </td>
+ <td>
+ <asp:Label runat="server" ID='identityUrlLabel' />
+ </td>
+ </tr>
+ <tr>
+ <td>
+ Realm: </td>
+ <td>
+ <asp:Label runat="server" ID='realmLabel' />
+ </td>
+ </tr>
+ </table>
+ <p>
+ Allow this authentication to proceed?
+ </p>
+ <uc1:ProfileFields ID="profileFields" runat="server" Visible="false" />
+ <asp:Button ID="yes_button" OnClick="Yes_Click" Text=" yes " runat="Server" />
+ <asp:Button ID="no_button" OnClick="No_Click" Text=" no " runat="Server" />
+</asp:Content> \ No newline at end of file
diff --git a/samples/OpenIdProviderWebForms/decide.aspx.cs b/samples/OpenIdProviderWebForms/decide.aspx.cs
new file mode 100644
index 0000000..1ca0138
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/decide.aspx.cs
@@ -0,0 +1,75 @@
+namespace OpenIdProviderWebForms {
+ using System;
+ using System.Diagnostics;
+ using System.Web.Security;
+ using System.Web.UI;
+ using DotNetOpenAuth.OpenId.Extensions.ProviderAuthenticationPolicy;
+ using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration;
+ using DotNetOpenAuth.OpenId.Provider;
+
+ /// <summary>
+ /// Page for giving the user the option to continue or cancel out of authentication with a consumer.
+ /// </summary>
+ public partial class decide : Page {
+ protected void Page_Load(object src, EventArgs e) {
+ if (ProviderEndpoint.PendingAuthenticationRequest == null) {
+ Response.Redirect("~/");
+ }
+
+ if (ProviderEndpoint.PendingAuthenticationRequest.IsDirectedIdentity) {
+ ProviderEndpoint.PendingAuthenticationRequest.LocalIdentifier = Code.Util.BuildIdentityUrl();
+ }
+ this.relyingPartyVerificationResultLabel.Text =
+ ProviderEndpoint.PendingAuthenticationRequest.IsReturnUrlDiscoverable ? "passed" : "failed";
+
+ this.identityUrlLabel.Text = ProviderEndpoint.PendingAuthenticationRequest.LocalIdentifier.ToString();
+ this.realmLabel.Text = ProviderEndpoint.PendingAuthenticationRequest.Realm.ToString();
+
+ // check that the logged in user is the same as the user requesting authentication to the consumer. If not, then log them out.
+ if (string.Equals(User.Identity.Name, Code.Util.ExtractUserName(ProviderEndpoint.PendingAuthenticationRequest.LocalIdentifier), StringComparison.OrdinalIgnoreCase)) {
+ // if simple registration fields were used, then prompt the user for them
+ var requestedFields = ProviderEndpoint.PendingAuthenticationRequest.GetExtension<ClaimsRequest>();
+ if (requestedFields != null) {
+ this.profileFields.Visible = true;
+ this.profileFields.SetRequiredFieldsFromRequest(requestedFields);
+ if (!IsPostBack) {
+ var sregResponse = requestedFields.CreateResponse();
+ sregResponse.Email = Membership.GetUser().Email;
+ this.profileFields.SetOpenIdProfileFields(sregResponse);
+ }
+ }
+ } else {
+ FormsAuthentication.SignOut();
+ Response.Redirect(Request.Url.AbsoluteUri);
+ }
+ }
+
+ protected void Yes_Click(object sender, EventArgs e) {
+ var sregRequest = ProviderEndpoint.PendingAuthenticationRequest.GetExtension<ClaimsRequest>();
+ ClaimsResponse sregResponse = null;
+ if (sregRequest != null) {
+ sregResponse = this.profileFields.GetOpenIdProfileFields(sregRequest);
+ ProviderEndpoint.PendingAuthenticationRequest.AddResponseExtension(sregResponse);
+ }
+ var papeRequest = ProviderEndpoint.PendingAuthenticationRequest.GetExtension<PolicyRequest>();
+ PolicyResponse papeResponse = null;
+ if (papeRequest != null) {
+ papeResponse = new PolicyResponse();
+ papeResponse.NistAssuranceLevel = NistAssuranceLevel.InsufficientForLevel1;
+ ProviderEndpoint.PendingAuthenticationRequest.AddResponseExtension(papeResponse);
+ }
+
+ ProviderEndpoint.PendingAuthenticationRequest.IsAuthenticated = true;
+ Debug.Assert(ProviderEndpoint.PendingAuthenticationRequest.IsResponseReady, "Setting authentication should be all that's necessary.");
+ ProviderEndpoint.PendingAuthenticationRequest.Response.Send();
+ ProviderEndpoint.PendingAuthenticationRequest = null;
+ }
+
+ protected void No_Click(object sender, EventArgs e) {
+ ProviderEndpoint.PendingAuthenticationRequest.IsAuthenticated = false;
+ Debug.Assert(ProviderEndpoint.PendingAuthenticationRequest.IsResponseReady, "Setting authentication should be all that's necessary.");
+ ProviderEndpoint.PendingAuthenticationRequest.Response.Send();
+ ProviderEndpoint.PendingAuthenticationRequest = null;
+ }
+ }
+} \ No newline at end of file
diff --git a/samples/OpenIdProviderWebForms/decide.aspx.designer.cs b/samples/OpenIdProviderWebForms/decide.aspx.designer.cs
new file mode 100644
index 0000000..795d1c7
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/decide.aspx.designer.cs
@@ -0,0 +1,70 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.3521
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OpenIdProviderWebForms {
+
+
+ public partial class decide {
+
+ /// <summary>
+ /// relyingPartyVerificationResultLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label relyingPartyVerificationResultLabel;
+
+ /// <summary>
+ /// identityUrlLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label identityUrlLabel;
+
+ /// <summary>
+ /// realmLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label realmLabel;
+
+ /// <summary>
+ /// profileFields control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::OpenIdProviderWebForms.ProfileFields profileFields;
+
+ /// <summary>
+ /// yes_button control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button yes_button;
+
+ /// <summary>
+ /// no_button control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button no_button;
+ }
+}
diff --git a/samples/OpenIdProviderWebForms/favicon.ico b/samples/OpenIdProviderWebForms/favicon.ico
new file mode 100644
index 0000000..beb3cb5
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/favicon.ico
Binary files differ
diff --git a/samples/OpenIdProviderWebForms/images/dotnetopenid_tiny.gif b/samples/OpenIdProviderWebForms/images/dotnetopenid_tiny.gif
new file mode 100644
index 0000000..c4ed4f5
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/images/dotnetopenid_tiny.gif
Binary files differ
diff --git a/samples/OpenIdProviderWebForms/login.aspx b/samples/OpenIdProviderWebForms/login.aspx
new file mode 100644
index 0000000..e8f42c5
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/login.aspx
@@ -0,0 +1,17 @@
+<%@ Page Language="C#" AutoEventWireup="true" Inherits="OpenIdProviderWebForms.login" CodeBehind="login.aspx.cs" MasterPageFile="~/Site.Master" %>
+<asp:Content ID="Content1" runat="server" ContentPlaceHolderID="Main">
+ <p>
+ Usernames are defined in the App_Data\Users.xml file.
+ </p>
+ <asp:Login runat="server" ID="login1" />
+
+ <p>Credentials to try (each with their own OpenID)</p>
+ <table>
+ <tr><td>Username</td><td>Password</td></tr>
+ <tr><td>bob</td><td>test</td></tr>
+ <tr><td>bob1</td><td>test</td></tr>
+ <tr><td>bob2</td><td>test</td></tr>
+ <tr><td>bob3</td><td>test</td></tr>
+ <tr><td>bob4</td><td>test</td></tr>
+ </table>
+</asp:Content> \ No newline at end of file
diff --git a/samples/OpenIdProviderWebForms/login.aspx.cs b/samples/OpenIdProviderWebForms/login.aspx.cs
new file mode 100644
index 0000000..4051877
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/login.aspx.cs
@@ -0,0 +1,22 @@
+namespace OpenIdProviderWebForms {
+ using System;
+ using System.Web.UI.WebControls;
+ using DotNetOpenAuth.OpenId.Provider;
+
+ /// <summary>
+ /// Page for handling logins to this server.
+ /// </summary>
+ public partial class login : System.Web.UI.Page {
+ protected void Page_Load(object src, EventArgs e) {
+ if (!IsPostBack) {
+ if (ProviderEndpoint.PendingAuthenticationRequest != null &&
+ !ProviderEndpoint.PendingAuthenticationRequest.IsDirectedIdentity) {
+ this.login1.UserName = Code.Util.ExtractUserName(
+ ProviderEndpoint.PendingAuthenticationRequest.LocalIdentifier);
+ ((TextBox)this.login1.FindControl("UserName")).ReadOnly = true;
+ this.login1.FindControl("Password").Focus();
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/samples/OpenIdProviderWebForms/login.aspx.designer.cs b/samples/OpenIdProviderWebForms/login.aspx.designer.cs
new file mode 100644
index 0000000..83826a1
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/login.aspx.designer.cs
@@ -0,0 +1,25 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.3521
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OpenIdProviderWebForms {
+
+
+ public partial class login {
+
+ /// <summary>
+ /// login1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Login login1;
+ }
+}
diff --git a/samples/OpenIdProviderWebForms/op_xrds.aspx b/samples/OpenIdProviderWebForms/op_xrds.aspx
new file mode 100644
index 0000000..afcfc75
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/op_xrds.aspx
@@ -0,0 +1,19 @@
+<%@ Page Language="C#" AutoEventWireup="true" ContentType="application/xrds+xml" %><?xml version="1.0" encoding="UTF-8"?>
+<%--
+This page is a required as part of the service discovery phase of the openid
+protocol (step 1). It simply renders the xml for doing service discovery of
+server.aspx using the xrds mechanism.
+This XRDS doc is discovered via the user.aspx page.
+--%>
+<xrds:XRDS
+ xmlns:xrds="xri://$xrds"
+ xmlns:openid="http://openid.net/xmlns/1.0"
+ xmlns="xri://$xrd*($v*2.0)">
+ <XRD>
+ <Service priority="10">
+ <Type>http://specs.openid.net/auth/2.0/server</Type>
+ <Type>http://openid.net/extensions/sreg/1.1</Type>
+ <URI><%=new Uri(Request.Url, Response.ApplyAppPathModifier("~/server.aspx"))%></URI>
+ </Service>
+ </XRD>
+</xrds:XRDS>
diff --git a/samples/OpenIdProviderWebForms/server.aspx b/samples/OpenIdProviderWebForms/server.aspx
new file mode 100644
index 0000000..10030a6
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/server.aspx
@@ -0,0 +1,53 @@
+<%@ Page Language="C#" AutoEventWireup="true" Inherits="OpenIdProviderWebForms.server" CodeBehind="server.aspx.cs" ValidateRequest="false" %>
+
+<%@ Register Assembly="DotNetOpenAuth" Namespace="DotNetOpenAuth.OpenId.Provider" TagPrefix="openid" %>
+<html>
+<head>
+ <title>This is an OpenID server</title>
+</head>
+<body>
+ <form runat='server'>
+ <%-- This page provides an example of how to use the ProviderEndpoint control on an ASPX page
+ to host an OpenID Provider. Alternatively for greater performance an .ashx file can be used.
+ See Provider.ashx for an example. A typical web site will NOT use both .ashx and .aspx
+ provider endpoints.
+ This server.aspx page is the default provider endpoint to use. To switch to the .ashx handler,
+ change the user_xrds.aspx and op_xrds.aspx files to point to provider.ashx instead of server.aspx.
+ --%>
+ <openid:ProviderEndpoint runat="server" OnAuthenticationChallenge="provider_AuthenticationChallenge" />
+ <p>
+ <asp:Label ID="serverEndpointUrl" runat="server" EnableViewState="false" />
+ is an OpenID server endpoint.
+ </p>
+ <p>
+ For more information about OpenID, see:
+ </p>
+ <table>
+ <tr>
+ <td>
+ <a href="http://dotnetopenid.googlecode.com/">http://dotnetopenid.googlecode.com/</a>
+ </td>
+ <td>
+ Home of this library
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <a href="http://www.openid.net/">http://www.openid.net/</a>
+ </td>
+ <td>
+ The official OpenID Web site
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <a href="http://www.openidenabled.com/">http://www.openidenabled.com/</a>
+ </td>
+ <td>
+ An OpenID community Web site
+ </td>
+ </tr>
+ </table>
+ </form>
+</body>
+</html>
diff --git a/samples/OpenIdProviderWebForms/server.aspx.cs b/samples/OpenIdProviderWebForms/server.aspx.cs
new file mode 100644
index 0000000..c0af0b4
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/server.aspx.cs
@@ -0,0 +1,18 @@
+namespace OpenIdProviderWebForms {
+ using System;
+ using DotNetOpenAuth.OpenId.Provider;
+
+ /// <summary>
+ /// This is the primary page for this open-id provider.
+ /// This page is responsible for handling all open-id compliant requests.
+ /// </summary>
+ public partial class server : System.Web.UI.Page {
+ protected void Page_Load(object src, System.EventArgs evt) {
+ this.serverEndpointUrl.Text = Request.Url.ToString();
+ }
+
+ protected void provider_AuthenticationChallenge(object sender, AuthenticationChallengeEventArgs e) {
+ Code.Util.ProcessAuthenticationChallenge(e.Request);
+ }
+ }
+} \ No newline at end of file
diff --git a/samples/OpenIdProviderWebForms/server.aspx.designer.cs b/samples/OpenIdProviderWebForms/server.aspx.designer.cs
new file mode 100644
index 0000000..89c8c8a
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/server.aspx.designer.cs
@@ -0,0 +1,25 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.3521
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OpenIdProviderWebForms {
+
+
+ public partial class server {
+
+ /// <summary>
+ /// serverEndpointUrl control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label serverEndpointUrl;
+ }
+}
diff --git a/samples/OpenIdProviderWebForms/styles.css b/samples/OpenIdProviderWebForms/styles.css
new file mode 100644
index 0000000..2e4d3db
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/styles.css
@@ -0,0 +1,10 @@
+h2
+{
+ font-style: italic;
+}
+
+body
+{
+ font-family: Cambria, Arial, Times New Roman;
+ font-size: 12pt;
+} \ No newline at end of file
diff --git a/samples/OpenIdProviderWebForms/user.aspx b/samples/OpenIdProviderWebForms/user.aspx
new file mode 100644
index 0000000..7306e79
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/user.aspx
@@ -0,0 +1,17 @@
+<%@ Page Language="C#" AutoEventWireup="true" Inherits="OpenIdProviderWebForms.user" CodeBehind="user.aspx.cs" MasterPageFile="~/Site.Master" %>
+
+<%@ Register Assembly="DotNetOpenAuth" Namespace="DotNetOpenAuth.OpenId.Provider" TagPrefix="openid" %>
+<asp:Content ID="Content2" runat="server" ContentPlaceHolderID="head">
+ <openid:IdentityEndpoint ID="IdentityEndpoint20" runat="server" ProviderEndpointUrl="~/Server.aspx"
+ XrdsUrl="~/user_xrds.aspx" ProviderVersion="V20"
+ AutoNormalizeRequest="true" OnNormalizeUri="IdentityEndpoint20_NormalizeUri" />
+ <!-- and for backward compatibility with OpenID 1.x RPs... -->
+ <openid:IdentityEndpoint ID="IdentityEndpoint11" runat="server" ProviderEndpointUrl="~/Server.aspx"
+ ProviderVersion="V11" />
+</asp:Content>
+<asp:Content ID="Content1" runat="server" ContentPlaceHolderID="Main">
+ <p>
+ OpenID identity page for
+ <asp:Label runat="server" ID="usernameLabel" EnableViewState="false" />
+ </p>
+</asp:Content> \ No newline at end of file
diff --git a/samples/OpenIdProviderWebForms/user.aspx.cs b/samples/OpenIdProviderWebForms/user.aspx.cs
new file mode 100644
index 0000000..f530f15
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/user.aspx.cs
@@ -0,0 +1,33 @@
+namespace OpenIdProviderWebForms {
+ using System;
+ using DotNetOpenAuth.OpenId.Provider;
+
+ /// <summary>
+ /// This page is a required as part of the service discovery phase of the openid protocol (step 1).
+ /// </summary>
+ /// <remarks>
+ /// <para>How does a url like http://www.myserver.com/user/bob map to http://www.myserver.com/user.aspx?username=bob ?
+ /// Check out gobal.asax and the URLRewriter class. Essentially there's a little framework that allows for URLRewrting using the HttpContext.Current.RewritePath method.</para>
+ /// <para>A url such as http://www.myserver.com/user/bob which is entered on the consumer side will cause this page to be invoked.
+ /// This page must be parsed by the openid compatible consumer and the url of the openid server is extracted from href in: rel="openid.server" href="?".
+ /// It is the responsibility of the consumer to redirect the user to this url.</para>
+ /// <para>The XRDS (or Yadis) content is also rendered to provide the consumer with an alternative discovery mechanism. The Yadis protocol allows the consumer
+ /// to provide the user with a more flexible range of authentication mechanisms (which ever has been defined in xrds.aspx). See http://en.wikipedia.org/wiki/Yadis.</para>
+ /// </remarks>
+ public partial class user : System.Web.UI.Page {
+ protected void Page_Load(object sender, EventArgs e) {
+ this.usernameLabel.Text = Request.QueryString["username"];
+ }
+
+ protected void IdentityEndpoint20_NormalizeUri(object sender, IdentityEndpointNormalizationEventArgs e) {
+ // This sample Provider has a custom policy for normalizing URIs, which is that the whole
+ // path of the URI be lowercase except for the first letter of the username.
+ UriBuilder normalized = new UriBuilder(e.UserSuppliedIdentifier);
+ string username = Request.QueryString["username"].TrimEnd('/').ToLowerInvariant();
+ username = username.Substring(0, 1).ToUpperInvariant() + username.Substring(1);
+ normalized.Path = "/user/" + username;
+ normalized.Scheme = "http"; // for a real Provider, this should be HTTPS if supported.
+ e.NormalizedIdentifier = normalized.Uri;
+ }
+ }
+} \ No newline at end of file
diff --git a/samples/OpenIdProviderWebForms/user.aspx.designer.cs b/samples/OpenIdProviderWebForms/user.aspx.designer.cs
new file mode 100644
index 0000000..ab7b4a1
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/user.aspx.designer.cs
@@ -0,0 +1,43 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.3521
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OpenIdProviderWebForms {
+
+
+ public partial class user {
+
+ /// <summary>
+ /// IdentityEndpoint20 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::DotNetOpenAuth.OpenId.Provider.IdentityEndpoint IdentityEndpoint20;
+
+ /// <summary>
+ /// IdentityEndpoint11 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::DotNetOpenAuth.OpenId.Provider.IdentityEndpoint IdentityEndpoint11;
+
+ /// <summary>
+ /// usernameLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label usernameLabel;
+ }
+}
diff --git a/samples/OpenIdProviderWebForms/user_xrds.aspx b/samples/OpenIdProviderWebForms/user_xrds.aspx
new file mode 100644
index 0000000..275e413
--- /dev/null
+++ b/samples/OpenIdProviderWebForms/user_xrds.aspx
@@ -0,0 +1,24 @@
+<%@ Page Language="C#" AutoEventWireup="true" ContentType="application/xrds+xml" %><?xml version="1.0" encoding="UTF-8"?>
+<%--
+This page is a required as part of the service discovery phase of the openid
+protocol (step 1). It simply renders the xml for doing service discovery of
+server.aspx using the xrds mechanism.
+This XRDS doc is discovered via the user.aspx page.
+--%>
+<xrds:XRDS
+ xmlns:xrds="xri://$xrds"
+ xmlns:openid="http://openid.net/xmlns/1.0"
+ xmlns="xri://$xrd*($v*2.0)">
+ <XRD>
+ <Service priority="10">
+ <Type>http://specs.openid.net/auth/2.0/signon</Type>
+ <Type>http://openid.net/extensions/sreg/1.1</Type>
+ <URI><%=new Uri(Request.Url, Response.ApplyAppPathModifier("~/server.aspx"))%></URI>
+ </Service>
+ <Service priority="20">
+ <Type>http://openid.net/signon/1.0</Type>
+ <Type>http://openid.net/extensions/sreg/1.1</Type>
+ <URI><%=new Uri(Request.Url, Response.ApplyAppPathModifier("~/server.aspx"))%></URI>
+ </Service>
+ </XRD>
+</xrds:XRDS>