how to add custom parameters to membership create user wizard? - c#

I am really confused right now. Ive read some solutions to this problem, but every single one is different.... some people say that web applications projects and web site projects need different solutions.
What I have in thoughts:
I have a web application project
I created a table UserProfile in that table where I store additional columns like a link to an image.
My problem right now is that when I call RegisterUser_CreatedUser on submit, I can't find any way to get Guid of the newly created user :
protected void RegisterUser_CreatedUser(object sender, EventArgs e)
{
FormsAuthentication.SetAuthCookie(RegisterUser.UserName, createPersistentCookie: false);
TextBox ImageUrl = RegisterUserWizardStep.ContentTemplateContainer.FindControl("ImageUrl") as TextBox;
UserProfile.SaveNewProfileInformation("place for new created user guid", ImageUrl.Text);
string continueUrl = RegisterUser.ContinueDestinationPageUrl;
if (!OpenAuth.IsLocalUrl(continueUrl))
{
continueUrl = "~/";
}
Response.Redirect(continueUrl);
}
How do I get the guid of new created user? and am i on the right track at all to solve this problem?

You need to get the created user with the UserName
{
FormsAuthentication.SetAuthCookie(RegisterUser.UserName, createPersistentCookie: false);
//If user is created, get it by UserName
MembershipUser createdUser = Membership.GetUser(RegisterUser.UserName);
Guid userID = new Guid(createdUser.ProviderUserKey.ToString());
TextBox ImageUrl = RegisterUserWizardStep.ContentTemplateContainer.FindControl("ImageUrl") as TextBox;
//Use the userID from the above code
UserProfile.SaveNewProfileInformation(userID, ImageUrl.Text);
}

Related

Remove Output Cache for User Controls in ASP.NET Webforms

I have an asp.net webforms SaaS application where multiple ecommerce websites are running. Each website has its own domain (abc.com, xyz.com etc.) and each website's content is fetched from the database based on the domain.
Now, in order to improve home page performance I am implementing Output Cache. Please note that the home page already contains multiple user controls (header, footer, top menu, user menu, mini cart, banners, home products etc.). All the user controls are eligible for Output Cache accept user menu (where logged in usernames are displayed, otherwise signup/login links) and mini cart (where no. of cart items are displayed and on click it shows the list of items in cart).
I added Output cache directive on each user control (that I want to be cached) with VaryByCustom to create separate cache for each domain.
<%# OutputCache Duration="300" VaryByParam="*" VaryByCustom="Host" %>
As VaryByHeader is not an available option for UserControls, I added an override function in Global.asax to return current host.
public override string GetVaryByCustomString(HttpContext context, string arg)
{
if (arg == "Host")
{
return context.Request.Url.Host;
}
return String.Empty;
}
Till now, everything is working perfect. User controls are being cached for different domains (hosts) and are being expired on the specified time.
THE PROBLEM: I want to give an option in the admin panel to the website admin users to manually refresh cache of their websites. For that I created a page (refreshcache.aspx) in the frontend application, and simply open that url (for example: abc.com/refreshcache.aspx) when the admin users click the refresh cache button from the admin panel.
I researched a lot and tried multiple approaches to clear user controls cache but failed. The last thing that I implemented is the following code which I added in the home page aspx which creates an object of StaticPartialCachingControl and adds key dependency on user controls cache.
In Home.aspx, I added the following code which is called in Page_Load
protected void LoadControlsCache()
{
CacheKey = "Host-" + Request.Url.Host;
CacheKeyArray[0] = CacheKey;
if (Cache[CacheKey] == null)
{
AddControlCache(header1);
AddControlCache(footer1);
AddControlCache(banner1);
AddControlCache(products1);
}
}
protected void AddControlCache(UserControl uc)
{
StaticPartialCachingControl pcc = (StaticPartialCachingControl)uc.Parent;
pcc.Dependency = new CacheDependency(null, CacheKeyArray);
Cache.Insert(CacheKey, "value", null, DateTime.Now.AddSeconds(300), Cache.NoSlidingExpiration);
}
And to remove the cache for a particular host, I used Cache.Remove method with the host specific key.
In refreshcache.aspx I added the following code
protected void Page_Load(object sender, EventArgs e)
{
Cache.Remove("Host-" + Request.Url.Host);
Response.Redirect("/");
}
I am not sure what I am missing or doing wrong. Just want a way to clear usercontrols cache for a particular host (domain).
Finally got the issue resolved by creating separate keys for all user controls, and adding dependency on user control object.
protected void LoadControlsCache()
{
string CacheKey = Request.Url.Host;
AddControlCache(header1, "header-" + CacheKey);
AddControlCache(footer1, "footer-" + CacheKey);
AddControlCache(banner1, "banner-" + CacheKey);
AddControlCache(products1, "products-" + CacheKey);
}
protected void AddControlCache(UserControl uc, string CacheKey)
{
if (Cache[CacheKey] == null && uc != null)
{
uc.Cache.Insert(CacheKey, 1);
uc.CachePolicy.Dependency = new System.Web.Caching.CacheDependency(null, new string[] { CacheKey });
}
}
Then to clear the cache, used Cache.Remove() with all the usercontrol keys.
protected void Page_Load(object sender, EventArgs e)
{
string CacheKey = Request.Url.Host;
Cache.Remove("header-" + CacheKey);
Cache.Remove("footer-" + CacheKey);
Cache.Remove("banner-" + CacheKey);
Cache.Remove("products-" + CacheKey);
Response.Redirect("/");
}
Hope it might help someone with a similar question!

