DisplayNameFor tag change text - asp.net-mvc

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" })

Related

MVC Details page not showing any data

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

How do I pass selected items in MVC4 EF5?

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.

Trouble with sending decimal value to view

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; }
}

MVC 5 Dynamic Data Form - List of Model Not Posting to Controller

Ok this is driving me nuts. Sometimes I find with MVC I get a bit lost in the woods and start looking down the wrong path and all goes to hell. So I'm reaching out to see if a fresh pair of eyes will point me in the correct direction.
Basically the structure is allowing an admin to create their own questions which in itself would be pretty simple, however in this case it's more than a "single" answer box. Example:
What are the name(s) and address(es) of your business locations?
Name: _______ Address: ____ City: ___ State: __ Zip: _
So if the client only had one location it would be an answer with 5 text boxes (name, address, city, state, zip)...but since the questions are created dynamically it could be 3 text boxes, 1, 2, etc.
So the problem I'm having is when the model is posted back to the controller the Questions part of the view model is fine, but the answers/choices part of it is always returning null. Please take a look and see if there's the giant on/off switch I clearly have neglected to include.
Here's the models and view model:
public class Questions
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public int FormID { get; set; }
[Display(Name = "Question Order")]
[Range(0, Int32.MaxValue, ErrorMessage = "Must Use an Integer")]
public int QuestionOrder { get; set; }
[Required]
[DataType(DataType.MultilineText)]
public string Question { get; set; }
[Display(Name = "Help Text")]
public string HelpText { get; set; }
public bool IsActive { get; set; }
[Display(Name = "Question May Have More Than One Entry")]
public bool CanHaveMoreThanOne { get; set; }
public int QuestionTypeID { get; set; }
}
public class Choices
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public int QuestionID { get; set; }
public string FieldName { get; set; }
public string QuestionLabel { get; set; }
public bool IsRequired { get; set; }
public string RegEx { get; set; }
public string TextIfSelected { get; set; }
public string QuestionToSkipToIfSelected { get; set; }
public bool IsActive { get; set; }
[NotMapped]
public string AnswerText { get; set; }
[NotMapped]
public bool AnswerBool { get; set; }
[NotMapped]
public int AnswerNumeric { get; set; }
[NotMapped]
public DateTime AnswerDate { get; set; }
}
public class ViewQuestion
{
public Questions Question { get; set; }
public IEnumerable<Choices> Answers { get; set; }
}
Here's the view:
#using InterviewMaster.Models
#model ViewQuestion
#using (Html.BeginForm("AnswerQuestion","Interview", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.HiddenFor(m => m.Question.CanHaveMoreThanOne)
#Html.HiddenFor(m => m.Question.FormID)
#Html.HiddenFor(m => m.Question.HelpText)
#Html.HiddenFor(m => m.Question.ID)
#Html.HiddenFor(m => m.Question.Question)
#Html.HiddenFor(m => m.Question.QuestionOrder)
#Html.HiddenFor(m => m.Question.QuestionTypeID)
<h3>#Model.Question.Question</h3>
<hr />
#if (Model.Question.QuestionTypeID == 1)
{
foreach(var o in Model.Answers)
{
Html.RenderPartial("Partial1", o);
}
}
else if (Model.Question.QuestionTypeID == 2)
{
//TO-DO: Make other types of answers such as radio buttons, checkboxes, etc.
}
<input type="submit" value="Create" class="btn btn-default" />
</div>
}
Here's the partial I'm using
#model InterviewMaster.Models.Choices
#using(Html.BeginCollectionItem("Choices"))
{
#Html.HiddenFor(model => model.ID)
#Html.HiddenFor(model => model.QuestionID)
#Html.HiddenFor(model => model.FieldName)
#Html.HiddenFor(model => model.QuestionLabel)
#Html.HiddenFor(model => model.IsRequired)
#Html.HiddenFor(model => model.RegEx)
#Html.HiddenFor(model => model.TextIfSelected)
#Html.HiddenFor(model => model.QuestionToSkipToIfSelected)
#Html.HiddenFor(model => model.IsActive)
#Html.HiddenFor(model => model.AnswerBool)
#Html.HiddenFor(model => model.AnswerDate)
#Html.HiddenFor(model => model.AnswerNumeric)
<div class="form-group">
<label>#Html.ValueFor(model => model.QuestionLabel)</label>
#Html.TextBoxFor(model => model.AnswerText)
</div>
}
and last but not least, the controller receiving this post:
// POST: /Interview/AnswerQuestion
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult AnswerQuestion(ViewQuestion dto)
{
foreach(var answer in dto.Answers)
{
Console.Write("Answer:" + answer.AnswerText);
}
return RedirectToAction("ContinueInterview", new { OrderID = 1, OrderDetailID = 1, FormID = 1, QuestionID = 1 });
}
Ok for those of you who may need this someday, here's what the problem was.
This...
#using(Html.BeginCollectionItem("Choices"))
should have been this...
#using(Html.BeginCollectionItem("dto.Answers"))
In the example on Steven Sandersons' site (http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/) it didn't really go into a complex example such as mine (not his fault...mine)
I thought it was whatever the model was you were editing/viewing. Instead, it's what you're sending back to the controller. Big duh on my part.
Hopefully this helps someone in the future. This took me about 8 hours of driving myself crazy....arrrrgggghhh!

ASP.Net MVC 4 Update value linked to a foreign key column

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

Resources