I'm new to MVC4 programming. Followed the NerdDinner tutorial initially. Now am gradually complicating the scenarios. I want to populate a DropDown list from a table's field but don't know how to, although I searched for relevant material from Internet but couldn't get some sophisticated info.
The scenario is that there are 2 tables Software and Category (which represents the category of the software whether it is Anti-Virus, Graphics etc...).
In Software table, catID is in int form which has a foreign key relationship with the catID in Category table.
In Category table, catID and catTitle are the only fields.
Now while creating the Create view to add/upload a new Software, I want that the catTitle of all the catIDs are shown in a Drop-Down List, from which the user will choose the Software category, but I don't know how to do that....
The model being used in my Create.cshtml file is
#model SoftwarePortal.Models.Software
So in this case, what will be the arguments for
#Html.DropDownListFor()
How and where should i specify the SQL stmt to fetch catIDs and corresponding catTitles? (I am using Linq to SQL...)
How to access a table that is not declared as the model of the current View...?
In controller
suppose your Generated database entity will be SoftDBEntities
private SoftDBEntities se = new SoftDBEntities();
public ActionResult Create()
{
//se.Categorys will get all categories
//se.Categorys may be replace with a function which return records from Category table
ViewBag.CatId= new SelectList(se.Categorys, "CatId", "CatTitle");
return View();
}
In cshtml file
#Html.DropDownList("CatId")
if above statement not work then try this
#Html.DropDownListFor(model.CatId,(SelectList)ViewBag.CatId,"CatId","CatTitle")
Oh gosh! Would you believe all that I needed to do was to typecast the ViewBag.Categories to SelectList inside #Html.DropDownListFor()!!! Because it doesn't automatically take the shape of the stored item...
So stupid of me...
Related
There are times where I have to display the relationship between two entities. Question is, should you retrieve the data all in one query (with a join statement)?
For example, I have the entity User and Picture. A picture is created by one user. If I wanted to display list of picture names, and who uploaded the certain picture.
Two approaches:
1) Using Entity Framework relationship, where Pictures is an entity, and it has a User property (the user that created it). The User is an entity too.
foreach(var picture : context.Pictures.all){
picture.name
picture.user.name
}
2) Combining Picture & User into one POCO object and return that to the controller.
Controller:
foreach(var pictureUser : dal.GetPictureUsers){
pictureUser.PictureName
pictureUser.UserName
}
GetPictureUsers()
{
PictureUser pictureUserPoc = new PictureUsersql.Include("Picture").include("User").Select(sa=> new PictureUser {
PictureName = sa.PictureName,
UserName = sa.UserName});
}
The latter one was suggested in order to increase performance. Personally I would have written it in the former way since you do not couple what you want in the View logic (having Picture and User relationship printed) in the data access layer.
I hope I have stated the question clearly.
Thanks!
#foreach (var profile in Model)
{
#Html.DisplayFor(model=>profile.PictureName);
#Html.DisplayFor(model=>profile.User.Name);
}
The Model represents the Pictures; if you strongly type the view then you can use it.
I am new to MVC and EF and I have a question.
I have built a site with models views controllers etc.
On an edit view for a Case (pretty big model so I won't post it here) I have a FK to a Customer model using CustomerID. When a user selects a customer id from a drop down list, I would like to display CustomerName, CustomerPhone etc after the selection of the ID. I think I might need to do a post back for this to work?
Also, do I need to Include the related entities as part of the initial data "get"? I have read some detail on that but I dont fully understand how that needs to work.
Please let me know if I should post more info. Thanks!
Here is my ActionResult for Edit
public ActionResult Edit(int id)
{
Cases cases = db.Cases.Find(id);
//related data needs to loaded to show related data fields
//include related data entities
var v = db.Cases.Include("Customers");
ViewBag.TechnicianID = new SelectList(db.Technicians, "TechnicianID", "LastName", cases.TechnicianID);
ViewBag.BranchID = new SelectList(db.Branches, "BranchID", "BranchName", cases.BranchID);
ViewBag.EngineModelID = new SelectList(db.EngineModels, "EngineModelID", "EngineModelName", cases.EngineModelID);
ViewBag.CaseCategoryID = new SelectList(db.CaseCategories, "CaseCategoryID", "CategoryName",cases.CaseCategoryID);
ViewBag.Qualified = new SelectList(new[] { "YES", "NO", "PARTIALLY" });
ViewBag.CaseStatus = new SelectList(new[] { "OPEN/IN PROCESS", "CLOSED" });
return View(cases);
}
The line
var v = db.Cases.Include("Customers")
is what I am trying to use to load related customer data and then show in my edit view like this:
#Html.EditorFor(model => model.Customer.CustomerName)
Well it depends on what you are trying to do. You could include a model which holds all the required data and send it with every call on that page (initial empty ofcourse)
Once you selected the customer, do post-back and send the customerId to your application and return the same page with the desired model.
You could do that via AJAX too.
Also, do I need to Include the related entities as part of the initial data "get"?
Not sure if I understand what you are trying to say. You mean that you think you would have to send all customer's data down to the page and select the related data on client side?
My first MVC3 EF 4.2 site and I'm confused on some things, currently on ViewModels when querying and saving. Please correct me if I explain this poorly, i'm not sure how to term this. The .edmx automatically created the table classes but I read it was better to create a ViewModel, considering I need to join tables to display/edit my Product completely. The controller code below is where I join tables to output a Product to edit, and then save. My question - what is the right way to save the Product, to the Product.cs model generated by DbContext or my own ProductViewModel.cs?
Is there an easier method to query a product and join the tables and then map to the viewmodels parameters, or do I keep doing all this in the controller like below?
I also want to save/update the product each time someone views/clicks on the product, so I wasn't sure if I create a separate ViewModel for updating just that parameter or again, use the Product model.
Hope that makes sense! I can explain further if needed.
private SiteForgeEntities db = new SiteForgeEntities();
public ActionResult Edit(int id)
{
var viewModel = (
from a in db.Products
join b in db.Sites
on a.SiteId equals b.SiteId
join c in db.Sections
on a.SectionId equals c.SectionId
join d in db.Affiliates
on a.AffiliateId equals d.AffiliateId
select new ProductViewModel()
{
ProductId = a.ProductId,
Product = a.Product,
Description = a.Description,
Image = a.Image,
Price = a.Price,
Clicks = a.Clicks,
Link = a.Link,
Site = b.Site,
Section = c.Section,
Affiliate = d.Affiliate
}).Single(x => x.ProductId == id);
return View(viewModel);
}
[HttpPost]
public ActionResult Edit(Product product)
{
...update database...do I pass in and save back to Product or my ProductViewModel
}
You use ViewModel to pass multiple models to the view, but when you save data, you need to save it to the appropriate model. If you are adding or modifying products, you will add items to products (using your DbContext). If you have one-to-many relationship defined between two models (in your Product.cs model you might have a property declared as:
public virtual ICollection<SomeOtherModel> SomeOtherData { get; set; }
you can use this to build a table instead of passing everything in a ViewModel. There is a nice tutorial here regarding the CRUD operations using EF4. Have a look at these short tutorials that can give you an idea about your strategy http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc.
I am building a personal Movie Catalogue and have the following structure:
Movie table/entity
MovieID (PK identifier) +
Other movie related properties
Person table/entity
PersonID (PK identifier) +
Other person related properties.
PersonMovie table/entity
MovieID (FK)
PersonID (FK)
Other columns containing information about what the person did on the movie (I.e. charactor name or job).
I want to have a view that allows a user to create/update a movie, or a person, and have a checkbox to then allow them to select existing or create new cast members (persons), or movies.
I am struggling on two fronts:
1) how to present this type of multi-page data collection. A movie has many cast members & a person can be involved in many movies.
2) how to update 2 or 3 of the tables above depending on what the user whats to enter. A user may want to add a movie but doesnt know the cast members yet or vice versa. A user may want to add a movie and add people who already exist as cast members of the movie.
Also I do not want cascading deletes and have struggled switching it off for the relationships between the above entities.
I can do this easily with webforms but am learning MVC 3 & Entity Framework 4 and am still getting my head around it all. I have looked around and haven't come across solutions/tutorials on what I would like to achieve.
Any help would be much appreciated.
Tony
I had a similar issue when I switched from another MVC framework (Rails as in ROR). For the starters, check out Leniency's reply on the similar question, that is; relationship-with-payload or non-PJT (pure-join-table) which unfortunately ASP.NET MVC3 doesn't support explicitly.
You can create a ModelView (a virtual entity) to wrap the collections of other entity types and pass it to the View. The aforementioned post has the detailed example with the code for Model, ViewModel, View, Partial and the Controller. (read both the answers on that post, my answer is continuation of Leniency's answer there)
Hope it helps!
Vulcan's on the right track, and my response that she linked too will help you get the model setup where the linking table contains extra data.
For building the views, you'll mostly likely find that ViewModels are the way to go for more complicated setup like you're describing, then your controller and service layer will deal with processing the view model data and translating it into EF entities. Viewmodels are built specifically to the view that you need, rather than trying to hammer a domain model into a view that may not fit it.
Here's a very rough start for one of the workflows for creating a movie, with an optional list of people.
Domain - your Movie and Person class, plus a linking table similar to what I described here.
View Models - Create a movie and attach people to it
public class MovieCreatePage
{
public MovieInput Input { get; set; } // Form field data...
public IEnumerable<People> People { get; set; } // list of people for drop downs
// ... other view data needed ...
}
public class MovieInput
{
[Required, StringLength(100)]
public string Name { get; set; }
// Easiest to just submit a list of Ids rather than domain objects.
// During the View Model -> Domain Model mapping, there you inflate them.
public int[] PeopleIds { get; set; }
// ... other input fields ...
}
Create.cshtml - just make a form for your view model.
Controller:
// NOTE! The parameter name here matches the property name from the view model!
// Post values will come across as 'Input.Name', 'Input.Year', etc...
// Naming the parameter the same as the view model property name will allow
// model binding. Otherwise, you'll need an attribute: [Bind(Prefix=".....")]
[HttpPost]
public ActionResult Create(MovieInput input)
{
if (ModelState.IsValid)
{
//
// Now do your mapping - I'd suggest Automapper to help automate it,
// but for simplicity, lets just do it manually for now.
var movie = new Movie
{
Name = input.Name,
Actors = input.PeopleIds != null
? input.PeopleIds.Select(id => new Person { Id = id })
: null
};
//
// Now save to database. Usually in a service layer, but again,
// here for simplicity
// First, attach the actors as stubbed entities
if (movie.Actors != null)
{
foreach (var actor in movie.Actors)
_db.People.Attach(actor); // Attach as unmodified entities
}
_db.Movies.Add(movie);
_db.SaveChanges();
TempData["Message"] = "Success!"; // Save a notice for a successful action
return RedirectToAction("Index");
}
// Validation failed, display form again.
return View(new MovieCreatePage
{
Input = input,
// ... etc ...
});
}
Hopefully this helps you some and points you in a good direction. It does, of course, bring up a lot of other questions that will just take time (ie, automapper, service layers, all the various EF gotcha's, etc...).
I have a SQL database with has the following: Customer, Item, Clothing and Food.
Item holds a key to Clothing or Food.
Item also holds a key to Customer. Therefore a customer can have an item, which may be of food or clothing.
I am using ADO.Net Entity Framework and have this generated automatically.
I currently have the following set-up: A person may enter their ID on the webpage and this is sent via a form post where the controller picks it up and queries the database using LINQ to get the customer. The customer view (details) is then returned. I can now see all the customer details etc.
However, what I want is to be able to see the items the customer has, the different food items and clothing items, but I am unsure how to do this. I also want to be able to allow the user to edit one field of the clothes and food items tables. Any idea how I would implement this?
Here is an ActionResult in my CustomerController:
public ActionResult Details(int id)
{
var cust = (from c in dataModel.Customers
where (c.MembershipID == id)
select c).First();
return View(cust);
}
I can also write cust.Items which is the entity which I want to display in the view with the customer (their items). How would I display this in the view also?
Hopefully this makes it a little more clear on what I am trying to achieve and how.
Thanks.
Using Entity Framework, if you're tables are linked properly with the right foreign keys and all that then your Customer entity should have a property that is a collection of Items.
You could also create your own strongly typed ViewModel that has a field for Customer and implement your own properties for Clothing and Food and populate those with another query.
This question was asked last night but its similar. The guy in the question wanted information to populate a dropdown passed in. You want something similar, not for a dropdown, but to fill in textboxes to edit. How to properly populate drop downs from ViewData in controller on multiple views in ASP.NET MVC
To create a ViewModel start by creating a new class and name it CustomerAndItemsViewModel, for example.
public class CustomerAndItemsViewModel
{
public Customer Customer { get; set; }
public IQueryable<Items> Items { get; set; }
}
public ActionResult Details(int id)
{
var cust = (from c in dataModel.Customers
where (c.MembershipID == id)
select c).First();
var items = (from i in dataModel.Items
where (i.MembershipID == cust.MembershipID)
select i;
return View(new CustomerAndItemsViewModel { Customer = cust, Items = items });
}
And don't forget that you will no longer be passing a Customer to your view. So you need to change the line at the top to something like:
#model Your.Path.To.CustomerAndItemsViewModel
Typically, if you want to pass back information that is not contained in just one of your entities, you have to create a class that encompasses more than one object. So, if you want a page that displays your customer information, and all their items (which they can then edit), you would need to have a the controller action pass back a "CustomerAndItems" object (or something similarly named). This object would hold a reference to the Customer as well as a collection of their Items. (You build the CustomerAndItems object within your Action.)
Then, your view would be strongly typed to CustomerAndItems, and you can then display each piece of information as you normally would.