This is my Movies controller.....
public class MoviesController : Controller
{
MoviesEntities db = new MoviesEntities();
public ActionResult Index()
{
var movies = from m in db.Films
where m.ReleaseDate > new DateTime(1989, 12, 20)
select m;
return View(movies.ToList());
}
public ActionResult Create()
{
return View();
}
[HttpPost]
public ActionResult Create(Film newFilm)
{
..some code for adding new movie in the database
}
}
and created Movie class in the model
namespace Movies.Models
{
[MetadataType(typeof(MovieMetadata))]
public partial class Movie
{
class MovieMetadata
{
[Required(ErrorMessage = "*")]
public string Title { get; set; }
[Required(ErrorMessage = "*")]
[Range(5, 100, ErrorMessage = "Movies cost between $5 and $100.")]
public decimal Price { get; set; }
}
}
}
This should give me proper validations.. but the range is not working..
also... they are getting added into database
[HttpPost]
public ActionResult Create(Film newFilm)
{
if (ModelState.IsValid)
{
..some code for adding new movie in the database
}
}
Do this. And with regard to the comment of Aman who is saying or JQuery validation. Clientside validation cannot be a replacement for serverside validation. So always use the ModelState validation next to clientside.
Related
I'm trying to list the items from my database into my view but I'm getting null back.
I know the connection must be working to a certain extent because in my database the tables didn't exist but once I ran my program it did create the tables. However when I add content into my table my view still returns NULL.
Also, haven't touched the Review table yet, just worried about getting Restaurants working.
Restaurant.cs
namespace OdeToFood.Models
{
public class Restaurant
{
public int Id { get; set; }
public string Name { get; set; }
public string City { get; set; }
public string Country { get; set; }
public ICollection<RestaurantReview> Reviews { get; set; }
}
}
OdeToFood.cs
namespace OdeToFood.Models
{
public class OdeToFoodDb : DbContext
{
public DbSet<Restaurant> Restaurants { get; set; }
public DbSet<RestaurantReview> Reviews { get; set; }
}
}
Controller
OdeToFoodDb _db = new OdeToFoodDb();
public ActionResult Index()
{
var model = _db.Restaurants.ToList();
return View();
}
Index.cshtml
#model IEnumerable<OdeToFood.Models.Restaurant>
#{
ViewBag.Title = "Home Page";
}
#{
if (Model != null)
{
foreach (var item in Model)
{
<div>
<h4>#item.Name</h4>
<div>#item.City, #item.Country</div>
<hr />
</div>
}
}
else
{
<h1>Null</h1>
}
}
You need to pass to model back to the view.
OdeToFoodDb _db = new OdeToFoodDb();
public ActionResult Index()
{
var model = _db.Restaurants.ToList();
return View(model);
}
You never actually send the model to the view. Pass it as an argument:
OdeToFoodDb _db = new OdeToFoodDb();
public ActionResult Index()
{
var model = _db.Restaurants.ToList();
return View(model);
}
Additionally, it's generally a good idea not to create database contexts in a shared scope. Keep the context as close to where it's used as possible and only expand its scope when you really need to. Something like this:
public ActionResult Index()
{
using (var _db = new OdeToFoodDb())
{
var model = _db.Restaurants.ToList();
return View(model);
}
}
Database contexts/connections in a shared scope is just asking for problems unless you pay close attention to what you're doing. As the code gets more complex, it becomes more likely that other methods will try to use it and it may be in an unknown state at that time.
How to correctly save to database? I have the following but not working. I am using a custom ModelMetadata (ORDERMetadata) and setting it equal to the .edmx / order.cs model and trying to save it.
The key field in Order.cs model is [OrderID], but I am passing [model.Order_Number] which is unique value. I am currently, not passing [OrderID] in ORDERMetadata model. Is this required?
Order.cs:
public partial class ORDER
{
public int OrderID { get; set; }
public int Order_Number { get; set; }
public string Order_Type { get; set; }
}
ORDERMetadata model:
[MetadataType(typeof(ORDERMetadata))]
public partial class ORDER
{
// Blank. It's just here to add the class-level attribute.
}
public class ORDERMetadata
{
[Display(Name = "Order Number")]
public int Order_Number { get; set; }
[Display(Name = "Order Type")]
public string Order_Type { get; set; }
}
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(ORDERMetadata model)
{
if (!ModelState.IsValid)
{
return View(model);
}
try
{
// update order
ORDER order = new ORDER();
order.Order_Number = model.Order_Number;
order.Order_Type = model.Order_Type;
db.Entry(order).State = EntityState.Modified;
db.SaveChanges();
ViewBag.UpdateResult = "Order updated!";
return View();
}
}
Change to:
ORDER order = db.ORDERS.SingleOrDefault(p => p.Order_Number == model.Order_Number);
I have a database with a table users. I generate the EF .edmx from the database and I can then access the users via:
public ActionResult Index()
{
var obj = context.Users.ToList();
return View(obj);
}
Which is fine my problem is that when I do the edit:
public ActionResult Edit(Guid id)
{
var obj = context.Users.Where(c => c.UserId == id).SingleOrDefault();
return View(obj);
}
I have no idea how to access the User model to add validation message? I was hoping to see something like:
public class User
{
[Required]
[Display(Name = "username")]
public string UserName { get; set; }
{
But I don't and I'm novice and don't really understand how to access / edit this model when generate from a database. Any advice tutorials would be appreciated.
see if u were using code first u could have used what user MISHA has suggested, u r using database first (as u are generating edmx from DB). In this case for mvc-validation to hook automatically- you have provide model's metadata.
You can create a metadata as below
namespace Your_Models_NameSpace
{
[MetadataType(typeof(UserMetaData))]
public partial class User
{
public class UserMetaData
{
[DisplayName("User Name")]
[Required(ErrorMessage = "Please provide a valid username")]
public object UserName { get; set; }
}
}
}
What you can do is, in the same namespace as your model, create a partial class with metadata like so:
[MetadataType(typeof(IPConfigMetadata))]
public partial class IPConfig
{
internal sealed class IPConfigMetadata
{
private IPConfigMetadata() { }
[RegularExpression(#"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b", ErrorMessage = "Must be a valid IP Address")]
public string CommanderIP { get; set; }
[Range(1024, 65535)]
public int IPPort { get; set; }
}
}
Check this post.
You could do something like:
public class User
{
[Required(ErrorMessage = "Username is required")]
public string UserName { get; set; }
{
Then in your action you would do:
public ActionResult Edit(User user)
{
if(ModelState.IsValid)
{
// Save user
}
return View(user);
}
EF4.1-Code-First-Gurus!
I wonder if there is a more elegant way to handle the following ASP.NET MVC 3 EF 4.1 Code First scenario: Lets say we have the following POCOs:
public class Entity
{
[Key]
public int Id { get; set; }
[ScaffoldColumn(false)]
public DateTime CreatedOn { get; set; }
[ScaffoldColumn(false)]
public DateTime ModifiedOn { get; set; }
}
and
public class Person : Entity
{
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime Birthday { get; set; }
}
Lets assume we have created some standard editing views, which are not including CreatedOn/ModifiedOn fields, because, they will be set in the repository and not by the user.
In my repository I have the following Update method. The methods excepts a list of fields, which should be updated (leaving CreatedOn/ModifiedOn fields out):
public void Update(Person person, List<string> properties)
{
Person tmpPerson = context.People.Single(x => x.Id == person.Id);
context.People.Attach(tmpPerson);
foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(person))
{
if (properties.Contains(descriptor.Name))
descriptor.SetValue(tmpPerson, descriptor.GetValue(person));
}
tmpPerson.ModifiedOn = DateTime.Now;
}
Now the controller is calling this method like this:
[HttpPost]
public ActionResult Edit(Person person)
{
if (ModelState.IsValid) {
personRepository.Update(person, new List<string> { "FirstName", "LastName", "Birthday"});
personRepository.Save();
return RedirectToAction("Index");
} else {
return View();
}
}
This all works like a charm. However, I really dislike, that I have to specify the fields manually. How would you handle this requirement? Of course I could add CreatedOn/ModifiedOn fields as hidden fields to the view, but I dont want to bload the form to much (There are much more fields).
Maybe this is a similar question:
How To Update EF 4 Entity In ASP.NET MVC 3?
I highly appreciate your help!
Joris
Yes there is more elegant version:
public void Update(Person person, params Expression<Func<Person,object>>[] properties)
{
context.People.Attach(person);
DbEntityEntry<Person> entry = context.Entry(person);
foreach (var property in properties)
{
entry.Property(property).IsModified = true;
}
person.ModifiedOn = DateTime.Now;
}
You will call the method this way:
[HttpPost]
public ActionResult Edit(Person person)
{
if (ModelState.IsValid)
{
personRepository.Update(person, p => p.FirstName,
p => p.LastName, p => p.Birthday);
personRepository.Save();
return RedirectToAction("Index");
}
else
{
return View(person);
}
}
I am trying to edit a record. I have the default route.
When I click the submit button I get an exception on the UpdateModel line:
The model of type 'MyProject.Mvc.Models.Product' could not be updated.
On the page the validation of the ProductId field is prompting the value is invalid:
The value '9' is invalid. 9 is the id of the record I am trying to edit. What could be wrong?
public ActionResult Edit(int id)
{
Product product = productRepository.GetProduct(id);
return View(new ProductFormViewModel(product));
}
[HttpPost]
public ActionResult Edit(int id, FormCollection productFormViewModel)
{
Product product = productRepository.GetProduct(id);
try
{
// TODO: Add update logic here
UpdateModel(product, "Product");
productRepository.Save();
return RedirectToAction("Index");
}
catch (Exception ex)
{
return View(new ProductFormViewModel(product));
}
}
If I change the update model line to:
UpdateModel(product);
then no exception is thrown and the data is not updated in the database.
[Edit]
I am using Entity Framework
namespace MyProject.Mvc.Models
{
[MetadataType(typeof(ProductMetaData))]
public partial class Product
{
public Product()
{
// Initialize Product
this.CreateDate = System.DateTime.Now;
}
}
public class ProductMetaData
{
[Required(ErrorMessage = "Product name is required")]
[StringLength(50, ErrorMessage = "Product name must be under 50 characters")]
public object ProductName { get; set; }
[Required(ErrorMessage = "Description is required")]
public object Description { get; set; }
}
public class ProductFormViewModel
{
public Product Product { get; private set; }
public ProductFormViewModel()
{
Product = new Product();
}
public ProductFormViewModel(Product product)
{
Product = product;
}
}
}
Do you need to edit the ID? if the ID is the PK of the product in your table then it could be a binding issue.
Try
[MetadataType(typeof(ProductMetaData))]
[Bind(Exclude="ID")]
public partial class Product
{
public Product()
{
// Initialize Product
this.CreateDate = System.DateTime.Now;
}
}
could you post your Model source code? does model have fields of class you want to update or just this class as object(Product)?
the problem could exists becouse when your model has object Product, you should pass to UpdateModel method prefix with name of the class...
The problem with UpdateModel(product, "Product"); is that you are using the same prefix (Product) as the Product class name. Try using a different prefix. For this you might need to rename the Product property of the ProductFormViewModel class.