MVC Radio Button List Grid - razor

I've got an issue trying to read the selected values from the radio button list in my [HttpPost] Controller. Any help would be greatly appreciated.
My models are the following:
public partial class RoleModel
{
public Guid RoleId { get; set; }
public string Description { get; set; }
public List<RoleModuleAccessRight> RoleModuleAccessRights { get; set; }
}
public class RoleModuleAccessRight
{
public string ModuleName { get; set; }
public int ModuleId { get; set; }
public bool HasFullControl { get; set; }
public bool HasReadOnly { get; set; }
public bool HasNoAccess { get; set; }
}
My Controllers:
[HttpGet]
public ActionResult Edit(Guid id)
{
RoleModel role = BusinessLayer.UserManager.GetRoleModel(id);
role.RoleModuleAccessRights = BusinessLayer.UserManager.GetModulesForRoleId(role.RoleId);
return PartialView("_Edit", role);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(RoleModel model)
{
if (ModelState.IsValid)
{
BusinessLayer.UserManager.UpdateAccessRights(model);
string url = Url.Action("List", "Roles");
return Json(new { success = true, url = url });
}
return PartialView("_Edit", model);
}
My View code:
#foreach (RoleModuleAccessRight item in Model.RoleModuleAccessRights)
{
#Html.HiddenFor(model => item.ModuleId)
string radioName = string.Format("RoleModuleAccessRights_{0}", item.ModuleId.ToString());
<tr>
<td>#item.ModuleName</td>
<td>
<div class="checkbox">
#Html.RadioButton(radioName, item.HasFullControl, item.HasFullControl)
</div>
</td>
<td>
<div class="checkbox">
#Html.RadioButton(radioName, item.HasReadOnly, item.HasReadOnly)
</div>
</td>
<td>
<div class="checkbox">
#Html.RadioButton(radioName, item.HasNoAccess, item.HasNoAccess)
</div>
</td>
</tr>
}
The issue im having is that when i post the form im not able to grab the information in my [HttpPost] Controller. It returns "null"
The mark up generated is the following:

Looking at your code, your ids are not unique which is going to break things, also using a dedicated template will simplify your problem. See this example https://stackoverflow.com/a/7668325
Another more generic article: Multiple radio button groups in MVC 4 Razor

Related

how can I show the record horizontally in view

I have the following record in a view horizontally. I cannot show the the exact layout here. but I hope you can understand what I am looking for the help.
One record under in one column, another record in another column in same row , maximumn 6 column should be shown in each row that means 6 record in each row .
I have the following model
public class Order
{
[Key]
public long id { get; set; }
public DateTime OrderDate { get; set; }
public string Customer { get; set; }
public string Itemname { get; set; }
public int QTY { get; set; }
}
In View I am using IEnumerable. I am trying to list in view the record horizontally in a table under td . maximum 6 record in a row
01/01/2020
02/01/2020
Customer 1
Customer 2
Item1
Item2
You can use bootstrap to specify the number of records per column, such as
<td class="col-xs-2 col-sm-2 col-md-2">
and the following is my demo:
Controller:
public class OrderController : Controller
{
private readonly OrderContext _context;
public OrderController(OrderContext context)
{
_context = context;
}
// GET: Orders
public async Task<IActionResult> Index()
{
var model = new OrderList()
{
OrderLists = await _context.Orders.ToListAsync()
};
return View(model);
}
}
Model:
public class Order
{
[Key]
public long id { get; set; }
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime OrderDate { get; set; }
public string Customer { get; set; }
public string Itemname { get; set; }
public int QTY { get; set; }
}
public class OrderList
{
public IEnumerable<Order> OrderLists { get; set; }
}
View:
#model OrderList
<table class="table">
<tbody>
<tr class="row">
#foreach (var item in Model.OrderLists)
{
<td class="col-xs-2 col-sm-2 col-md-2">
#Html.DisplayFor(modelItem => item.OrderDate)<br />
#Html.DisplayFor(modelItem => item.Customer)<br />
#Html.DisplayFor(modelItem => item.Itemname) <br />
</td>
}
</tr>
</tbody>
</table>
Result:

MVC, Razor - Submitting form (inside #if) gives empty object in post

I am trying to save some changes to a database.
The view gets a Model, and should be able to make changes and have them saved. However, when i submit the form, the ContactInfo parameter in the post method is not null, but all the properties are.
I'm using MVC5 with Razor. the script is in a seperate .ts-file
In controller:
[HttpPost]
public bool SaveInfoChanges(ContactInfo editedContactInfo)
{
// Save data
return true;
}
Script:
export function saveInfoChanges() {
$("#EditContactInfoForm").submit();
};
HTML:
#if (true)
{
#using (Html.BeginForm("SaveInfoChanges", "ContactInfoBox", FormMethod.Post, new { id = "EditContactInfoForm" }))
}
<table>
#Html.HiddenFor(model => model.Name)
#Html.HiddenFor(model => model.Address1)
#Html.HiddenFor(model => model.Address2)
#Html.HiddenFor(model => model.ZipAndCity)
#Html.HiddenFor(model => model.Country)
<tr>
<td>test</td>
<td>
#Html.TextBoxFor(model => model.Address3, new { id = "ContactTypeInput", placeholder = "", style = "width:300px" })
</td>
</tr>
</table>
}
}
Model:
public class ContactInfo
{
public string ContactInfoBoxHeaderText { get; set; }
public string Name { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string Address3 { get; set; }
public string ZipAndCity { get; set; }
public string Country { get; set; }
}
I can't think of more relevant information to give, but please don't hesitate to ask.
Thanks in advance!
Removing the #if solved the problem. I just need to find another way to hide/show the elements.

Populate DropDown from database in an edit view using MVC4

I am new to MVC and trying to populate a dropdown list in the "create" view which is generated from a view model, but it returns with an error saying object reference is not an instance of an object. below is my code :
Controller Code:
public ActionResult Create()
{
return View(new AddRecipeViewModel());
}
Model Code:
public class DifficultyLevel
{
[Key]
public int Id { get; set; }
public string Difficulty { get; set; }
}
public class AddRecipeViewModel
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<RecipeReview> Reviews { get; set; }
public virtual IEnumerable<DifficultyLevel> Difficulty { get; set; }
}
View:
<div>
<select>
#foreach (var item in Model.Difficulty)
{
<option>#item.Difficulty</option>
}
</select>
</div>
Is there an easy workaround this ? as I will be adding more drop downs in this as I go along.
Thanks,
Vishal
not sure if you need to use virtual in your view models.. that's usually only for the entity models. but anyway, try adding a constructor to AddRecipeViewModel and set the collections equal to empty lists so they won't be null.
public class AddRecipeViewModel
{
public AddRecipeViewModel()
{
Reviews = new List<RecipeReview>();
Difficulty = new List<DifficultyLevel>();
}
[Key]
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<RecipeReview> Reviews { get; set; }
public virtual IEnumerable<DifficultyLevel> Difficulty { get; set; }
}

