User groups management - asp.net-mvc

I am trying to implement user management functionality for a web site.
I am using ASP.NET MVC 3, Entity Framework 4.1, MvcScaffolding.
Let's consider the entities:
The user entity:
public class User
{
public int Id
{
get;
set;
}
public string FirstName
{
get;
set;
}
public string LastName
{
get;
set;
}
public virtual ICollection<UserGroup> Groups
{
get;
set;
}
}
The user group entity:
public class UserGroup
{
public int Id
{
get;
set;
}
public string Name
{
get;
set;
}
public virtual ICollection<User> Users
{
get;
set;
}
}
As you see, there is the many-to-many relationship between the user and the user group entities.
So, I would like to have the following UI for editing an user group:
There are two grids:
1. Users grid contains current state of the user group which is being edited.
2. Browse users grid contains all users (except the users which already belong to the user group). When the user row of this grid is clicked, the user will be moved to the users grid. Also, this grid should support paging, filtering and sorting to provide nice user browsing.
So, the user picks users for the user group and then clicks the "Save" button. User group controller class should save the changes.
Now the question: how can the functionality be implemented? Is there any good example for the such many-to-many relationship problem?
If there is no simple solution, what UI for the user group management could you advise me to use?
P.S. I am quite novice with ASP.NET, so I don't realize how to implement such dynamic grids.
Update 1:
I have looked through the jqGrid examples. link
See Advanced -> Multi Select
There is the problem, the checkboxes' selection is reset when you change the filter. How to store all selected IDs despite the filter change?

Telerik has great grid: http://demos.telerik.com/aspnet-mvc/grid/detailsajax.
I could not understand your whole scenario, especially this: "Browse users grid contains all users (except the users which already belong to the user group). When the user row of this grid is clicked, the user will be moved to the users grid".
I think scenario could be this:
If user is at concrete group, two grids are shown:
a) users existing in group, where each row contains user info and button remove
b) users not existing in group, where each row contains user info and button add
In such case, all logic is quite straightforward, you don't need any fancy logic, as everything is on same page.
In user page, there could be a grid with groups, and if user is in that group, in that row is button remove, and if user is not, there is button add. With well chosen user dto for edit view, that will be also quite straigtforward to implement.

Related

Information about form sender - ASP.NET MVC

I would like to create a group in my app. In model that group has a field Admin_ID to specify who is the owner. How to include that information in a form? With hidden field? I don't think this would be safe enough solution... Any other ideas?
In model that group has a field Admin_ID to specify who is the owner.
Then apply authentication (see the tutorial for your MVC version) so you know which user is logged in, use authorization to restrict access to admins only and in the controller assign the creating user's ID to the model when it is created:
[Authorize(Roles="Admin")]
public ActionResult Create(SomeModel modelToCreate)
{
// get user, depends on how your project is set up...
var user = GetLoggedOnUser();
modelToCreate.Admin_ID = user.ID;
}
If hidden field is not enough for security - don't include it there, but have a separate action that only does operation on your Admin group.
Sorry, can't give more details, as your question does not contain enough information.
You can always save the Admin_ID in the Session.
To better understand:
public class Group
{
public int A { get; set; }
public string B { get; set; }
public string C { get; set; }
public string ID_Admin { get; set; }
}
where ID_Admin should be automatically generated when someone who is logged in want to submit that form (he need to fill only A, B and C fields). So let's say currently logged user has ID 42, and he want to submit that form (without any knowledge of that additional field of course) - and I want to include that information about his ID in final model submission.

How to save claims used in a MVC site using Thinktecture IdentityModel

I am working on a MVC web site with Claims Authentication and also using Thinktecture IdentityModel.
Each user has a set of CLAIMS: City, Username, Email, Roles, Birthdate.
I have 3 tables in the database: USERS, USERS_PROFILES and USERS_CLAIMS.
USERS contains the columns Username and Email;
USERS_PROFILES contains the columns City and Birthdate.
I am saving these values in these tables ... And I save the Roles in the USERS_CLAIMS table.
When I load a user I fill the ClaimsIdentity with the data from these tables.
THE QUESTION IS:
When I create a user should I, for example, save the email both in USERS table and in USERS_CLAIMS table?
It seems data replication but I am not sure ... Or should I save in only one of them?
What is your approach to this? And what kind of claims, beside roles, do you have that don't fit in a USERS or USERS_PROFILE table?
Thank You,
Miguel
As you're using MVC (Model View Controller), why don't you use Models ?
Your ClaimsIdentity is a model, just create a ClaimsIdentityModel.cs in your Model folder, and use it like this :
public class ClaimsIdentityModel
{
public string Username { get; set; }
public string Email { get; set; }
public string City { get; set; }
public Datetime Birthdate{ get; set; }
}
Then, when you load your user, just fill a ClaimsIdentityModel. And you're done.
As name of each table suggest, the values shall represent those only.
Users are identified as by usernames. Email is one of the claim done by the User.
Roles are also claims, so as City.
If you are creating profile table and adding city in profile, it shall be avoided to add it in Claims table. But you need to handle requirement of City as claim by queries Profile table and providing value as claim as needed.
ClaimsIdentity is System.Security.Principal.GenericIdentity type that is used to identify the user in claim based approach.
(Making Model will be helpful in the View)

how should a controller pass back different entities or collections to a view

