I'm attempting to use the new ASP.NET Identity 2.0 authentication system(s) in a WebForms application, but I'm having trouble validating a user before allowing the data source for users to save.
The trouble stems from calling IIdentityValidator.ValidateAsync
from the data source's OnUpdating
event. The markup is functionally identical to the default Dynamic Data templates (except for the addition of Async="true"
), with a few customizations in the code behind. Basically, I manually set the MetaTable
for the request (since this page is a replacement for one of my dynamic data routes, but I'd like to keep the benefit of scaffolded properties) and I've added the DetailsDataSource_Updating
event. Though the code sample below successfully saves the user to our database, the following error is usually thrown before returning to the client:
"An asynchronous module or handler completed while an asynchronous operation was still pending."
I've spent a considerable amount of time attempting to get this to work, but have yet to find a solution that does not lock up the page or throw the above error. I fear that I am completely misunderstanding async/await in WebForms, or worse, that async/await is only really usable for database queries/binding outside of MVC.
public partial class Edit : System.Web.UI.Page
{
protected UserManager manager;
protected CustomMetaTable table;
protected void Page_Init(object sender, EventArgs e)
{
manager = UserManager.GetManager(Context.GetOwinContext());
table = Global.DefaultModel.GetTable(typeof(User)) as CustomMetaTable;
DynamicDataRouteHandler.SetRequestMetaTable(Context, table);
FormView1.SetMetaTable(table);
DetailsDataSource.EntityTypeFilter = table.EntityType.Name;
}
protected void Page_Load(object sender, EventArgs e)
{
Title = table.EntityName;
DetailsDataSource.Include = table.ForeignKeyColumnsNames;
}
protected void FormView1_ItemCommand(object sender, FormViewCommandEventArgs e)
{
if (e.CommandName == DataControlCommands.CancelCommandName)
{
Response.Redirect(table.ListActionPath);
}
}
protected void FormView1_ItemUpdated(object sender, FormViewUpdatedEventArgs e)
{
if (e.Exception == null || e.ExceptionHandled)
{
Response.Redirect(table.ListActionPath);
}
}
protected async void DetailsDataSource_Updating(object sender, Microsoft.AspNet.EntityDataSource.EntityDataSourceChangingEventArgs e)
{
IdentityResult result = await manager.UserValidator.ValidateAsync(e.Entity as User);
if (!result.Succeeded)
{
e.Cancel = true;
}
}