I am trying to add multiple rows of data and pass it to the table in database along with another item to a different table. Below is the struct of the databse:
User Table
userid
name
Movie Table
Movieid
userid
moviename
Cinema Table
Movieid
cinemaid
location
time
The movietable has 1 to many realtionship with the Cinema table. The user table has one I have four different viewmodels associating to them:
UserViewModel
{
public int userid;
public string name;
}
MoviewViewModel
{
public int movieid;
public int userid;
public string moviename;
public List<CinemaViewModel> cinema;
}
CinemaViewModel
{
public int movieid;
public int cinemaid;
public string location;
public string time;
}
UserandMovieViewModel
{
public List<MoviewViewModel> movie;
public UserViewModel user;
}
I am passing the userandmoviewmodel from the controller create to the view and would like to add one entry for user and movie, but would like to add multiple entries to the Cinema database from that single page. it works fine when i add a single entry to cinema. however i would like to have the ability to add multiple entries to cinema table when form is posted. I have tried the tutorial below but that doesnt seem to work for create.
http://ivanz.com/2011/06/16/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-1/
EDIT
The code which give null exception
<ul id="movieEditor" style="list-style-type: none">
#foreach (CinemaViewModel cinemamodel in Model.UserandMovieViewModel.cinema) {
Html.RenderPartial("MovieEntryEditor", cinemamodel);
}
</ul>
<a id="addAnother" href="#">Add another</a>
EDIT2
The create controller code
[httpget]
public ActionResult Create()
{
UserViewModel usermodel = new UserviewModel();
List<MovieViewModel> moviemodel= new List<MovieViewModel>();
UserandMovieViewModel model = new UserandMovieViewmodel{user = usermodel, movie=moviemodel }
return View(model)
}
[httppost]
public ActionResult Create(UserandMovieViewmodel model)
{
IRepository<User> userrep = new ApplicationRepository<User>();
IRepository<Movie> userrep = new ApplicationRepository<Movie>();
IRepository<Cinema> userrep = new ApplicationRepository<Cinema>();
User user = null;
Movie movie = null;
Cinema cinema = null;
UserViewModel usermodel = model.usermodel;
MovieViewModel moviemodel= model.moviemodel;
CinemaViewModel cinemamodel = model.moviemodel.cinema;
if(ModelState.valid)
{
user = new user();
user.name = usermodel.name;
userrep.add(user);
movie = new movie();
movie.userid = user.userid; (gets from database as its autoappend)
movie.moviename = moviemodel.moviename;
movierep.Add(movie);
cinema = new cinema();
cinema.movieid = movie.movieid;
cinema.location = cinemamodel.location;
cinema.time = cinemamodel.time;
cinemarep.Add(cinema);
}
return View(model);
}
I have written the code from memory as i dont currently have it. Please correct any errors you see.
EDIT 3
Partial View
#model Application.ViewModels.CinemaViewModel
<li style="padding-bottom:15px">
<div style="width: 450px; float: left;">
<label class="location">
Location
</label>
<span style="margin-left: 26px;">
#Html.TextBoxFor(model => model.location)
#Html.ValidationMessageFor(model => model.location)
</span>
<span>
#Html.TextBoxFor(model => model.time)
#Html.ValidationMessageFor(model => model.time)
</span>
</div>
I suspect that you have your list as null, so you can try just to new it up in constructor:
public class MoviewViewModel
{
public MoviewViewModel(){
cinema = new List<CinemaViewModel>();
}
public int movieid;
public int userid;
public string moviename;
public List<CinemaViewModel> cinema;
}
public class UserandMovieViewModel
{
public UserandMovieViewModel(){
movie = new List<MoviewViewModel>();
}
public List<MoviewViewModel> movie;
public UserViewModel user;
}
EDIT:
Your view:
<ul id="movieEditor" style="list-style-type: none">
#if(Model.UserandMovieViewModel.cinema.Any())
{
foreach (CinemaViewModel cinemamodel in Model.UserandMovieViewModel.cinema) {
Html.RenderPartial("MovieEntryEditor", cinemamodel);
}
}
else
{
#{ Html.RenderPartial("MovieEntryEditor", new CinemaViewModel()) };
}
</ul>
<a id="addAnother" href="#">Add another</a>
Related
I have a controller that return a List of Messages
public ActionResult MainMenu()
{
var myDataOp = new DataBaseOperations();
var Message=myDataOp.GetMessages();
return View(Message);
}
Here is the Function That gets the List
public List<ViewClass> GetMessages()
{
PrincelysDataContext pData = new PrincelysDataContext();
Princelys.Models.ViewClass myViewList =new ViewClass();
var myMessage =from r in pData.Messages select r;
DateTime presentTime = new DateTime();
foreach (var myValues in myMessage)
{
myViewList.myMessage.Add(new ViewClass
{
CreatedName ="ffff",// (from m in pData.Users where m.userid == myValues.createdBy select m.userName).Single(),
Messages = myValues.Message,
CreateOn = myValues.createddatetime.Subtract(presentTime)
});
}
return myViewList.myMessage;
}
I then use my list in the View Page.
#model Princelys.Models.ViewClass
....
#foreach (var messageValues in Model.myMessage)
{
<li class="left clearfix">
<span class="chat-img pull-left">
<img src="http://placehold.it/80/30a5ff/fff" alt="User Avatar" class="img-circle" />
</span>
<div class="chat-body clearfix">
<div class="header">
<strong class="primary-font">#messageValues.CreatedName</strong> <small class="text-muted">#messageValues.CreateOn.TotalHours mins ago</small>
</div>
<p>
#messageValues.Messages
</p>
</div>
</li>
}
I get an error when I run the view page on a browser
The model item passed into the dictionary is of type 'System.Collections.Generic.List`1[Princelys.Models.ViewClass]', but this dictionary requires a model item of type 'Princelys.Models.ViewClass'.
This is the class that hold the properties
public class ViewClass
{
public ViewClass()
{ myMessage = new List<ViewClass>(); }
public string CreatedName { get; set; }
public string Messages { get; set; }
public TimeSpan CreateOn { get; set; }
public List<ViewClass> myMessage;
}
This is my first MVC 5 project. Any help would be greatly appreciated.
You are returning List<ViewClass> in your controller action, however looks like your view is strongly typed with ViewClass. Change it to #model IEnumerable<ViewClass> Or other way round i.e. return ViewClas from controller.
Based on the comments the issue is GetMessages should return ViewClass so it should look like below
public ViewClass GetMessages()
{
PrincelysDataContext pData = new PrincelysDataContext();
Princelys.Models.ViewClass myViewList =new ViewClass();
var myMessage =from r in pData.Messages select r;
DateTime presentTime = new DateTime();
foreach (var myValues in myMessage)
{
myViewList.myMessage.Add(new ViewClass
{
CreatedName ="ffff",// (from m in pData.Users where m.userid == myValues.createdBy select m.userName).Single(),
Messages = myValues.Message,
CreateOn = myValues.createddatetime.Subtract(presentTime)
});
}
return myViewList;
}
You are passing a List to the view, but your view is strongly typed to a single member of that list. Try changing this in your model:
#model List<ViewClass>
So I have two models, Product and Review. The Product model contains a navigation property called Review as seen below:
Public class Product
{
[HiddenInput(DisplayValue=False])
public int ProductID {get; set;}
[Required]
public string ProductName {get; set;}
[HiddenInput(DisplayValue=False)
public ICollection<Reviews> {get; set;}
}
The the Review model:
public class Review
{
[HiddenInput(DisplayValue=false)]
public int ReviewId { get; set; }
[Required]
public int ProductID { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string Subject { get; set; }
[Required]
public string Body { get; set; }
}
I have an Action ViewResult method for ProductDetails where it fetches all Products plus all the reviews which has the same FK ProductIDs as seen here below:
public ViewResult ProductDetails(int productId)
{
Product product = repository.Products
.Include(p => p.Reviews)
.FirstOrDefault(p => p.ProductID == productId);
return View(product);
}
Then there is a View Which contains very simple HTML elements you can see it below:
#model app.models.Product
#Html.DisplayFor(model => model.ProductName)
#foreach (var review in Model.Reviews)
{
#Html.Partial("_Reviews", review)
}
Within above view I called for a partial view to render all reviews belong to that specific product. In the Partial view i have a form where the user can submit a review. I want the user to submit a review for the Product which the name is at the top of the view. I know i have to create an action for this but the only thing makes me uncomfortable with it is that i can't figure out how to get the ProductID of that specific Product.
Edit:
As per Stephen's answer I had to put the form Html elements into the main view which is ProducDetails and had put some scripts to call Json result to save data in the database.
Controller method to save the Review:
[HttpPost]
public JsonResult CreateReview (Review review)
{
if (review.ReviewId == 0)
{
db.Reviews.Add(review);
}
else
{
Review dbEntry = db.Reviews.Find(review.ReviewId);
if (dbEntry != null)
{
dbEntry.ProductID = review.ProductID;
dbEntry.Name = review.Name;
dbEntry.Subject = review.Subject;
dbEntry.Body = review.Body;
}
}
db.SaveChanges();
return Json(true);
}
You're wanting to create a new Review for the Product so the form needs to be in the main view, not the partial. The following assumes you want to submit using ajax and update the list of existing reviews
#model app.models.Product
#Html.DisplayFor(model => model.ProductName)
// display existing reviews
<div id="reviews">
#foreach (var review in Model.Reviews)
{
#Html.DisplayFor(m => review.Body)
}
</div>
<h2>Create new Review</h2>
#Html.Partial("_NewReview", new Review(){ ProductID = Model.ProductID })
Where _NewReview.cshtml is
#model Review
#using (Html.BeginForm())
{
#Html.HiddenFor(m => m.ProductID)
#Html.EditorFor(m => m.Name)
#Html.EditorFor(m => m.Subject)
#Html.TextAreaFor(m => m.Body)
<input id="create" type="submit" value="Create" />
}
and delete the _Reviews.cshtml file
Then in the main view, add the following script
var url = '#Url.Action("Create", "Review")';
var reviews = $('#reviews');
var form = $('form');
$('#create').click(function() {
$.post(url, form.serialize(), function(response) {
if (response) {
reviews.append($('#Body').val()); // add the new Review to the existing reviews
form.get(0).reset(); // reset the form controls
}
}).fail(function (result) {
// oops
});
return false; // cancel the default submit
});
which will submit to (in ReviewController)
[HttpPost]
public JsonResult Create(Review model)
{
// Save the model
return Json(true); // return something to indicate success
}
As i can imagine ProductId is unique
In Your Partial View you can Write your code inside Ajax.BeginForm
#model Review
#Ajax.BeginForm("ActionName", "ControllerName", new { productId = Model.ProductId }, #*AjaxOptions Attribute*#)
{
Review Fields here
<input type="submit" value="Submit Review"/>
}
To get the ProductID, you have add the ForeignKey of the Product Table in the Review Table.
public class Review
{
[HiddenInput(DisplayValue=false)]
public int ReviewId { get; set; }
[Required]
public int ProductID { get; set; }
[Required]
[ForeignKey("ProductID")]
publiv virtual Product {get;set;}
}
hope this helps
I am currently working on an assignment at university from which I unfortunatly lost some code to not long ago.
In particular it is where I have specific products display to a specific store, the code I have is not working
at all for me now, help would be appreciated
I have a web service and a local database in place from which the web service brings in the product information
and the local information has the store data and the store grade data.
Here is the code that I have in place for it to display on the details view page.
#model Part1MVC.ViewModels.GradeProductVM
#{
ViewBag.Title = "Details";
}
<h2>Details</h2>
<fieldset><legend>GradeProductVM</legend>
<div class="display-label">#Html.DisplayNameFor(model => model.Gradeid)</div>
<div class="display-field">#Html.DisplayFor(model => model.Gradeid)</div>
<div class="display-label">#Html.DisplayNameFor(model => model.GradeName)</div>
<div class="display-field">#Html.DisplayFor(model => model.GradeName)</div>
</fieldset>
<div>There are #Model.Products.Count products</div>
#foreach (var prod in Model.Products) { <div>#prod.ProductName</div>}
<p>#Html.ActionLink("Edit", "Edit", new { id=Model.Gradeid }) |
#Html.ActionLink("Back to List", "Index")</p>
// This is the code for service1.cs to get grades product
public List<PhysicalProduct> GetProductsForGrade(int gradeid){
var list = new List<PhysicalProduct>();
try {
using (var db = new ProductsEntities()) {
var q = from prod in db.PhysicalProducts
join pg in db.ProductToGrades on prod.ProductId equals pg.ProductId
where pg.StoreGradeId == gradeid
select prod;
return q.ToList();
}
}
catch (Exception ex) {
return null;
}
return list;
}
////This is the controller code
public ActionResult Details(int id){
Grade grade = db.Grade.SingleOrDefault(x => x.GradeId == id);
//var products = ServiceLayer.GetProducts();
var products = ServiceLayer.GetProductsForGrade(id);
var vm = new ViewModels.GradeProductVM(id, grade.Description, products);
return View(vm);
}
//This is the View model Code
public class GradeProductVM {
public int Gradeid { get; set; }
public string GradeName { get; set; }
public List<PhysicalProduct> Products { get; set; }
public GradeProductVM() {
}
public GradeProductVM(int gradeid, string name, List<PhysicalProduct> prods){
Gradeid = gradeid;
GradeName = name;
Products = prods;
}
}
I can get all the products that are currently in the database to display to every store but not specific products to specific stores.
Thanks
Please post the database table structure, seems the query join may be wrong.
Rest seems correct!
I'm brand new to ASP.NET MVC, and I would appreciate any help with my question. I already did plenty of research (not enough apparently) on this topic. I need to bind a dropdownlist to a specific column in a table and then render it in the view. I already have the query to retrieve the table in the controller:
public ActionResult SelectAccountEmail()
{
var queryAccountEmail = (from AccountEmail in db.UserBases select AccountEmail)
var selectItems = new SelectList(queryAccountEmail);
return View(selectItems);
}
I get lost when it come to binding the query to a dropdownlist in the view.
#model RecordUploaderMVC4.Models.UserBase
#{
ViewBag.Title = "SelectAccountEmail";
}
<h2>SelectAccountEmail</h2>
#Html.LabelFor(model => model.AccountEmail);
#Html.DropDownList(Model.AccountEmail);
#Html.ValidationMessageFor(model => model.AccountEmail);
<input /type="submit" value="Submit">
I get this error when I run it:
Server Error in '/' Application.
--------------------------------------------------------------------------------
The model item passed into the dictionary is of type 'System.Web.Mvc.SelectList', but this dictionary requires a model item of type 'RecordUploaderMVC4.Models.UserBase'.
Any help will be appreciated.
Thanks in advance.
Few things wrong. Firstly, change your model to add the following properties (Looking at your view, it's RecordUploaderMVC4.Models.UserBase):
public class UserBase
{
public string AccountEmail { get; set; }
public SelectList Emails { get; set; }
//rest of your model
}
Then, build your model in your controller properly:
public ActionResult SelectAccountEmail()
{
UserBase model = new UserBase();
var queryAccountEmail = (from AccountEmail in db.UserBases select AccountEmail)
model.Emails = new SelectList(queryAccountEmail);
return View(model);
}
Then in your view you can do:
#Html.LabelFor(model => model.AccountEmail)
#Html.DropDownListFor(model => model.AccountEmail, Model.Emails)
#Html.ValidationMessageFor(model => model.AccountEmail)
Step 1:
First Create a model Like this to hold your ListofAccountEmail
public class AccountEmailViewModel
{
public int AccountEmailId { get; set; }
public string AccountEmailDescription { get; set; }
}
Step 2: Create your model class
public class UserBaseViewModel
{
public IEnumerable<SelectListItem> AccountEmail { get; set; }
public string AccountEmail { get; set; }
}
Step 3 :
In Controller
[HttppGet]
public ActionResult SelectAccountEmail()
{
var EmailAccounts = (from AccountEmail in db.UserBases select AccountEmail)
UserBase userbaseViewModel = new UserBase
{
AccountEmail = EmailAccounts.Select(x => new SelectListItem
{
Text = x.AccountEmailDescription,
Value = Convert.ToString(x.AccountEmailId)
}).ToList()
};
return View(userbaseViewModel);
}
Step 4 : In View
#model RecordUploaderMVC4.Models.UserBase
#{
ViewBag.Title = "SelectAccountEmail";
}
<h2>SelectAccountEmail</h2>
#Html.ValidationSummary()
<h2>SelectAccountEmail</h2>
#Html.LabelFor(model => model.AccountEmail )
#Html.DropDownListFor(x => x.AccountEmailId, Model.AccountEmail, "Please Select", "")
</div>
<input /type="submit" value="Submit">
I am using C# in ASP MVC3. I have two tables from SQL Server.Table names are SMS_User and SMS_Division in SQL Server 2008. When i create a new user, I want to show division id from sms_division table.
SMS_User contains UserName, DivisionID, EmailAddress
SMS_Division contains DivisionID, DivisionName.
Controller Code :
UserController : Controller
{
private NetPerfMonEntities2 db = new NetPerfMonEntities2();
IEnumerableZamZam= db.SMS_Division.Select(c => new SelectListItem { Value = c.divisionid.ToString(), Text = c.divisionid.ToString() } );
}
When I create a new user in User Create() VIEW I want to show a DivisonName as a dropdown list instead of a text box. How I do that ?
#Html.DropDownListFor(model => model.divisionid, (IEnumerable<SelectListItem>) ViewData["Divisions"], "<--Select a divison-->")
#Html.ValidationMessageFor(model => model.divisionid)
I have this error message :
CS0103: The name 'sms_amountlimit2' does not exist in the current context
I'll be assuming a few missing part of your question in my answer, and give you a generic pattern to have a working dropdown list in ASP.NET MVC 3 :
Let's start with the models :
UserModel would be the class representing the data extracted from sms_user
public class UserModel
{
public string Username { get; set; }
public string EmailAddress { get; set; }
public int DivisionId { get; set; }
}
DivisionModel would be the class representing the data extracted from sms_division
public class DivisionModel
{
public int DivisionId { get; set; }
public string DivisionName { get; set; }
}
By Extracted, I mean anything that can transform the data in your Database in instanciated classes. That can be an ORM (EntityFramework or others), or SQL Queries, etc...
Next, is the viewmodel, because it wouldn't make sense to plug an IEnumerable of divisions in UserModel, and I personally don't really like using ViewData when I can avoid it :
public class UserViewModel
{
public UserModel User { get; set; }
public IEnumerable<DivisionModel> Divisions {get; set;}
}
Next, the controller :
public class UserController : Controller
{
public ActionResult Create()
{
List<DivisionModel> divisions = new List<DivisionModel>();
divisions.Add(new DivisionModel() { DivisionId = 1, DivisionName = "Division1" });
divisions.Add(new DivisionModel() { DivisionId = 2, DivisionName = "Division2" });
UserModel user = new UserModel() { Username = "testUser", EmailAddress = "testAddress#test.com" };
return View(new UserViewModel() { User = user, Divisions = divisions });
}
}
I just create the Division list and the user, but you would get then from you database by any means you are using.
And finally the View :
#model ViewModels.UserViewModel
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
<p>
#Html.DropDownListFor(model => model.User.DivisionId, new SelectList(Model.Divisions, "DivisionId", "DivisionName"), "-- Select Division --")
#Html.ValidationMessageFor(model => model.User.DivisionId)
</p>
Note that the model binded to the view is the ViewModel.
In your model add a collection of the divisions then create the dropdown list like below:
#Html.DropDownListFor(m => m.SelectedDivisionId,
new SelectList(Model.Divisions, "DivisionId", "DivisionName"),
"-- Select Division --")