Most of the samples I see online are showing CRUD with single entity class.
If I were to create a CRM application and one of the views needs to display customer information in read only mode and on the same page, display Contacts, Notes, Attachments, Addresses, how should the controller pass these different entities to the view?
Should I be creating another model class which will be a container for the various other entities and populate that model class with the various entities and pass back to the View.
In another scenario, say I wanted to display the Customer entity in Edit mode and the View has dropdowns for Customer Active Status, Customer StateCode, Customer Satisfaction dropdowns. Each of these dropdowns have other entity collections that are bound to them. So, again in this scenario, how should a controller pass back the model which has all these entities and not just Customer entity.
I continue to read on ViewModel pattern and I think this may be the way to go but would certainly appreciate more guidance and pointers.
You're exactly right. Create a ViewModel which represents the objects which your page requires.
Your first scenario could be something like the following:
public class CustomerInformationViewModel
{
IEnumerable<Contact> Contacts { get; set; }
IEnumerable<Note> Notes { get; set; }
}
Populate these in your controller and then access them in your view.
#foreach (var contact in Model.Contacts)
{
#Html.DisplayFor(c => c.Name)
}
For your second scenario, exactly the same. You want to bind to your customer properties but you also want some additional collections for drop down lists.
public class CustomerEditViewModel
{
Customer Customer { get; set; }
IEnumerable<Status> StatusOptions { get; set; }
IEnumerable<StateCode> StateCodeOptions { get; set ; }
}
Just keep in mind that you will need to re-populate these collections in your controller if you discover that your ModelState is invalid at the controller.

Creating a list in asp.net mvc without javascript

I want to create a form where the user creates a list and then saves it. The list can have an arbitrary number of rows. The user cannot save the list until it is complete (all rows/items are added) and I cannot use javascript to do it all on the clientside before posting.
The form will create a contact, like in an address book or something. The entity looks like this:
public class Contact
{
public string Name { get; set; }
public string Company { get; set; }
public List<ContactRow> ContactRows { get; set; }
}
The ContactRow looks like this:
public class ContactRow
{
public string Type { get; set; }
public string Value { get; set; }
}
So, basically it is a contact with a name and a company. The contact has a list of contact rows, where each row has a type (phone, email, etc) and a value (555 - 12334, test#email.com, etc).
My form will contain two ordinary textboxes for Name och Company respectively. But I'm not sure how to handle the list with contact rows. What I want the user to be able to do is adding new rows, editing rows and deleting rows. All this must be done before the save button i clicked, i.e. the list must be all done when saving.
This is not very hard to to with javascript and I've already done that. But now I want to implement this functionality without javascript. It is ok to post to the server while building up the list, but the list cannot be saved until it is done.
Ideas?
If you do not wish to use javascript a postback whilst building up the list is all you can do.
This user experience is often deemed poor as work is ongoing, but is the best starting point when using progressive-enhancement to make your application more user friendly.
The OP stated Javascript was not an option. I feel your pain as one of our applications had a similar requirement. We have a construct called an updateable list with the same functionality as you outlined.
We perform data handling on the server. Each list is displayed in a table. Each row contains the item data and has an action icon associated with it. The default is to display and we support new, updated and deleted actions.
After the user enters data for an item they press a button to add or remove the item from the list. Selecting existing items allows for an update operation. The list, and status, is determined on the server and the client does not run Javascript.
As #rich.kelly pointed out you will need to go to the server for each operation. It takes longer to do anything and your session gets a workout but it meets the client requirements.

Alternative User management in ASP.NET MVC

I am in the planning phase of a new ASP.NET MVC application and one of the requirements is storing some user information that is not part of the standard set found in the User class that comes with ASP.NET MVC. I suppose it comes down to two questions.
1) Can I edit the class that is being used already to store the information that I need?
2) If I roll my own how can I keep things like the Authentication piece that make things so nice when trying to lock down some views using the User.IsAuthenticated method?
Another alternative I have considered is using the User class provided as is, and instead putting the other information into a separate table with the guid userid as the foreign key.
Suggestions?
Profiles are one option as #Burt says, and offers a lot of flexibility.
I had a similar need to track Employee information, but I opted to roll my own Employee class and create a relationship to a standard User. I really like how this has worked out as I can keep any Employee specific business logic separate from the User class Membership system.
Since not every User was going to be bound with an employee, this made more sense for my case. It may not for yours, but it is an alternative.
So, I have something like:
public class Employee
{
public Employee(string name) : this()
{
Name = name;
}
public virtual string Name { get; set; }
public virtual string Title { get; set; }
public virtual decimal Salary { get; set; }
public virtual decimal Hourly { get; set; }
public virtual decimal PerDiem { get; set; }
public virtual string StreetAddress { get; set; }
public virtual Guid UserId { get; set; }
public virtual MembershipUser User {
get
{
// note that I don't have a test for null in here,
// but should in a real case.
return Membership.GetUser(UserId);
}
}
}
See ASP.Net MVC Membership Starter Kit. It provides the Asp.Net MVC controllers, models, and views needed to administer users & roles. It will cut distance in half for you.
Out of the box, the starter kit gives you the following features:
List of Users
List of Roles
User
Account Info
Change Email Address
Change a User's Roles
Look into profiles that are part of the membership functionality provided by MS. They are extendable and pretty flexible.

Resources