MVC3 and EF // Add an Image to an existing database object - asp.net-mvc-3

Model
public class Discount
{
public int DiscountId {get; set;}
public string Name { get; set; }
public string Information { get; set; }
}
I want to add an image to this model that does not exist yet. For instance when a user browses to the CRUD page Create View, the user can create a new Discount and it will have the option to browse/upload a new image that will be identified with the new discount created.
File Upload ASP.NET MVC 3.0
has taught me how to upload images in MVC3 but I am needing assistance on mapping this uploaded image to a specific discount (DiscountID).

I'm not sure what is your actual requirement is, but you can give image name based on the DB id. Eg. Img0001 etc.. Also, save the path of that image file in the related record in the DB.

Related

How to dynamically reflect changes to a Razor Page Model on pages and database?

I'm building my first Razor Pages app by following Microsoft's tutorial, and I'm curious about the correct way to reflect changes to my model on CRUD/scaffolded pages and corresponding database table. I have used below steps to handle this, but my solution feels more like a hack. Is there a better way to do it? I'm looking for a dynamic solution which allows for better separation of concerns.
What I aim to do: I want to remove CVRnr from below model, have the corresponding column in the database table dropped, as well as removing references to CVRnr on pages. The problem is that my changes to the model isn't reflected dynamically elsewhere in the project.
namespace Virksomhedsgodkendelser.Models
{
public class Company
{
public int ID { get; set; }
public int Pnr { get; set; }
public int CVRnr { get; set; }
}
}
What I have done to solve this:
Deleted public int CVRnr { get; set; } from the model
Deleted the CRUD pages in ~/Pages/Companies/
Re-added the CRUD pages via: Add > New Scaffolded Item > Razor Pages using Entity Framework
Deleted dbo.Company from my database
Re-added the database table via Package Manager Console: Add-Migration InitialCreate + Update-Database

How to Authenticate using MVC5RC/RTW with existing database

I originally asked this question when Identity was in beta. The classes and interfaces have changed considerably since then and it appears the RTW version has some modifications again over the RC version. In principle I need to achieve the following.
authenticate the local login against my usertable tblMembers which contains the userid field and password which are the two items I need to authenticate.
have access to my tblMember record/class via the Controller.User property (Prior to MVC5 identity I had achieved this using the membership provider methods.) regardless of if the user logged in via the localuser method or via one of the other OAuth providers (Twitter, Google etc).
Ability to display my own custom username despite the login method. Local users login with a userid 1234567 and a password, ideally I would like to display "John Smith (1234567)" regardless of the authentication method (local/Twitter etc)
Initially I'm unsure as to what my memberclass should be inheriting from It appears from the
aspIdentitySample project that I should be using IdentityUser?
public partial class tblMember
{
public int id { get; set; }
public string membership_id { get; set; }
public string password { get; set; }
....other fields
}
Are there any new or updated examples of integrating your existing database/user tables with the ASP.NET Identity system?
I am also adding the identity tables to my database. If you create a new web project in visual studio 2013 you will see that now in RTM everything works better than RC plus you will see the
following table
public class ApplicationUser : IdentityUser
{
}
So Instead of ApplicationUser you can call your table tblMembers
public class tblMembers : IdentityUser
{
}
your table tblMembers will inherit Id Username Password security stamp and a discriminator column saying this is a tblMemeber
without making custom classes for authentication the easiest thing to do would be just to make the username the combination of your old usernames and userids. Then store the users real name or old username without the user id in a separate column.
have the users register with the built in user login and they can go to manage account and click use another service to log in. This will link the Google account to their regular account, so no matter which one they use it will log them in to the same account. If you have users with connected table information, I suggest you seed your table with all the users with something similar to the register method found in the template.Then just match the new combined username and Id to the old ones and populate data where needed in sql management studio.
Again a lot of issues in RC with extending IdentityUsers have been fixed. Microsoft is already adding more features to the identity user store and this tutorial http://www.windowsazure.com/en-us/develop/net/tutorials/web-site-with-sql-database/ is supposed to be updated soon. I plan on making my own walk through when i'm done changing my database but for now I hope my suggestions even though they are a simpler solution than you might want to implement.
You can do this easily by modifying the IdentityModel.cs as per the below:
Override OnModelCreating in your DbContext then add the following, this will change AspNetUser table to "Users" you can also change the field names the default Id column will become User_Id.
modelBuilder.Entity<IdentityUser>()
.ToTable("Users", "dbo").Property(p => p.Id).HasColumnName("User_Id");
or simply the below if you want to keep all the standard column names:
modelBuilder.Entity<IdentityUser>()
.ToTable("Users", "dbo")
Full example below (this should be in your IdentityModel.cs file) i changed my ApplicationUser class to be called User.
public class User : IdentityUser
{
public string PasswordOld { get; set; }
public DateTime DateCreated { get; set; }
public bool Activated { get; set; }
public bool UserRole { get; set; }
}
public class ApplicationDbContext : IdentityDbContext<User>
{
public ApplicationDbContext()
: base("DefaultConnection")
{
}
protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<IdentityUser>()
.ToTable("Users", "dbo").Property(p => p.Id).HasColumnName("User_Id");
modelBuilder.Entity<User>()
.ToTable("Users", "dbo").Property(p => p.Id).HasColumnName("User_Id");
}
}
Please note i have not managed to get this working if the current table exists.
Also note whatever columns you do not map the default ones will be created.
Hope that helps.
I'm starting to think (partially due to the lack of information in this area), that it may be easier to user the default identity classes, but to provide referential integrity to my own user table from the AspNetUsers table.
If i add a custom linking field into the AspNetUsers table is it possible to access my tables from the Controllers.User property? i.e. Controller.User.tblMember.Orders?

