I'm creating a MVC application with a CRUD. In the list view I have the PagedList helper. I set the pageSize variable in the code: pageSize= 5, so the list only show 5 files and allow go to the previous and next pages.
In the other side, I want to create an option called "Parameters" where the user can define yourself the "pageSize" value.
I'm confused about how to do it.
Thanks in advance.
Consider using a Profile provider
http://wiki.asp.net/page.aspx/1327/profile-provider-in-aspnet-mvc/
Or create a bespoke UserSettings table to store the setting yourself.
You can write pagesize that user choose in session variable and read it from it when you need:
To write to session you should call:
Session["pagesize"]=pagesize;
To read from session you can use:
var pagesize = (int)Session["pagesize"];
You should check that this value is in session before cast to avoid null reference exception.
Session variable can be used when you want keep it only during working period of user. If you want save it for long period, you should save it into database or in file.
If you are using Sql Sever, then do a simple table
Create Table UserProfile (
UserId Int Not null,
ProfileName Varchar(50) Not null
Value Varchar(50) Not Null
foreign key (UserId) references [UsersTable] (UserId)
)
You can save and retrieve PageSize or any other profile from this table.
What's common among modern web applications is a page size <select /> list:
What you want to do next is remember the user's choice in a cookie. The user experience (UX) is much better than the profile approach for 2 reasons:
both registered and anonymous users can select a page size
it is not necessary to navigate to a setting or profile page to select the page size
There are scenarios that call for a profile page but definitely not this one.
Related
I am really new in cakephp. I want to know how to restrict the user from opening pages such as Users for example when the user changes the url. Well, I am not good at telling my own problems so here:
for example: the user id is 1 so when he viewed his own details it should be something like users/view/1, but i dont want that user to view user # 2 when he changes the url to users/view/2. I hope you undersand. Thanks in advance!
assuming you have the current looged in user data store in a session somewhere.
the idea is to compare it against the passed id in the url
---- in your UsersController.php
public function view($id){
if($this->Session->read('User.id') != $id ){
// cannot continue...
// possibly redirect....
}
}
The solution can be found via google:
http://www.dereuromark.de/2011/10/05/common-cakephp-problems-and-solutions/
Basically, you get the current id from session:
$uid = $this->Session->read('Auth.User.id');
And compare it against the record you are displaying/editing.
If they don't match, you throw a NotAllowedException().
Protip: Don't append the id for edit/view etc, if it's the user's own profile or if it can only be viewed by the owner.
Same way you obtain the ID above for validation, you can also use this session user id to get the correct record in the first place.
Also, don't put the id into the view (forms) - not even as hidden field - but inject it into the data array prior to saving/validating.
You can also see a current CakePHP 2.4 implementation here - which can also be seen/tested live via corresponding website.
I was looking for a data level Authorization filter in my ASP.Net MVC 4 Application.
We are using Entity Framework for Data access.
The application need to display all the data but should restrict the access to certain fields in a table based on the user roles.
eg: TASK table
{
int Id,
string TaskName,
DateTime StartDate,
DateTime EndDate
}
This whole data will be displayed to all the users and users have the options to edit the fields also. But should restrict the edit options like as follows
Role Admin can edit all the fields
Role Manager can Edit TaskName but cannot edit StartDate and EndDate
Role Users cannot Edit any of the fields
All these edit will be calling the Edit action in the TaskController.
How can I implement the functionality in my application.
You might try Postsharp. PostSharp allows you to design custom attributes for injecting boilerplate code at compile-time. It should be possible to use it for scenarios such as your example. I've used it for exception handling, logging, caching, & security. It can be applied to any layer or framework.
See, "Securing Fields and Properties" in the following illustrated example:
http://www.sharpcrafters.com/solutions/authorization
Hope it helps.
This is not EF, another ORM, but might help to see how it can be done - full source code is here.
Autorization subsystem is explained here.
It does what you need - row-level, up-to-column granularity, role-based authorization.
Sounds like what you are after is a true 'business' object that is smart and contains authorization at the property level not just at the method level. I would suggest using CSLA.NET and create your business object model with smart objects. This gives you that feature as well as a bunch of others.
This whole data will be displayed to all the users and users have the options to edit the fields also. But should restrict the edit options
Instead of a single Edit action in Task controller
create a specific action for each unique field set allowed to be edited
Edit(TaskName, StartDate, EndDate) for Admin
Edit(TaskName) for Manager
no Edit action for User, since ther are not allowed to change any fields
use authorization per action
I want to implement the type of authentication that is explained here in an ASP.NET MVC application.
http://jaspan.com/improved_persistent_login_cookie_best_practice
My current implementation is having a Users and UserLoginTokens tables:
CREATE TABLE [Users].[Users]
(
Id int NOT NULL,
UserName nvarchar(30) NULL, -- Not unique. Login by Email.
Email nvarchar(100) NOT NULL,
PasswordHash nvarchar(512) NOT NULL,
PasswordSalt nvarchar(512) NOT NULL,
)
CREATE TABLE [Users].[UserLoginTokens]
(
Id int NOT NULL,
UserId int NOT NULL,
Token varchar(16) NOT NULL,
Series varchar(16) NOT NULL,
)
After the user is log in, he issued a User cookie with the content: t=#Token&s=#Series.
Now, I have PersistentLoginModule that search for this cookie each request, validate that the Token and Series are valid build the user from it.
My questions:
In order to implement this, is it good idea to implement my own authentication module and don't use the FormsAuthentication at all?
Should I validate the token against the DB in each request?
When should I discard the old Token and issued to user a new one?
Regarding the implementation of the DB, if I understand it correctly the Series is always the same, for a given user. If so, maybe I should move it to the User table?
Thanks, any help will be very appreciate!
If you're going to build your own Authentication Module, I would recommend still using the FormsAuthentication ticket.
The FormsAuthenticationTicket class has a UserData property that you can use to store additional data.
You can use the static FormsAuthentication.Encrypt(ticket) and FormsAuthentication.Decrypt(ticket) methods to store and retrieve the data set in the cookie.
NO. You don't want to go to the database on every request. You might want to store something like the HASH of the provided evidence in some kind of session variable (after you've verified it against the database). You could then later just recompute the HASH and compare it to the value you've already verified during the current session (to verify that it hasn't been tampered with).
You should definitely do your research on best practices and authentication hacking. The article you linked to is from 2006. There has been lots of changes in web security since then.
Check the source code to the FormsAuthenticationModule to see how the Microsoft implementation works (using something like reflector). You should also make sure that this KB patch is installed http://support.microsoft.com/kb/2416472
Our web application needs one common parameter in every action method.
In our case it is the customer account id and we need to support the following scenarios
a. A group of users might have the same account id which can be derived from the user profile.
b. Customer Support team should be able explicitly supply the account id of a customer and also should be able to switch the account on any page
We are trying to not to use asp.net session to store this kind of data.
Are there any other options to store and manage this kind of common parameter data?
Write it out as an ecrypted value to hidden field on your master page and supply the value to every view. When the user is in a a customer role, place a change account "control" on the page that is able to retrieve and update the account data -- via AJAX, perhaps -- to change the current account id. It might be easiest to do this with a custom base controller which gets the data via the ValueProvider directly and stores it as a property on the page rather than having it be a parameter to every method.
Use Routing for the value. So if you need to change the id you can use another URL or post it as a parameter.
Whenever you need the value just ask the ValueProvider for it.
In case it is blank - use the one from user profile.
Of course you'd better write small method that will do just that:
// Register route like:
route.MapRoute("ProvidesAccountId", "{controller}/{id}/account{accountId}/{action}.aspx")
// Property on the base controller
protected Account CurrentAccount {
get {
var accountId = ValueProvider.GetValue<int?>("accountId"); // GetValue is just a helper
if (accountId.HasValue)
return YourRepositor.GetAccountBy(accountId.Value);
return CurrentUser.Account;
}
}
Not to use current user's account hit the URL: Profile/123/account/Edit.aspx
To use another account you can hit the URL: Profile/123/account-456/Edit.aspx
You get the idea.
Cheers,
Dmitriy.
I have an MVC application that times out the session after 20 minutes. I store some values for a dropdown in a Session variable. If a user allows a page to timeout and then refreshes the page, I have no values in the dropdown.
What is the best way to deal with this?
Persist the information into some form of storage e.g. a Database.
I assume the dropdown data is from a database. If so, you'll need to repopulate the session. I assume you are using Windows authentication - otherwise, say if you were using form-based authentication, you would also have to get the user to log in again by redirecting to a login page.
If the dropdown data is not from a database, you could store it in Web.config and update it from there.
Exactly how you deal with this depends on specifics which you haven't mentioned. For example, on some of my projects, it's been sufficient to check if the session variable exists (on every non-post access to the page) and if absent, repopulate the session with that information.
You can try to use InMemory cache instead of Session (if it's really needed to store it somewhere and do not get from database). You need just to specify key (for each dd list) and expiration time
using System.Runtime.Caching;
public static dynamic Get(string key)
{
ObjectCache cache = MemoryCache.Default;
var item = cache.Get(key);
return item;
}
public static void Put(string key, dynamic ddResult)
{
CacheItemPolicy policy = new CacheItemPolicy();
policy.AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(1); // expiration in one minute
ObjectCache cache = MemoryCache.Default;
cache.Set(key, ddResult, policy);
}
Can I know whether it's a Windows application or a web-based application in the web-based application if you are going to use the database as source to display the data in the dropdown we give it as :
DropDownList3.DataSource = Class2.details().Tables[0];
DropDownList3.DataBind();
Here Class2 is the class having the function name called details in that we are going to have the SQL query to display the data from the database to the dropdown (SELECT query).
Then we will using that dropdownlist's data into the session as
session["anyname"]=dropdownlist3.selecteditem.text;
Then according to you we can give the timeout values in the web.config file also.