C# GUI save input text (TextBox) [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I'm pretty new to the C# and while making my first program i'm facing a problem.
So I got 3 windows form (MyForm1; MyForm2 and MyForm3)
MyForm1 has 2 buttons (Available Account & Add a new account)
When i click one of these buttons it opens a new windows form.
In the Add a new Account form I have 2 TextBox (1 for the ID and 1 for the PWD + Button (Save) and i'd like the user to input his ID and PWD and save it so i can re-use it in the Available Account form but i have no clue how to that. I tried different things i saw on YT but nothing seems to works like i would
Thanks for your help <3 (Tell me if you want me to copy/paste some part of the code).
Edit:
Here are the sourcecodes of the mentioned forms.
Form1
Form2
Form3
I deleted all my failed attemps, so they are basics.
From your post it's hard to determine what you're trying to do. So. If you only want to pass values between forms, you could do something like this:
Add new account form:
public static bool AddNewAccount(out int id, out string password)
{
id = 0;
password = "";
AddNewAccountForm f = new AddNewAccountForm();
bool result = (f.ShowModal() == ModalResult.OK);
if(result)
{
id = f.GetId();
password = f.GetPassword();
}
f.Dispose();
return result;
}
and in main form:
int id;
string pass;
if(AddNewAccountForm.AddNewAccount(out id, out pass))
{
//here user clicked OK, so you can save to the database your id and password
}
else
{
//here user clicked Cancel
}
I assumed that there are two buttons on your AddNewAccountForm. One - OK and the other - Cancel. You have to set the modal result for these buttons.
So, how it works?
AddNewAccount method is static method, so you can call it from your main like:
AddNewAccountForm.AddNewAccount()
AddNewAccount method is going to create your form, show it modally and then assign values enetred by user to out parameters.
My code assumes also that your AddAccountForm has methods like:
int GetId()
{
return Convert.ToInt32(idTextBox.Text);
}
string GetPassword()
{
return passwordTextBox.Text;
}
Note that GetId is badly written, I wanted it to be clear. Now that you understand this method, conversion to int should look like that (TryParse is better way to convert string to int):
int GetId()
{
int id;
if(!int.TryParse(idTextBox.Text, out id))
return -1;
else
return id;
}
You can also "group" id and password in some structure. Code would be cleaner. But I don't think you need it now. However, if you are curious you can read about structures here: https://msdn.microsoft.com/en-us/library/aa288471%28v=vs.71%29.aspx?f=255&MSPPError=-2147217396
If you want to store values in database or files:
** Part about good practices and system engeneering **
You should really not save them using AddAccountForm. This class is to create account in your application (just the model) - not to save it. If you want to store these values(id and password) you should pass them to your main form - as I already showed you and then main form should save them - using another class which is responsible for data management. I am not giving any example, because I don't know if you really need it now.
To make your code really reusable, you should keep a strict separation between display (view) and the data.
You didn't mention that you had a database. This lack of mention is a start of this separation. Your problem would be similar if you just have a List of account, or a Dictionary, or maybe a text file containing the items you want to edit in your application.
So let's assume you want to edit a collection of Accounts. You want to be able to add an Account to this collection, or change the data of an existing account in this collection.
This functionality is similar to the functionality of an ICollection<Account>.
So all that Form1 needs to know, is that it holds an ICollection<Account>. Somehow during initialization Form1 loads the Accounts collection. If the operator presses Add, a Form2 opens where he can fill in the required values for a new Account. The operator chooses either OK or Cancel to indicate he want this Account to be added to the collection or not (Using a Save button in the form is not windows standard and a bit unclear, so don't use it).
Add an Account
Code in Form1
private ICollection<Account> existingAccounts;
void OnButtonAdd(object sender, ...)
{
using (var form = new Form2())
{
form. ...// fill any needed values
// show form2 and check if OK or Cancel:
var dlgResult = form.ShowDialog(this);
// only add if OK pressed, otherwise ignore
if (dlgResult == DialogResult.OK)
{
this.existingAccounts.Add(form.Account);
}
}
}
Cond in Form2
In visual studio designer create a Form with a TextBox for the ID and a textbox for the password (give it password properties, so it displays *****)
Add an OK and a Cancel button. Give the DialogResult property of these buttons the proper OK and Cancel value.
Finally add one property to get the typed values:
public Account Account
{
get
{ // extract the values from the display
return new Account()
{
Id = this.TextBoxId.Text,
Pwd = this.TextBoxPwd.Text,
};
}
}
Edit existing Account
You also have a button to edit an existing account. Do you only want to edit the last Added account, or do you want to be able to edit any existing account?
In the latter case you'll have to make something that displays all existing account where operators can select one of them. Probably using a DataGridView, or a BindingSource. You'll probably end up with a function like:
Account GetSelectedAccount() {...}
The Form to edit an existing Account is similar to the form to create a new account. You should really consider using the same form for it.
public Account Account
{
get
{ // extract the values from the display
return new Account()
{
Id = this.TextBoxId.Text,
Pwd = this.TextBoxPwd.Text,
};
}
set
{
this.TextBoxId.Text = value.Id;
this.TextBoxPwd.Text = value.Pwd;
}
}
In form1, upon pressing Edit:
void OnButtonEdit_Click(object sender, ...)
{
using (var form = new FormEdit())
{
Account accountToEdit = this.GetSelectedAccount();
form.Account = accountToEdit;
// or: GetLastAddedAccount if you only want to edit the last added one
var dlgResult = form.ShowDialog(this);
if (dlgResult == DialogResult.OK)
{ // extract the edited Account from the form:
Account editedData = form.Account;
this.UpdateSelectedAccount(editedData);
}
}
}
Like in the examples above I usually decide to have an interface with a property that inserts and extracts Accounts instead of accessing every Account property separately. This allows you to change internals of an Account without having to change all (software) users of this Account
It's all about passing data between forms, So you can use one of following :
set the user input in public string so you can access the strings from other forms by the input form object.
you can pass the user input as constructor parameters and then use the data in your form.
there are also other multiple ways like delegate but i think the 2 previous ways are simple.

Data Validation not working in Edit Mode

I want to implement validation on text box for whether the name exists in the database. I am using wpf with c#. I have implemented a validation on the text box while saving new data. My problem is in Edit Mode: when I go to edit mode and try to save, an error appears that the name already exist.
The Below Code works fine on save mode But when it comes to Edit mode when datas get binding the error message shows.
pls suggest me a good way to implement the validation that work on edit mode too.
class MyParent
{
public MyCarClass CurrentCarEntity {get; set;}
private void txtName_TextChanged(object sender, RoutedEventArgs e)
{
CurrentCarEntity.Name = txtName.Text.Trim();
var getName = //Code for getting name from local db
if(CurrentCarEntity.Name != Null)
{
if(getName.Equals(CurrentCarEntity.Name))
{
MessageBox.Show("Name Already Exists");
}
}
}
}
Looks like you're making validation fail for the entire form if the name already exists - validation will trigger every time you try to submit (edit, insert, etc) so edits will always fail.
I would make two textboxes, one for inserts and one for edits. Hide the insert box while in edit mode, or if you want to stick with one, at least disable the validator when editing.
It seems that you are following the wrong approach
let us assume we have a class called users like following
public class User: IValidatableObject
{
public int Id{get; set;}
public string UserName{get; set;}
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if(string.IsNullOrEmpty(UserName))
yield return new ValidationResult("Username field is required!", new string[]{"UserName"});
else
{
// check if another User has the same username already
var db= new YourDbContext();
var exists=db.Users.FirstOrDefault(t=>t.Id!=Id && t.UserName.ToLower()=UserName.ToLower());
if(exists!=null)
yield return new ValidationResult("Username is already used by another user!", new string[]{"UserName"});
}
}
}
you don't need to worry about the edit or create, since in both cases you are checking the database if the Users table contains another user,and not same user you are creating or editing, has the same username.
hope this will help you

Membership not recognized

I am using the createUserWizard control to register the users for my website, but I also use my own table to store information (address, image, description, ...) about these users.
When creating a user, I also want to create a new instance in my own table. I want to link my own table to ASP.NET's user table via the userID. I tried grabbing this from the createUserWizard with Membership, but ASP doesn't recognize membership. Am I forgetting to add something?
Here's my code (code behind)
protected void CreateUserWizard1_CreatedUser(object sender, EventArgs e)
{
try
{
BLLorganisation BLLo = new BLLorganisation();
Organisation o = new Organisation();
TextBox t = new TextBox();
t = (TextBox)(this.CreateUserWizard1.FindControl("UserName"));
o.organisation_name = t.Text;
o.fk_user_id = Membership.GetUser(CreateUserWizard1.UserName).ProviderUserKey.ToString();
BLLo.insertOneOrganisation(o);
}
catch (Exception ex)
{
feedback.InnerHtml = ex.Message;
feedback.Style.Add("display", "block");
}
}
Include using System.Web.Security;

Help creating a Windows Form for an Entity who has a reference to a different Entity

Here is the scenario (ADO.NET Entity Framework and C#).
Contact*:
String name;
Address addr;
Address*:
String street;
String city;
**this is not the real code, but you get the picture*
I am trying to create a Windows Form that appears flat to the user. In other words, the Form will have four fields (name,addr,street,city), and when the users clicks on the Add button in a bindingSourceNavigator, I want to create a new instance of Contact such that Contact.addr is a reference to a newly created Address.
If I were only working with objects this would be simple, but I'm trying to create a new row in the table that backs Address.
Here is what I've tried so far:
private void contactBindingSource_AddingNew(object sender, AddingNewEventArgs e)
{
Contact newContact = new Contact();
Address newContactAddr = new Address();
newContact.Address = newContactAddr;
newContactAddr.Contacts.Add(newContact);
//I realize I don't need the Contact list reference in Address,
//but VS2010 created it, so I'm just adding the new Contact to
//the list for now.
e.NewObject = newContact;
}
private void contactBindingNavigatorSaveItem_Click(object sender, EventArgs e)
{
contactBindingSource.EndEdit();
context.SaveChanges(); //throws UpdateException
}
Some background: The Form has a binding source for Contact, and this method is the event handler for when new Contacts are created. I read on MSDN that this is how one modifies the object before it is actually added to the BindingSource. context refers to my entity model.
What happens: When I click the add button, I am able to enter in the contact information. But when I click the save button, I get an UpdateException. I suspect this is because I did not create the Address properly, but being new to the ADO.NET framework (and .NET programming in general), I don't really know the correct way to do this.
An example:
I have 3 tables, Users, UserRoles and Roles.
when i create a user i want this user to receive a role and i would then do
using(DatabaseEntities db = new DatabaseEntities())
{
//creates the user and add the properties except roles
Users user = new Users();
user.username = "Test";
//get an existing role
var role = db.Roles.SingleOrDefault(r => r.roleName == "User");
//adds the userid and roleid in to userRoles
user.Roles.Add(role);
db.Users.AddObject(user);
//saves it to the db
db.SaveChanges();
}
so, in order for it to work in your example, you would first need to insert One of them to the db before using it in order to save the other object along with the row to the table that links them together.
I hope this simple example helps you.

Categories