I am pretty new to MVC and I am building a small contacts app. I have created the database and the Index page displays the data for the DB fine. The Issue I have is my details page. It will display the titles but wont show any data.
Here is my Model:
namespace BCM.Models
{
using System;
using System.Collections.Generic;
public partial class Contact
{
public int Id { get; set; }
public string FirstName { get; set; }
public string Surname { get; set; }
public string CompanyName { get; set; }
public string Address { get; set; }
public string Address2 { get; set; }
public string Address3 { get; set; }
public string City { get; set; }
public string County { get; set; }
public string Country { get; set; }
public string PostCode { get; set; }
public string Telephone { get; set; }
public string Telephone1 { get; set; }
public string Telephone2 { get; set; }
public string Telephone3 { get; set; }
public string Telephone4 { get; set; }
public string Email { get; set; }
public string Email2 { get; set; }
public string Website { get; set; }
public string Notes { get; set; }
}
}
Here is my controller:
public ActionResult Details()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Contact contact = db.Contacts.Find(id);
if (contact == null)
{
return HttpNotFound();
}
return View(contact);
}
And here is a section of my View:
#model BCM.Models.Contact
#{
ViewBag.Title = "Details";
}
<h2>Details</h2>
<div>
<h4>Contact</h4>
<hr />
<dl class="dl-horizontal">
<dt>
#Html.DisplayNameFor(model => model.FirstName)
</dt>
<dd>
#Html.DisplayFor(model => model.FirstName)
</dd>
<dt>
#Html.DisplayNameFor(model => model.Surname)
</dt>
<dd>
#Html.DisplayFor(model => model.Surname)
</dd>
<dt>
#Html.DisplayNameFor(model => model.CompanyName)
</dt>
<dd>
#Html.DisplayFor(model => model.CompanyName)
</dd>
This is what my details page shows:
enter image description here
Thanks in advance
Managed to work out what I was missing. It was to do with my #Html.ActionLink not passing through the Id
Related
I have following code in my Details View of Entity A
<dt>
#Html.DisplayNameFor(model => model.User1.UserName)
</dt>
<dd>
#Html.DisplayFor(model => model.User1.UserName)
</dd>
I want to change their title that is shown in Details View
it is showing UserName where i want it to be Submitted by
it cant be overloaded because DisplayName For donot have any overloaded function with two params
#Html.DisplayFor(model => model.User1.UserName,"Submitted By") Not working
any Help
Here is my Model of Bugs Where i have Fields of Assigned to and submitted by which are related to the users model so i am having problem that "UserName" is shown at the place of column Name where it should show the Names as "Assigned To" and "Submitted By"
public partial class Bug
{
public int ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Priority { get; set; }
public string Severity { get; set; }
public string Status { get; set; }
public int AssignedTo { get; set; }
public int SubmittedBy { get; set; }
public int ComponentID { get; set; }
public int ProjectID { get; set; }
public System.DateTime DueDate { get; set; }
public Nullable<int> BugNumber { get; set; }
public string NormalFlow { get; set; }
public System.DateTime CreationDate { get; set; }
public virtual Component Component { get; set; }
public virtual Project Project { get; set; }
public virtual User User { get; set; }
public virtual User User1 { get; set; }
}
You can control the displayed text via the [Display] attribute on your model. In your case you'd want to set the attribute on the underlying model for User1:
public class User
{
[Display(Name = "Submitted By")]
public string UserName;
}
See https://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.displayattribute.name%28v=vs.110%29.aspx for more details on the DisplayAttribute class.
As long as you want to change the displayed text of a label no need to change your model..
just edit your Razor View like this:
<dt>
#Html.DisplayName("Submitted By")
</dt>
<dd>
#Html.DisplayFor(model => model.User1.UserName)
</dd>
OR
<dt>
Submitted By
</dt>
<dd>
#Html.DisplayFor(model => model.User1.UserName)
</dd>
Here is one that is working for me.
#Html.LabelFor(model => model.category_type_id, "Category Type", htmlAttributes: new { #class = "control-label col-md-2" })
I am new to MVC and would appreciate any advice. I have several models/tables that work together. The trouble I am having is with a many-to-many relationship. What I want is to have a listbox that a user can multiselect from and pass those values to save in join table, while saving the primary entry to another table.
My models:
public class Card
{
public virtual int CardID { get; set; }
public virtual string Title { get; set; }
//A bunch of properties...
//Drop Down Lists
public int RarityID { get; set; }
public virtual Rarity Rarity { get; set; }
public int MainTypeID { get; set; }
public virtual MainType MainType { get; set; }
public int CardSetID { get; set; }
public virtual CardSet CardSet { get; set; }
public int SubTypeID { get; set; }
public virtual SubType SubType { get; set; }
public virtual string AdditionalType { get; set; }
public virtual IList<CardAbility> Abilities { get; set; }
public virtual int[] SelectedAbilities { get; set; }
}
public class Ability
{
public virtual int AbilityID { get; set; }
public virtual string Title { get; set; }
public virtual IList<CardAbility> Cards { get; set; }
}
public class CardAbility
{
public int CardAbilityID { get; set; }
public virtual Ability Ability { get; set; }
public int AbilityID { get; set; }
public virtual Card Card { get; set; }
public int CardID { get; set; }
}
My Controller:
public ActionResult Create()
{
ViewBag.RarityID = new SelectList(db.Rarities, "RarityID", "Title");
ViewBag.MainTypeID = new SelectList(db.MainTypes, "MainTypeID", "Title");
ViewBag.CardSetID = new SelectList(db.CardSets, "CardSetID", "Title");
ViewBag.SubTypeID = new SelectList(db.SubTypes, "SubTypeID", "Title");
ViewBag.Abilities = new MultiSelectList(db.Abilities, "AbilityID", "Title");
return View();
}
// POST: /Card/Create
[HttpPost]
public ActionResult Create(Card card)
//[ModelBinder(typeof(CardBinder1))]
{
if (ModelState.IsValid)
{
db.Cards.Add(card);
db.SaveChanges();
foreach (var items in card.SelectedAbilities)
{
var obj = new CardAbility() { AbilityID = items, CardID = card.CardID };
db.CardAbilities.Add(obj);
}
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.RarityID = new SelectList(db.Rarities, "RarityID", "Title", card.RarityID);
ViewBag.MainTypeID = new SelectList(db.MainTypes, "MainTypeID", "Title", card.MainTypeID);
ViewBag.CardSetID = new SelectList(db.CardSets, "CardSetID", "Title", card.CardSetID);
ViewBag.SubTypeID = new SelectList(db.SubTypes, "SubTypeID", "Title", card.SubTypeID);
ViewBag.Abilities = new MultiSelectList(db.Abilities, "AbilityID", "Title");
return View(card);
My Create View:
model MTG.Models.Card
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Card</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Title)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Title)
#Html.ValidationMessageFor(model => model.Title)
</div>
<div class="editor-label">
#Html.Label("Abilities")
</div>
<div class="editor-field">
#Html.ListBoxFor(model => model.Abilities, (ViewBag.AbilityID as MultiSelectList))
#Html.ValidationMessageFor(model => model.Abilities)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.RarityID, "Rarity")
</div>
<div class="editor-field">
#Html.DropDownList("RarityID", String.Empty)
#Html.ValidationMessageFor(model => model.RarityID)
</div>
// A lot more fields...
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
My DBContext:
public DbSet<Ability> Abilities { get; set; }
public DbSet<Rarity> Rarities { get; set; }
public DbSet<CardSet> CardSets { get; set; }
public DbSet<MainType> MainTypes { get; set; }
public DbSet<SubType> SubTypes { get; set; }
public DbSet<Card> Cards { get; set; }
public DbSet<CardAbility> CardAbilities { get; set; }
public class AbilitiesToCardsConfiguration : EntityTypeConfiguration<CardAbility>
{
internal AbilitiesToCardsConfiguration()
{
this.HasKey(p => new { p.AbilityID, p.CardID });
this.HasRequired(p => p.Ability)
.WithMany(p => p.Cards)
.HasForeignKey(p => p.AbilityID);
this.HasRequired(p => p.Card)
.WithMany(r => r.Abilities)
.HasForeignKey(p => p.CardID);
}
}
I have been working on this for about 3 days and have done a lot of trial and error from what I have read online. At this point, the create view does display a listbox that is pulling the titles from the Abilities table. When I try to save, I get a validation error "The value "1" is invalid.", where 1 is the ID for that ability. When debugging, I see that the modelstate is invalid and the error is
{System.InvalidOperationException: The parameter conversion from type 'System.String' to type 'MTG.Models.CardAbility' failed because no type converter can convert between these types.
at System.Web.Mvc.ValueProviderResult.ConvertSimpleType(CultureInfo culture, Object value, Type destinationType)
at System.Web.Mvc.ValueProviderResult.UnwrapPossibleArrayType(CultureInfo culture, Object value, Type destinationType)
at System.Web.Mvc.ValueProviderResult.ConvertTo(Type type, CultureInfo culture)
at System.Web.Mvc.DefaultModelBinder.ConvertProviderResult(ModelStateDictionary modelState, String modelStateKey, ValueProviderResult valueProviderResult, Type destinationType)}
I know it doesn't like the types and can't convert, but if I try anything else with the listboxfor helper it won't bring in the data and usually crashes before I even get to see the create page. Sorry this is so long, I just wanted to give all the information I could. :) Thank you for any help.
Generate a listbox for SelectedAbilities instead of Abilities:
#Html.ListBoxFor(model => model.SelectedAbilities , (ViewBag.AbilityID as MultiSelectList))
By the way you need to do the same for RarityID instead of Rarity, MainTypeID instead of MainType and etc.
I have trouble with sending value from view to controller. When I send a value like 35 it works but when I try to pass 35.00 I have validation message:
The value '125.50' is not valid for Cena.
When i try give 35,50 i get:
The field Cena must be a number.
Here is my view code
<div class="editor-label">
#Html.LabelFor(model => model.Cena)
</div>
<div>
#Html.TextBoxFor(model => model.Cena)
#Html.ValidationMessageFor(model => model.Cena)
</div>
<p>
<input type="submit" value="Dodaj" />
</p>
Model:
public partial class Czapki
{
public Czapki()
{
this.Zamowienie = new HashSet<Zamowienie>();
}
public int IdCzapki { get; set; }
[Required]
public string Model { get; set; }
[Required]
public int Ilosc { get; set; }
public decimal Cena { get; set; }
[Required]
public string Rodzaj { get; set; }
public bool Checked { get; set; }
public virtual ICollection<Zamowienie> Zamowienie { get; set; }
}
I'm relatively new to MVC 4 and ASP.net in general. I'm trying to create a "room" with some properties, one of which queries from a list of statuses contained in another model. I have my classes set up as follows:
Room.cs
public class Room
{
[Key]
public Guid RoomId { get; set; }
[Required(ErrorMessage = "A Room Name is required")]
public string Name { get; set; }
public string Description { get; set; }
public virtual Status Status { get; set; }
[DisplayName("Created On")]
public DateTime? Created { get; set; }
[DisplayName("Last Modified")]
public DateTime? Modified { get; set; }
}
Status.cs
public class Status
{
[Key]
public int StatusId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
When I use the default scaffolding for the create action against the room, I am using the following code, which is working flawlessly, and properly applying the status of "New" to the newly created room.
// Post: /Room/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Room room)
{
if (ModelState.IsValid)
{
room.Created = DateTime.Now;
room.Status = db.Statuses.Single(s => s.Name == "New");
room.RoomId = Guid.NewGuid();
db.Rooms.Add(room);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(room);
}
When I attempt the same syntax for assigning room.Status on an edit action, in my case, automatically changing the status from "New" to "Discovery", the status values are never modified in the database. I am tracing the locals right up to the db.SaveChanges(); call, and I can see that the room.Status value is accurately reflecting the definition to the new status, but it's simply not updating on the back end. Here is my update code:
//Room/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Room room)
{
if (ModelState.IsValid)
{
room.Modified = DateTime.Now;
room.Status = db.Statuses.Single(s => s.Name == "Discovery");
db.Entry(room).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(room);
}
I'm at a loss as to how to change this value! My Edit view is as follows:
#model vwr.Cloud.Models.Room
#{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>Room - #Html.ValueFor(model => model.Name)</legend>
#Html.HiddenFor(model => model.RoomId)
#Html.HiddenFor(model => model.Name)
#Html.HiddenFor(model => model.Created)
#Html.HiddenFor(model => model.Status.StatusId)
<div class="editor-label">
Room Status - #Html.ValueFor(model => model.Status.Name)
</div>
<div class="editor-label">
Created Date - #Html.ValueFor(model => model.Created)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Description)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Description)
#Html.ValidationMessageFor(model => model.Description)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
It took me WAY too long to figure this out, but I also needed to add a [ForeignKey] entry to my Room class that mapped to the Navigation Property. I can't say I yet understand HOW it works, suffice to say, it does :-).
Final room.cs
public class Room
{
[Key]
public Guid RoomId { get; set; }
[Required(ErrorMessage = "A Room Name is required")]
public string Name { get; set; }
public string Description { get; set; }
[ForeignKey("Status")]
public virtual int StatusId { get; set; }
public virtual Status Status { get; set; }
[DisplayName("Created On")]
public DateTime? Created { get; set; }
[DisplayName("Last Modified")]
public DateTime? Modified { get; set; }
}
public class Room
{
[Key]
public Guid RoomId { get; set; }
[Required(ErrorMessage = "A Room Name is required")]
public string Name { get; set; }
public string Description { get; set; }
[ForeignKey("Status")]
public virtual int StatusId { get; set; }
public virtual Status Status { get; set; }
[DisplayName("Created On")]
public DateTime? Created { get; set; }
[DisplayName("Last Modified")]
public DateTime? Mod
I have a list of comments under my detail page in MVC. I want the user to be able to add comments in the same page and save to the database. How do I pass data to the controller action and save this using dbcontext that holds my comment class.
I have this follow code in my CommentController:
public ActionResult Create(int MovieId)
{
var moviecomment = _db.Moviecomment.Where(r => r.MovieID == MovieId);
return View(moviecomment);
}
[HttpPost]
public ActionResult Create(MovieComment Moviecomment)
{
var MovieComment = _db.Moviecomment.Add(Moviecomment);
_db.SaveChanges();
return RedirectToAction("Details");
}
And has a partial View:
#model MvcMovie.Models.MovieComment
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<div class="addcommentbox">
<h2> Add Comment </h2>
#Html.TextAreaFor(model => model.comment)
<div class="ErrorMessage">
#Html.ValidationMessageFor(model => model.comment)
</div>
<input id="addComment" type="button" onclick="" value="Add" />
</div>
}
and in my Detail page i have this:
#model MvcMovie.Models.Movie
#{
ViewBag.Title = "Details";
}
<h2>Details</h2>
Movie
Title
#Html.DisplayFor(model => model.Title)
Genre
#Html.DisplayFor(model => model.Genre)
PostDate
#Html.DisplayFor(model => model.PostDate)
Staring
#Html.DisplayFor(model => model.Staring)
Description
#Html.DisplayFor(model => model.Description)
Trailer
#Html.DisplayFor(model => model.Trailer)
<fieldset>
#Html.Partial("Comments",Model.MovieComment)
</fieldset>
<p>
</p>
<p>
#Html.ActionLink("Edit", "Edit", new { id=Model.MovieID }) |
#Html.ActionLink("Back to List", "Index")
</p>
#Html.RenderAction("Create","Comment" new { id = Model.MovieID })
i want user to able to add comment when they are in detail page: other thing seem to been fine but this line
#Html.RenderAction("Create","Comment" new { id = Model.MovieID })
give me the following error. cannot implicitly convert type void to object. Please any help will be appreciated.
The model code:
public class Movie
{
public int MovieID { get; set; }
public string Title { get; set; }
public String Genre { get; set; }
public DateTime PostDate { get; set; }
public string Staring { get; set; }
public string Description { get; set; }
public string Picture { get; set; }
public string Trailer { get; set; }
public virtual ICollection< MovieComment> MovieComment { get; set; }
}
For comment
public class MovieComment
{
// public MovieComment()
//{
// Movie = new HashSet<Movie>();
//}
public int MovieCommentID { get; set; }
public string comment_title { get; set; }
public String comment { get; set; }
public int MovieID { get; set; }
// [ForeignKey("ID")]
public virtual Movie Movie { get; set; }
//[ForeignKey("ProfileID")]
public virtual Profile Profile { get; set; }
public String ProfileID { get; set; }
//public string MovieUserID { get; set; }
}
Not sure if this is your only error, but the syntax is wrong for the line that's giving you an error. You are missing a comma. Try:
#Html.RenderAction("Create","Comment", new { id = Model.MovieID })
If this doesn't fix your problem, can you also post the code for your model?