I have created a standard ASP.NET MVC project in VS12 using the "Internet Application" Template for Web Applications.
VS has automatically created a database called aspnet-Authentification-20130123105949.mdf. When I open the database table webpages_Roles just one of my created Roles is shown there. But this role doesn't exist anymore, it seems as if the data shown here is old.
I add roles by using:
public String AddRole(String name)
{
Roles.CreateRole(name);
return name + " was added.";
}
My method to list the roles shows different roles than in the DB view:
public String ListRoles()
{
String[] roles = Roles.GetAllRoles();
String res = "";
foreach(String role in roles) {
res += "\n" + role;
}
return res;
}
I've already tried to refresh the DB View, but this does not help.
I have no problems with other databases created by myself.
Related
Is there any method for storing global variables without using cookies or session[""] in asp.net mvc ?
I know that cookies and session[""] have some disadvantages and I want to use the best method if exit.
If they are indeed global variables, you should implement the singleton pattern and have an Instance globally accessible that holds your variables.
Here is a simple example:
public sealed class Settings
{
private static Settings instance = null;
static readonly object padlock = new object();
// initialize your variables here. You can read from database for example
Settings()
{
this.prop1 = "prop1";
this.prop2 = "prop2";
}
public static Settings Instance
{
get
{
lock (padlock)
{
if (instance == null)
{
instance = new Settings();
}
return instance;
}
}
}
// declare your global variables here
public string prop1 { get; set; }
public string prop2 { get; set; }
}
The you can use them in your code like this:
var globalvar1 = Settings.Instance.prop1;
This class with its variables will be initialized only once (when the application starts) and it will be available in your application globally.
Basically you have following options:
Cookies - valid as long as you set, must be allowed by client's browser, can be deleted by user, stored on user's PC.
Session - valid for all requests, not for a single redirect, stored on server.
ViewData - after redirect it's cleared (lives only during single request).
TempData - it's useful for passing short messages to view, after reading a value it's deleted.
ViewBag - is available only during the current request, if redirection occurs then it’s value becomes null, is dynamic so you don't have intellisense and errors may occur only in runtime.
Here - http://www.dotnet-tricks.com/Tutorial/mvc/9KHW190712-ViewData-vs-ViewBag-vs-TempData-vs-Session.html - you can find fantastic article which describes them.
Sure: HttpContextBase.Application (no expiration) or HttpContextBase.Cache (with expiration). You can access the HttpContextBase instance through the HttpContext property of the Controller class.
So... HACK ALERT... There is no good way to do an MVC 5 or 6 web app using session variables that I have found (yet). MVC doesn't support Session variables or Cookies, which are implemented via session variables. Global variables will be set for ALL users, which is not how Session variables work.
However, you can store "session variables" based on the User.Identity.Name or the underlying User.Identity.Claims.AspNet.Identity.SecurityStamp into a database along with a timestamp and viola! You have implemented primitive session variables. I had a very specific need to save two weeks of programming by not interfering with the GUI that our user interface specialist had written. So I returned NoContent() instead of the normal View() and I saved my hacky session variable based on the user's login name.
Am I recommending this for most situations? No. You can use ViewBag or return View(model) and it will work just fine. But if you need to save session variables in MVC for whatever reason, this code works. The code below is in production and works.
To retrieve the data...
string GUID = merchdata.GetGUIDbyIdentityName(User.Identity.Name);
internal string GetGUIDbyIdentityName(string name)
{
string retval = string.Empty;
try
{
using (var con = new SqlConnection(Common.DB_CONNECTION_STRING_BOARDING))
{
con.Open();
using (var command = new SqlCommand("select GUID from SessionVariablesByIdentityName md where md.IdentityName = '" + name + "' and LastSaved > getdate() - 1", con))
{
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
retval = reader["GUID"].ToString();
}
}
}
}
}
catch (Exception ex)
{
}
return retval;
}
To save the data...
merchdata.SetGUIDbyIdentityName(User.Identity.Name, returnedGUID);
internal void SetGUIDbyIdentityName(string name, string returnedGUID)
{
RunSQL("exec CRUDSessionVariablesByIdentityName #GUID='" + returnedGUID + "', #IdentityName = '" + name + "'");
}
internal void RunParameterizedSQL(SqlConnection cn, SqlCommand cmd, object sqlStr)
{
string retval = string.Empty;
try
{
cn.Open();
cmd.ExecuteNonQuery();
cn.Close();
}
BTW: The SQL table (named SessionVariablesByIdentityName here) is fairly straightforward and can store lots of other things too. I have a LastSaved datetime field in there so I don't bother retrieving old data from yesterday. For example.
I've created an ASP.Net MVC4 web application and it includes the templated functionality that allows users to register with external providers such as Facebook and Twitter. This uses OAuth and SimpleMembership. I'm using Entity Framework code-first, which I'm new to, so I'm finding it difficult to do something really simple.
Once the user has registered with the external provider, a record is created in webpages_OAuthMembership with fields Provider, ProviderUserId and UserId. UserId maps to UserId in the UserProfile table. How do I read the ProviderUserId for the authenticated user? I need it to for use with the FB.api and for other things like retrieving the user photo using https://graph.facebook.com/[ProviderUserId]/picture?type=small.
I have tried this:
SimpleMembershipProvider provider = (SimpleMembershipProvider)Membership.Provider;
string providerUserId = provider.GetUser("[username]", true).ProviderUserKey.ToString();
but ProviderUserKey just returns the UserId rather than ProviderUserId.
There must be a simple way to do this that I'm missing?
This answer assumes using Entity Framework 6 Code First approach (although all the code should work with earlier versions of EF).
I was having issues with accessing Provider and ProviderUserId too. I was attempting to delete a user accounts that authenticated with OAuth. I was able to delete the actual user account from the database with the code:
((SimpleMembershipProvider)Membership.Provider).DeleteAccount(selectedUser); // deletes record from webpages_Membership table
((SimpleMembershipProvider)Membership.Provider).DeleteUser(selectedUser, true); // deletes record from UserProfile table
However, this left the entry in the webpages_OAuthMembership table (which I wanted to delete!).
To solve this, I made a class with the same name as the db table:
public class webpages_OAuthMembership
{
[Key, Column(Order=0)]
public string Provider { get; set; }
[Key, Column(Order = 1)]
public string ProviderUserId { get; set; }
public int UserId { get; set; }
}
The Key and Column data annotations let EF know that Provider and ProviderUserId form a composite key (I think SQL Server calls it a clustered PK). Anyways, in the DbContext class that initializes the database, I did a DbSet on that class:
public DbSet<webpages_OAuthMembership> webpages_OAuthMembership { get; set; }
This now allows you to access the OAuth table in the database in your code
var db = new DbContext(); db.webpages_OAuthMembership.ToList();
// this would give you all entries in the OAuth table
For your case, to get the ProviderUserId, you could use the following code
var OAuthAccount = db.webpages_OAuthMembership.Where(u => u.UserId == userIdOfUserYouAreSearchingFor).FirstOrDefault;
// ProviderUserId would be OAuthAccount.ProviderUserId
where 'userIdOfUserYouAreSearchingFor' is the UserId (from UserProfile table). Make sure to have the FirstOrDefault on the end. That way, if there is no entry in the database for that particular UserId, it will receive null and you can check again that.
Now in my case, I wanted to delete entries from said table. Just in case anyone else comes across this, I will include that info too.
I used this code
var OAuthAcct = ((SimpleMembershipProvider)Membership.Provider).GetAccountsForUser(selectedUser).ToList();
var provider = OAuthAcct[0].Provider;
var providerUserId = OAuthAcct[0].ProviderUserId;
((SimpleMembershipProvider)Membership.Provider).DeleteOAuthAccount(provider, providerUserId);
to delete entries from the webpages_OAuthMembership table.
Hope that helps!
I am an asp.net mvc newbie. I haven't really done anything since classic asp. I want to display a list of files from a Mysql database based on the users role. So far I have created two tables some files will be viewable by more than one role. I am also using the MySql Membership Provider
Table Files
FileID, FileName, FilePath
Table FilesRole
FileID, RoleID
I am thinking I can add a file to the files table and then for each role that has access to that file I will need to add the fileID to the FilesRole table and also get the RoleID from the my_aspnet_roles table and add that to.
and then somehow when someone goes to view the files it will grab the ID of every role they are in and then get a list of files from the db
I have no idea where to start on this so any help would be greatly appreciated.
Let me get you up to speed:
1. Create users and add them to roles
Webdeveloper Express and Visual Studio have a Web administration tool for your website:
To access the Web Site Administration Tool, on the Website menu, click ASP.Net Configuration.
Ref: http://msdn.microsoft.com/en-us/library/yy40ytx0.aspx
You can add users and roles and add-users-to-roles from there.
2. Create database records (assuming you have a mysql administration panel of some sort)
Now create some file records in your database and create create some association records between files and roles. I would use RoleName instead of RoleID because the default RoleProvider interface works with string names.
3. Learn how to query the mysql database from ASP.NET
Read this for instance: http://support.discountasp.net/KB/a358/how-to-query-a-mysql-database-in-aspnet.aspx
4. Create the correct query based on the Users roles
string[] userRoles = Roles.GetRolesForUser(HttpContext.Current.User.Identity.Name);
// creates "'role1','role2' from array.
string userRolesForSqlQuery = userRoles.Select(x => "'" + x + "'").Aggregate((a,b) => a + "," + b);
//Psuedo code for querying the database...
var fileForUserQuery = String.Format("SELECT FileID, FileName, FilePath FROM Files
INNER JOIN FilesRole ON Files.FileID = FilesRole.FileID
WHERE FilesRole.RoleName IN ({0});", userRolesForSqlQuery);
Hopefully this gets you there...
This is what I have so far. It works but I know it is not correct because I am doing database stuff in the Controller and that should be done in the model but I can't figure out how to get it done that way.
Model
public class files
{
public int fileid { get; set; }
public string fileName { get; set; }
public string filePath { get; set; }
}
Controller
public ActionResult Index()
{
IList<files> downloads = new List<files>();
// Get Users Role(s) thanks Ropstah
string[] userRoles = Roles.GetRolesForUser(User.Identity.Name);
string userRolesForSqlQuery = userRoles.Select(x => "'" + x + "'").Aggregate((a, b) => a + "," + b);
// MySql Connection thanks again Ropstah
string connectionString = "my data source";
var MySqlConnectionString = String.Format(#"SELECT fileid, fileName, filePath, FROM downloads
INNER JOIN downloadsroles on downloads.fileid = downloadsroles.downloadsid
WHERE downloadsroles.roleName IN ({0});", userRolesForSqlQuery);
MySqlConnection conn = new MySqlConnection(connectionString);
MySqlCommand comm = conn.CreateCommand();
MySqlDataReader Reader;
comm.CommandText = MySqlConnectionString;
conn.Open();
Reader = comm.ExecuteReader();
while (Reader.Read())
{
downloads.Add(new files() { fileName = Reader["fileName"].ToString(),
filePath = Reader["filePath"].ToString()});
}
conn.Close();
return View(downloads);
}
View
#foreach (var downloads in ViewData.Model)
{
<tr>
<td>
#downloads.fileName
</td>
<td>
#downloads.filePath
</td>
</tr>
}
I have added the SqlRoleProvider tables aspnet_Users, aspnet_Roles, and aspnet_UsersInRoles to my Entity Framework 1.0 model in VS 2008.
I've tried the following which intellisense won't even help me with.
private void BindFormView(string userName)
{
using (var context = new MyEntities())
{
var users = from u in context.aspnet_Users
where u.UserName = userName
select u;
}
//...
}
My eventual goal is to get all of the roles a given user has. It's all looks right in my model, but I cannot seem to access it effectively.
Dude, do not map the membership tables.
Access them via the Membership Provider API:
Membership.GetUser("blah");
Why shouldn't you map it?
Because it's presuming SQL (defeats the point of a "model" abstraction in EF)
Kidding yourself if you can figure out the complex relationships/associations in the database
The Membership API has all the information you require.
To get the roles for a user, use RoleProvider.GetRolesForUser
It looks like the roles are setup as a navigation property from the users. So, building on your code you should be able to do something like this:
private void BindFormView(string userName)
{
using (var context = new MyEntities())
{
//Get the first user matching your query
var user = (from u in context.aspnet_Users
where u.UserName == userName
select u).FirstOrDefault();
//Using the navigation properties, get the roles associated with this user
var roles = user.aspnet_Roles().ToList();
}
//...
}
I have a ASP.NET Website project and I need to list all the users and their groups on my Windows system. I have set the identity impersonation to true and provided the username and password of the admin in the web.config. Where do I start?
Thanks in advance.
Update:
I have the following code at the moment -
var machine = new DirectoryEntry("WinNT://<IP ADDRESS>");
foreach (DirectoryEntry child in machine.Children)
{
// get the child's group(s).
}
When I debug, I can see the list of users in machine.Children. How do I find the group(s) that this user belongs to?
This article covers how to talk to Active Directory and should get you where you want to go:
http://www.codeproject.com/KB/system/everythingInAD.aspx
To get users, you would do something like this:
public List<string> GetUserList()
{
string DomainName="";
string ADUsername="";
string ADPassword="";
List<string> list=new List<string>();
DirectoryEntry entry=new DirectoryEntry(LDAPConnectionString, ADUsername, ADPassword);
DirectorySearcher dSearch=new DirectorySearcher(entry);
dSearch.Filter="(&(objectClass=user))";
foreach(SearchResult sResultSet in dSearch.FindAll())
{
string str=GetProperty(sResultSet, "userPrincipalName");
if(str!="")
list.Add(str);
}
return list;
}
You probably want to start with the DirectoryEntry and Active Directory support in .net.
Here's a good resource: http://www.codeproject.com/KB/system/everythingInAD.aspx
Local access is similar, even if you're not in a domain:
DirectoryEntry localMachine = new DirectoryEntry("WinNT://" +
Environment.MachineName);
DirectoryEntry admGroup = localMachine.Children.Find("administrators",
"group");
object members = admGroup.Invoke("members", null);
foreach (object groupMember in (IEnumerable)members) {
DirectoryEntry member = new DirectoryEntry(groupMember);
//...
}