I got 2 Models with 1-1 relationship.
public class CustomerModel
{
public int Id { get; set; }
public string Name { get; set; }
public AddressModel Address { get; set; }
}
public class AddressModel
{
public int Id { get; set; }
public string Street { get; set; }
}
Now I need a view that I can link the Address model with the customer, so, in the create of the customerModel, it bring the address create too, and linked, like in the post the address will be in the customer field.
#model Mvc.Models.CustomerModel
#Html.EditorForModel(Model)
#Html.EditorFor(x => x.Address)
If you create your view like that, you will then able to post back to an action result that takes a CustomerModel and the binding should work correctly
You'll probably want to do a bit more with custom annotations etc. as I doubt you'll want the user to be able to edit the Address id, but that should point you in the right direction
Related
Okay, so I'm in the middle of an ASP.NET project in work at the minute and it's all going well. So far I have all the models, views and controllers made and they all work perfectly, but now I have been told that I need to make a class (lets just call it results to make life easy here) to display all the data. This is an example I was given for what the displayed results would look like:
There are multiple different displays at the moment for different things like a person, travel insurance, car insurance etc. and the only common things between each different display are the full name, contact email, contact number, contact address and recorded time stamp. It's the additional data that changes for each display depending on what is being requested, i.e., person displays all the information stored about the person like full name, age, DOB, mobile number, home address and so on while travel insurance displays all information stored about the travel insurance for the person who is asking like the trip type, trip destination, group type (single/couple/family/friends), travelers ages and so on..
My question is this: how do I create this results class to display the required data? Do I need another controller, model and view or do I just need to create a class called Result and put everything into that? (I think I just have to create a class but I am not sure, hence why I am asking) Also, how do I make it in such a way that different things are displayed in the additional data depending on what the person searched for? Like I don't need all the additional data about car insurance appearing when a person searched their travel insurance - does this mean I will need multiple forms of the results class which all refer to a different searchable thing or can everything go in the one class?
Apologies if this is awfully worded and/or a bad question - I did try looking for something to help myself before posting here but I couldn't find anything. I'm also quite new to the whole ASP.NET front so apologies if I'm missing anything obvious.
Create a base Model class and put all the common properties to be displayed in that, and derive other Model classes from that class with their specific properties in them. You can pass Person object to the view where Person's info need to be displayed and TravelInsurance object where Travel Insurance's info needs to be displayed.
public class ModelBase
{
public string FullName { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string Address { get; set; }
public DateTime TimeStamp { get; set; }
}
public class Person : ModelBase
{
public string DateOfBirth { get; set; }
public string MobileNumber { get; set; }
}
public class TravelInsurance : ModelBase
{
public string TripType { get; set; }
public string TripDestination { get; set; }
}
If that does not sound like the way to go, you can have a generic Model class with a generic Data property within it:
public class Model<T>
{
public string FullName { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string Address { get; set; }
public DateTime TimeStamp { get; set; }
public T Data { get; set; }
}
public class Person
{
public string DateOfBirth { get; set; }
public string MobileNumber { get; set; }
}
public class TravelInsurance
{
public string TripType { get; set; }
public string TripDestination { get; set; }
}
where you can pass objects to your view like this:
var x = new Model<Person> { FullName = "...", Data = new Person { } };
OR
var x = new Model<TravelInsurance> { FullName = "...", Data = new TravelInsurance { } };
This is my project model :
public class Project
{
public int ProjectID { get; set; }
public string ProjectTitle { get; set; }
public string ProjectDetails { get; set; }
public virtual ICollection<Proposal> Proposals{ get; set; }
}
This is my Proposal model :
public class Proposal
{
public int ProposalID { get; set; }
public string BidTitle { get; set; }
public string BidDetails { get; set; }
public virtual Project Project { get; set; }
}
As you can see, there is one-to-many relationship between Project and Proposal. In
mydomain/Project/Details/ProjectID
view, I want to put a button, when this button is clicked, user can create a new Proposal for that project. My question is how I can pass that project's information to bid? If you can give me some tips about it, I'd be really glad. Thanks.
Create a model known as a viewmodel, which includes both the models you want to use under the same view. Your would look something like this:
public class ProposalAndProjectModel
{
public Proposal Proposal { get; set; }
public Project Project{ get; set; }
}
Save it as something like ProposalAndProjectModel.cs and then in your view, reference this model.
Now in your view you will be able to do the following:
Model.Proposal.propertyName
or
Model.Project.propertyName
This should help you as for getting the correct parameters for creating new objects.
You say when user click button user goto another page. You can sen projectID as get to that page. Thats how you can get that projectID.
I'm quite stuck with ASP MVC Model's, Now I understand how to create a simple model so I could set some values like this:
namespace build_01.Models
{
public class NewBooking
{
public int bookingID { get; set; }
public string bookingName { get; set; }
}
}
Now what I'm trying to do is have a Model that has all the bookingNames for example such as:
namespace build_01.Models
{
public class BookingNames
{
public string administrator { get; set; }
public string normal { get; set; }
public string user { get; set; }
}
}
However, what I would like to do is get this data from a database, for example I could have adminsistrator, normal, user, superuser, banned or whatever I like but the idea is that this information in the database can be changed. The bookingNames can be added, edited or deleted.
So let's say I just added superuser and banned to the database my model would now look like this for when I send it to the view and submit a form from the view to send to the HTTPPOST controller:
namespace build_01.Models
{
public class BookingNames
{
public string administrator { get; set; }
public string normal { get; set; }
public string user { get; set; }
public string superuser { get; set; }
public string banned { get; set; }
}
}
In my view I'm basically making checkboxes based on this information however I need to be able to set and get the values in a model so I can access them in my HTTPOST controller.
Now i've had a look at the Entity Framework but that doesn't seem to be what I want.
Is it possible to be able to create a model with the actual rows or even a column from a row in order to send it to the view to create a form for those columns so that I can return the values to the HTTPPOST in order to input data into a row in a table?
If so how can I approach this?
I'm creating MVC5 app, and I'm already using ASP.NET Identity to create users. So, I already have the AspNetUsers table, and whenever user registers I get an entry there. I also have an Admin role, where I manually specify, which registered user is an admin. On the other hand, I also need to register Businesses, and much like normal Users, they will be able to log-in, register, and do some stuff. The point is that they will have both some similar and different fields with/from the normal users. For example, they will also have, e-mail address, password (which I want to be hashed like for normal users), e-mail confirmation, unique id etc. But they have different fields for more information, like their address, zip, country, category, etc. which normal users don't have. How can I achieve this in MVC?
Should I do something like the ApplicationUser class?
public class ApplicationUser : IdentityUser
I mean, should I inherit my Business model from the IdendityUser? If yes, how will my model know which of the fields from IdentityUser to use and which not?
Here is my current Business model:
public class Business
{
public int BusinessID { get; set; }
public string BusinessName { get; set; }
[ForeignKey("Category")]
public int CategoryID { get; set; }
public virtual Category Category { get; set; }
[ForeignKey("Subcategory")]
public int SubcategoryID { get; set; }
public virtual Subcategory Subcategory { get; set; }
public string BusinessAddress { get; set; }
public string BusinessZip { get; set; }
public string BusinessPhone { get; set; }
public string BusinessDescription { get; set; }
public string Facebook { get; set; }
public string Twitter { get; set; }
public byte[] ImageData { get; set; }
public string ImageMimeType { get; set; }
[Range(0.0, 5.0)]
public double BusinessRating { get; set; }
public virtual ICollection<Review> Reviews { get; set; }
}
So, apart from those fields, I want my table to include the stuff similar to AspNetUsers, like Email, EmailConfirmed, PasswordHash, SecurityStamp, etc.
EDIT:
Please note that some of my fields in the Business model are required. And also below you can find my ApplicationUser class.
public class ApplicationUser : IdentityUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
}
Use simple inheritance:
public class Business : ApplicationUser
{
...
}
You'll end up with a Discriminator column in your AspNetUsers table that will help Entity Framework identity which class it should instantiate for the row (Business or ApplicationUser). Then you can either just query as normal or if you only want one particular type or another, you can use OfType<T>:
var businessUsers = db.Users.OfType<Business>();
Note: By default, Entity Framework handles simple inheritance with a single table with a Discriminator column. For most cases this works just fine, but you must keep in mind that any property you add to subclasses of your base class, must be nullable. You cannot require something like a DateTime on Business to be required at the database-level, because then you could never save an ApplicationUser, which does not that property. However, this is only an issue at the database-level. You can still use view models to make a particular property on Business required from a front-end perspective.
I'm tying myself in knots - and thought it best to take a big step back, and back to basics.
I understand I should be using a ViewModel, so that is what I'm trying to contruct.
My demo app will have 4 sections (4 different parts of a form to complete):
Get Date/Number of days from user
Use that data to query the database, and return a list of qualifying records - each of these will have a unique ID of TypeID - and for each of these, they should also have 2 dynamic DropDownLists associated with them (so that whatever is selected in ListBox3 for each of the lists, corresponds to the TypeID3 (and whatever ID that has)
user will then be able to select Extras, again from a drop down list populated dynamically
users Name/Add/Tel will be collected
My "View" of what the ViewModel needs to look like/hold is:
I beleive my viewModel should look something like this:
public class SearchViewModel
{
public DateTime Date{ get; set; }
public int Days { get; set; }
public IQueryable<TypeID> TypeIDs { get; set; }
public IQueryable<LB1Item> LB1Items { get; set; }
public IQueryable<LB2Item> LB2Items { get; set; }
public IQueryable<Extras> Extras { get; set; }
public string Name { get; set; }
public string Add { get; set; }
public string Tel { get; set; }
public string email { get; set; }
}
First of all - is this how you would construct a ViewModel for what I've described above? I'm not certain of the DropDown Boxes, as for each form, there could be 1, 2, 3....10, 11, 12 for each TypeID retrieved - based on the Date selected.
Each of the drop down boxes for LB1Item and LB2Item - need to have their selected values stored against the TypeID for each line also.
This is what I think the class should look like for 1 drop down:
public class LB1Item
{
public String TypeName { get; set; }
public long TypeID { get; set; }
public int NumSelected { get; set; }
public int TypeCount { get; set; }
public IEnumerable<SelectListItem> CarsAvail
{
get
{
return new SelectList(
Enumerable.Range(0, TypeCount+1)
.OrderBy(typecount => typecount)
.Select(typecount => new SelectListItem
{
Value = typecount.ToString(),
Text = typecount.ToString()
}
), "Value", "Text");
}
}
}
Does that look ok also? Or am I overcomplicating what I'm trying to achieve?
I'd also like, after POSTing back the data after each stage (1, 2, 3, 4) to be actively populating the ViewModel with the selected values - and passing it back down to the view, so that I can retrieve it for the next Step.
What I want to end up with is something like this:
Date: 01/09/2012
Days: 4
{ List:
TypeID: 3059 ListBox1: 2 ListBox2: 8748,
TypeID: 2167 ListBox1: 7 ListBox2: 2378,
TypeID: 4983 ListBox1: 4 ListBox2: 5873
}
{List:
ExtraID: 4324,
ExtraID: 3878,
ExtraID: 4872,
ExtraID: 7698,
ExtraID: 2873
}
Name: Mark
Add: My town
Tel: 0912378
Email: me#me.com
Thanks for any help/pointers/samples...
Mark
For this type of solution I would separate out each section you want to render as individual views and use Ajax calls using Jquery ajax method. I would also use KnockoutJS to handle the views in your client. So you will essentially have two ViewModels, one in JavaScript in the client and one in MVC for returning the pieces you need as JSON for the Ajax calls from the client. Section 1 of your view is entered by the user into the client so you do not need it on the Controller side. Section 1 is basically the data used to query for Section 2. No need to make your collections IQueryable either since you will not being querying the lists that are returned. Your ViewModel on the Controller side might look something like this:
public class Section2
{
public List<TypeID> TypeIDs { get; set; }
public List<LB1Item> LB1Items { get; set; }
public List<LB2Item> LB2Items { get; set; }
}
public class Section3
{
public List<Extras> Extras { get; set; }
}
public class Section4
{
public string Name { get; set; }
public string Add { get; set; }
public string Tel { get; set; }
public string email { get; set; }
}
So the steps that would be taken are that when an event is thrown that the date and days have been entered by the user an Ajax call is made back to a controller with entered data and days to query for the information that will populate Section 2. The controller returns the Section2 ViewModel as JSON and it is rendered in the HTML using Knockout. Then when the user selects from the lists in Section 2 an event is thrown to query the controller again to return the information needed to populate Section 3, and the cycle is repeated.
There is an excellent example on using Knockout to do exactly what you are trying to do here.