need to render html from mvc, only displaying htmls tags not text

I am using razorpdf to generate a pdf report in my mvc 4 application. each time I generate the pdf, the description field will display a bunch of html tags and fields that are not supposed to be shown, i just want the plain text from the description field displayed. does anyone have any advice on how to do this, also any advice on how to add an image into the pdf page as well?
this is my view that is generating the pdf:
#model List<ArdentMC.DHS.COP.Mobile.MVC.Models.Reports>
#{
Layout = "";
}
<!DOCTYPE html>
<html>
<head>
<div style="color=red; align:center;">UNCLASSIFIED/FOR OFFICAL USE ONLY</div>
</head>
<body>
<table style="width:300px;">
#foreach (var item in Model)
{
<tr>
<td>#item.Phase</td>
<td>#item.NocNumber</td>
<td>#item.Title</td>
<td>#item.Location</td>
</tr>
<tr<
<td></td>
<td></td>
<td>#item.ReportDateText</td>
<td>#item.Description</td>
</tr>
}
</table>
<br /><br /><br /><br /><br />
<br /><br /><br /><br /><br />
<div style="color:black; align:center;">US Department of Homeland Security</div>
<br />
<div style="color:red; align:center;">UNCLASSIFIED/FOR OFFICAL USE ONLY</div>
</body>
</html>
this is my model where the information is getting pulled from:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace ArdentMC.DHS.COP.Mobile.MVC.Models
{
public class Reports
{
public string NocNumber { get; set; }
public string Title { get; set; }
public Nullable<System.DateTime> IncidentDate { get; set; }
public string ReportDateText { get; set; }
public string IncidentType { get; set; }
public Nullable<int> IncidentSubtypeId { get; set; }
public string IncidentSubtype { get; set; }
public Nullable<int> PhaseId { get; set; }
public string Phase { get; set; }
public string InitialNotification { get; set; }
public string Location { get; set; }
public string NocSpotRep { get; set; }
public string Contributors { get; set; }
public string Participants { get; set; }
public string Description { get; set; }
public Nullable<int> IncidentStateId { get; set; }
public string IncidentState { get; set; }
public Nullable<System.DateTime> PublishDate { get; set; }
public Nullable<System.DateTime> ArchiveDate { get; set; }
}
}
does anyone have some advice on how to just get the description text to display? thank you in advance.
I was able to add
#foreach (var item in Model){
#Html.Raw(item.Description)
} into my view and that rendered the correct code for the description field so that there are no viewable tags, only text.
public ActionResult NotFound() {
Response.ContentType = "text/html";
return View();
}

