Is there a built-in way of associating persistent model data with an authenticated user in MVC4, or are you supposed to provide your own implementation?
The MSDN tutorials I've read don't suggest how to do it, but I've seen a WebSecurity.CurrentUserId property I could store. For example, a model for a site that allows the user to upload photos:
public class Photo
{
public int Id { get; set; }
public int UserID { get; set; } // Controller sets WebSecurity.CurrentUserId?
public DateTime Created { get; set; }
...
}
Or is there an "MVC way"?
can you not use something like this:
public class Photo
{
public int Id { get; set; }
public int UserID { get; set; }
public DateTime Created { get; set; }
public UserProfile user {get;set;}
...
}
public class UserProfile
{
public int UserID { get; set; }
}
Related
i am trying to define a database model in code-first to see and display which user is assigned as a specialist for the record data.
I have a very simple model for the user:
public class User
{
public int ID { get; set; }
public string userName { get; set; }
public string firstName { get; set; }
public string lastName { get; set; }
....
}
Next I have defined two (simple) models which define the data that can be edited by the user and the specialist should be assigned to using a dropdownlist:
public class Order
{
public int ID { get; set; }
public string orderNumber { get; set; }
public int specialistID { get; set; }
public virtual User specialist{ get; set; }
}
public class Part
{
public int ID { get; set; }
public string partNumber { get; set; }
public string description { get; set; }
public int specialistID { get; set; }
public virtual User specialist{ get; set; }
}
What kind of relation between the models can be used without having a navigation property for each table in the User model?
Do I need to use additional tables to define the relationship: User.Id-Order.specialistID and the relationship: User.Id-Part.specialistID ?
Is there a smarter way out-of-the-box by Entity Framework?
Many thanks for your answers.
Pascal
By default when you add forign-key constraint to the many-to-one table the Entity Framework add virtual property to the entity class and virtual ICollection to the User.
I'm having trouble understanding how to implement a ViewModel in Asp.net MVC, I have the following tables:
Form
ID, Data
Report
ID, FormID, Owner, Category, Status, SubmissionDate
ReportValues
ID, ReportID, Title, Value
I'm looking for a way to display and edit Report and ReportValues in the one ViewModel where ReportValues.ReportID = Report.ID
ReportValues will have multiple entries that relate to a Report.
I have had a look at similiar questions on here and tried following a tutorial ( http://techfunda.com/howto/262/list-data-using-viewmodel ) and coming up empty handed.
If you need any more information let me know and thanks in advance for any replies!
Your View Model is nothing more than a class. You can solve this many ways, but here's an example.
Create your 3 classes like you normally would.
public class Form
{
public int Id { get; set; }
public string Data { get; set; }
}
public class ReportValues
{
public int Id { get; set; }
public int ReportId { get; set; }
public string Title { get; set; }
public string Value { get; set; }
}
public class Report
{
public int Id { get; set; }
public int FormId { get; set; }
public string Owner { get; set; }
public string Category { get; set; }
public string Status { get; set; }
public DateTime SubmissionDate { get; set; }
}
Then, create your ViewModel class to include the three above classes like this.
public class ReportViewModel
{
public Form Form { get; set; }
public ReportValues ReportValues { get; set; }
public Report Report { get; set; }
}
In your view you can access your three classes and their properties as you would in your controller. Model.Form.Id
Depending on your data types, ReportValues will likely be a property of Report, but that's entirely up to your data structure. You will need to populate the classes using whatever method you want (Entity Framework, ADO, etc.) before you can pass them to your view and use them.
In MVC i want to authenticate users,they must not be able to see other user data when logged on. Users must be able to CRUD their own data only. I have created two model:
public class User
{
public int id { get; set; }
public string Username { get; set; }
public string Firstname { get; set; }
public string Lastname { get; set; }
public List<Product> Products { get; set; }
}
public class Product
{
public int productId { get; set; }
public string productName { get; set; }
public double productPrice { get; set; }
public User Users { get; set; }
}
And i have product controller, where i want to authenticate users from CRUD other users data.
You can make your code to perform CRUD operations on only the products available for logged in user.
Use below scenario for your requirement.
public class User
{
public int id { get; set; }
public string Username { get; set; }
public string Firstname { get; set; }
public string Lastname { get; set; }
public List<Product> Products {
get{
//get all products from database/storage for this user. for ex: I have called a method to get products
//you can filter products related to this user by sending this user id to database or using code like below
//Writing this code/logic in controller would be preferable
return GetAllProducts().Where(p => p.Users.id == this.id).ToList();
}
set;
}
}
Agree with Rajesh, I would recommend you use Current User's data and filter Rajesh you showed. Current User's Data may include Id of current logged user. If you use cookies to keep user's session, you can retrieve his Id from cookies in controller or filter attribute: HttpContext.Current.Request.Cookies["auth_cookie"].
I am buys designing the model below:
public class LogModel
{
public class UserActivityLogs
{
[Key]
public int id { get; set; }
//Id of the user
public string userId { get; set; }
//Time of the log
public DateTime time { get; set; }
public LogActions action { get; set; }
}
// Types of actions to log
public class LogActions
{
[Key]
public int id { get; set; }
public string name { get; set; }
public string description { get; set; }
}
}
Now what I would like to know is do I need to add a table in the context for Logactions as well as UserActivityLogs or will EF see that the two tables are linked and create the log action table automatically?
Also have I specified my relationships correctly? What I was aiming for is that I can define multiple types of Logactions and then a userlog will then have a single log action associated to it.
First, don't use nested classes, it's a needless complication. Use namespaces to organize classes.
Second, don't use plural names for classes. One instance of class represents one entity. Also, use CamelCase names for properties.
Third, yes, Entity Framework will be aware of the associations between the two classes and create a database model with two tables and a foreign key.
So this leaves you with:
namespace MyApp.LogModel
{
public class UserActivityLog
{
[Key]
public int Id { get; set; }
public string UserId { get; set; }
public DateTime Time { get; set; }
public LogAction LogAction { get; set; }
}
public class LogAction
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
}
I want to create large user table (advance User Profile) and save user's data in my database context. So, I don't want to use 2 DbContexts in my project. When users register to site, they data (UserName, Password etc.) stores my own User table. My classes are like this:
public class ModelBase
{
public int Id { get; set; }
public DateTime CreateDate { get; set; }
public DateTime LastUpdateDate { get; set; }
}
public class User : ModelBase
{
public string UserName { get; set; }
public string Password{ get; set; }
public string FullName { get; set; }
public string Email { get; set; }
public DateTime BirthDate { get; set; }
public string Specialty { get; set; }
}
public class News : ModelBase
{
public int UserId { get; set; }
public string Title { get; set; }
...
}
....
Context is so:
public class MyDBContext : DbContext
{
public MyDBContext()
{
Database.SetInitializer<MyDBContext>(new MyDBContextInitializer());
}
public DbSet<User> UserSet { get; set; }
public DbSet<News> NewsSet { get; set; }
public DbSet<Project> ProjectSet { get; set; }
public DbSet<Section> SectionSet { get; set; }
....
}
class MyDBContextInitializer : DropCreateDatabaseIfModelChanges<MyDBContext>
{
protected override void Seed(MyDBContext context)
{
base.Seed(context);
}
}
I replaced DbContext name with mine and changed connection name in default SimpleMembershipInitializer class like this:
....
Database.SetInitializer<MyDBContext>(null);
try
{
using (var context = new MyDBContext())
{
if (!context.Database.Exists())
{
// Create the SimpleMembership database without Entity Framework migration schema
((IObjectContextAdapter)context).ObjectContext.CreateDatabase();
}
}
WebSecurity.InitializeDatabaseConnection("MyDBContextConnection", "User", "Id", "UserName", autoCreateTables: true);
....
Finally, I changed RegisterModel and WebSecurity.CreateUserAndAccount() suitable my User class. But, it does not work.
How can I use my own User table for register to site?
You can have Asp.net Membership and your complex classes connected together.
with this approach you will save so much time because asp.net membership is much more robust(you don't need to think about Role and User management) and sure you can make use of existing open source project like this and add it to your project with minimum effort of time.
Then your class will have structure like :
public class CustomUserDetail : ModelBase
{
public string UserName { get; set; } // what you really need is this to be unique for each user in you data base
// public string Password{ get; set; } handled by asp.net Membership
public string FullName { get; set; }
// public string Email { get; set; } handled by asp.net Membership
public DateTime BirthDate { get; set; }
public string Specialty { get; set; }
}
Then you can can add extension method to IPrincipal like :
public static CustomUserDetail CustomUserDetail (this IPrincipal principal)
{
var repository = new YourUserDetailRepository();
return repository.GetCurrentUserDetail();
}
and finnaly in your code easily use
<p> #User.CustomUserDetail.FullName </p>