MVC3 Registration form and model

I have a question regarding the MVC 3 and more exaclty about the views and models. I want to mention that I'm new to MVC so I'm oly learning it.
Basically for example lets take te registration form:
I have a controller, view and model, to register a new user.
AccountController
Register.chtml
AccountModel => RegisterationModel
Now, in registration model i have all the datamembers with data annotations, for example:
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
This are then rendered in view.
What bothers me, or I don't really understand how to do it properly:
Ok I have RegistrationModel ... but later on, for example if i want to render the profile of the user, should i call registrationmodel again or then it will be profilemodel? So basically I will have a lot of the same models just to render the same thing ... no?
Can't I have then one general Model, something like user, and then User i can pass with RegistrationModel/ProfileModel to view.
Maybe it is a bit difficult to understand what I mean exactly, but how I imagine it: for example a user submits a form, everything is parsed and a User object is created with all the data members, then this User object is pased to DAL, where it is submitted to DB. Later on someone visits the profile of this user and the DAL, will return User object back which is then displyed.
The answer to your question is no you should generally separate your domain models from your view models. Consider a following scenario. Let's say you have a User model and your business logic allows you to both add a new user and edit an existing user. Let's say your user model looks like this:
public class User
{
[Required]
public int? UserId {get; set;}
[Required]
public string LastName {get; set;}
[Required]
public string FirstName {get; set;}
[Required]
public string Password {get; set;}
public bool IsAdmin {get; set;}
}
Now in order for your user model to be valid you have to have User ID to make the user identifiable. When you're inserting a new user you don't need the ID because that is something database will automatically take care of on insertion. However when you're doing an update of the user then you need the user ID to be populated. So now you have a model that in one case requires a field (UserId) but in another it doesn't. How are you going to handle that?
The answer is view models and this is the reason why they exist and why it's advised to create one for each entry form you have in your project. In this case you would end up with a different insert and update user view models. I know it's tedious to convert these view models into the underlying domain models but there are libraries to help you do that automatically like AutoMapper (https://github.com/AutoMapper/AutoMapper/wiki/Getting-started).
2nd and probably more serious problem is over posting. Suppose you are using the above User model to edit the user in your database. Now the model has an IsAdmin field which specifies whether user is an admin or not. Now your edit user view will omit this field since you don't want the general user to be able to make themselves an admin. But let's say you're dealing with a really smart user and he make a hidden field with id of IsAdmin and makes it value to be true:
<input type="hidden" id="IsAdmin" value="true" />
and then he/she posts the form to your save user url. Because you are using the domain logic user model which has IsAdmin property this hidden field will map to your model and this user just managed to make himself/herself and admin in your site. This is precisely why you need view models so this scenario can never happen.

How to return a model still containing data from when view was rendered in mvc3

I have been working with mvc for a little while now, but now im stuck with a problem that I didnt see come :)
The method in the controller returns a view with a model containing a Customer and Booking:
public class CustomerAndBooking
{
public Customer customer { get; set; }
public Booking booking { get; set; }
}
In my view i fill out the fields from the Booking. Very simple. The Customer is just being showed in the view and not modified. When I submit the view, the Booking in the model have all the data I choosed from the view, but the Customer is null?? I was hoping that the Customer would still be as it were when the controller first created the model.
How do I make it so my model is still intact when submitting the view??
You can do this by add to view:
#Html.HiddenFor(m => m.customer);

How do I show a different Required message to instances of the same object in MVC3?

I have a Razor MVC3 project which has two user records in a form, one for the key contact and one for a backup contact. For example;
public class User
{
[Required(ErrorMessage = "First name is required")]
public string FirstName { get; set; }
}
Validation all works well except for the small issue where the user fails to fill out a field, it says 'First name is required' but I'd like to point the user to which one of the first name fields is missing. Such as 'Backup contact first name is required' or 'Key contact first name is required'.
Ideally I'd like to leave the [Required] annotation on the class as it is used elsewhere.
This seems like one of those small cases that might have been missed and is not easily achieved, but please prove me wrong.
Ryan
One way you can accomplish this is with a separate view model for this screen, instead of a single User model with all the error messages. In the new view model, you could have a BackupContactFirstName property, KeyContactFirstName property, etc each with its separate error message. (Alternatively this view model could contain separate User models as properties, but I've found that Microsoft's client validation doesn't play well with complex models and prefers flat properties).
Your view model would look like this:
public class MySpecialScreenViewModel
{
[Required(ErrorMessage = "Backup contact first name is required")]
public string BackupContactFirstName { get; set; }
[Required(ErrorMessage = "Key contact first name is required")]
public string KeyContactFirstName { get; set; }
}
Then pass your view model to the view like this:
#model MySpecialScreenViewModel
...
Your post controller action would collect the properties from the view model (or map them to separate User models) and pass them to the appropriate data processing methods.
An alternative I have stumbled across, just modify the ModelState collection. It will have the elements in a collection named by index, like 'User_0__EmailAddress' and you can adjust / amend / replace the Errors collection associated with that key.
[Required(ErrorMessage = "{0} is required")]
{0}=The DisplayName is automatically placed on it
sample
[DisplayName("Amount per square meter")]
[Required(ErrorMessage = "{0} is required")]
public int PriceMeter { get; set; }
output
Amount per square meter is required

Resources