How to build a Create View for a Many to Many relationship

Ok, looks like someone should run into this, but I have not found anything that helps. This is my scenario.
I have a clients and skills model. The objective is to allow clients to rate each of a set of skills, all of them.
So, here I'll paste model, viewModel, Controller and View. at the end the crucial question
MODEL
namespace ClientSkills.Models
{
public class Client
{
public int ClientId { get; set; }
public string Name { get; set; }
public ICollection<ClientSkills> Skills { get; set; }
}
public class Skill
{
public int SkillId { get; set; }
public string Name { get; set; }
public ICollection<ClientSkills> Clients { get; set; }
}
public class Rating
{
public int RatingId { get; set; }
public string Name { get; set; }
public ICollection<ClientSkills> ClientSkills { get; set; }
}
public class ClientSkills
{
[Key, Column(Order=0)]
public int ClientId { get; set; }
[Key, Column(Order = 1)]
public int SkillId { get; set; }
public int RatingId { get; set; }
public Rating Rating { get; set; }
public Skill Skill { get; set; }
public Client Client { get; set; }
}
public partial class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public DbSet<Client> Client { get; set; }
public DbSet<Skill> Skill { get; set; }
public DbSet<Rating> Rating { get; set; }
public DbSet<ClientSkills> ClientSkills { get; set; }
}
}
VIEW MODEL
namespace ClientSkills.Models
{
public class RateViewModel
{
public RateViewModel()
{
this.Skills = new List<SkillViewModel>();
}
public RateViewModel(Client client)
{
this.ClientId = client.ClientId;
this.Skills = new List<SkillViewModel>();
if (client.Skills.Count == 0)
{
var context = new ApplicationDbContext();
foreach (var skill in context.Skill)
{
var skillVM = new SkillViewModel(skill);
skillVM.SelectedRatingid = context.Rating.First(r => r.Name == "No aplica").RatingId;
Skills.Add(skillVM);
}
}
else
{
foreach (var item in client.Skills)
{
var skillVM = new SkillViewModel(item);
skillVM.SelectedRatingid = item.SkillId;
this.Skills.Add(skillVM);
}
}
}
public int ClientId { get; set; }
public List<SkillViewModel> Skills { get; set; }
}
public class SkillViewModel
{
public SkillViewModel()
{
Ratings = new List<Rating>();
}
public SkillViewModel(Skill skill)
{
var context = new ApplicationDbContext();
this.Ratings = context.Rating.ToList();
this.SkillId = skill.SkillId;
this.SkillName = skill.Name;
}
public SkillViewModel(ClientSkills item)
{
var context = new ApplicationDbContext();
this.Ratings = context.Rating.ToList();
this.SkillId = item.SkillId;
this.SkillName = item.Skill.Name;
this.SelectedRatingid = item.RatingId;
}
public List<Rating> Ratings { get; set; }
public int SelectedRatingid { get; set; }
public int SkillId { get; set; }
public string SkillName { get; set; }
}
}
CONTROLLER
namespace ClientSkills.Controllers
{
public class RateController : Controller
{
//
// GET: /Rate/Create
public ActionResult Create()
{
//first, we assume there is an already selected user
var context = new ApplicationDbContext();
var client = context
.Client
.Include(c => c.Skills)
.First(c => c.Name.ToLower() == "ricker");
var model = new RateViewModel(client);
return View(model);
}
}
}
VIEW
This View is made creating a Create view with the wizard, deleting the useless field it creates and putting the code below
<table>
<tr>
<td>Skill</td>
<td>Rate</td>
</tr>
#foreach (var item in Model.Skills)
{
<tr>
<td>
#Html.DisplayFor(model => model.Skills.First(i => i.SkillName == item.SkillName).SkillName, new { #class = "control-label col-md-2" })
</td>
<td>
#Html.DropDownListFor(x => item.SelectedRatingid, new SelectList(item.Ratings, "RatingId", "Name"), "Seleccione el valor")
</td>
</tr>
}
</table>
The problem is that in the RateViewModel(Client client) constructor in the line skillVM.SelectedRatingid = context.Rating.First(r => r.Name == "No aplica").RatingId; I set a default value for the selectedRatingId property. I need to make sure all clients has all skills rated even if they forgot or bypass one of them.
When the view is loaded, and I was sure the ratesid was well set, the skill names look ok but the drop dpwn lists does not show the selected default value.
How can I make the view to bind the selectedRatingId property to the drop down list control?
Passing selected value to SelectList:
#Html.DropDownListFor(x => item.SelectedRatingid, new SelectList(item.Ratings, "RatingId", "Name", item.SelectedRatingid), "Seleccione el valor")
As I understand it (rightly or wrongly) that last parameter is an object if it matches with one of the options values - it is selected else the first one in the options is selected.
More info about the Selectlist overload.