When I postback on my "Review" page I check the modelstate and based on the results either redisplay the page or continue. I have two issues.
When it fails validation it hangs up on partial views on that it loaded fine on the original get for the page.
edit: This was caused by the [HttpGet]attribute being applied to methods for the partials views. I removed the attribute and the partials renedered.
If I comment out the partials then the the whole page diplays without any CSS styles..it's all text black and white. Edit: I'm still having the problem with the styles missing from the page
[HttpGet]
public ActionResult Review()
{
var agmtsService = new AgreementsService();
bool? scoreRelease = agmtsService.GetReleaseScoreIndicator();
var vm = new ReviewModel {ReleaseScoreIndicator = scoreRelease};
return View(vm);
}
[HttpPost]
public ActionResult Review(ReviewModel model)
{
if(!ModelState.IsValid)
{
return View(model);`**This is displaying the view w/o head section and no css**`
}
return RedirectToAction("CheckOut", "Financial");
}
edit:
View Model
public class ReviewModel
{
public bool? ReleaseScoreIndicator { get; set; }
// Terms & Conditions
[RequiredToBeTrue(ErrorMessage = "Eligibility Checkbox must be checked.")]
public bool TermsEligibility { get; set; }
[RequiredToBeTrue(ErrorMessage = "True and Accurate Checkbox must be checked.")]
public bool TermsAccurate { get; set; }
[RequiredToBeTrue(ErrorMessage = "Identity Release Checkbox must be checked.")]
public bool TermsIdentityRelease { get; set; }
[RequiredToBeTrue(ErrorMessage = "Score Release Checkbox must be checked.")]
public bool TermsScoreRelease { get; set; }
}
public class RequiredToBeTrueAttribute : RequiredAttribute
{
public override bool IsValid(object value)
{
return value != null && (bool)value;
}
}
View
#model Registration.Web.Models.ReviewModel
#{
ViewBag.DisableNavigation = true;
}
<script type="text/javascript">
$(document).ready(function () {
$('.open_review').toggle(function() {
$(this).text('Done').parents('.review_section').addClass('open_for_review').find('.review_content').slideDown('fast');
return false;
}, function() {
$(this).text('Review').parents('.review_section').removeClass('open_for_review').find('.review_content').slideUp('fast');
return false;
});
});
</script>
<div class='section module'>
<h2>
Please Review Your Application
</h2>
<p>
Remember that your application fee is
<strong>
not refundable.
</strong>
Review your information below and make corrections before submitting.
</p>
<div class='review_section'>
<a class="button open_review" href="#">Review</a>
<h4>
Identification
</h4>
#{Html.RenderAction("Review", "PersonalInformation");}
</div>
<div class='review_section'>
<a class="button open_review" href="#">Review</a>
<h4>
Education
</h4>
#{Html.RenderAction("Review", "MedicalEducation");} /////hangs here
</div>
<div class='review_section'>
<a class="button open_review" href="#">Review</a>
#{Html.RenderAction("Review", "PostGraduate");}////then hangs here
</div>
</div>
<div class='actions' id='terms_and_conditions'>
#using (Html.BeginForm("Review", "Agreements", FormMethod.Post))
{
//"reviewForm","Agreements", FormMethod.Post
#Html.ValidationSummary(true)
<div class='group' id='data_release'>
<h4>
Data Release
</h4>
<p>
Do you wish to release your scores?
</p>
<ul class='input_group'>
<li>
#Html.RadioButtonFor(model => model.ReleaseScoreIndicator, true)
<label>
Yes
</label>
</li>
<li>
#Html.RadioButtonFor(model => model.ReleaseScoreIndicator, false)
<label>
No
</label>
</li>
</ul>
</div>
<div class='group' id='terms'>
<h4>
Terms & Conditions
</h4>
#Html.ValidationSummary(false)
<table>
<tbody>
<tr>
<th>
#Html.CheckBoxFor(x => x.TermsEligibility)
#* #Html.CheckBox("terms_eligibility")*#
</th>
<td>
<label for='terms_eligibility'>
I currently meet all of the
requirements
and have read the
Information
</label>
</td>
</tr>
<tr>
<th>
#Html.CheckBoxFor(x => x.TermsAccurate)
#* #Html.CheckBox("terms_accurate")*#
</th>
<td>
<label for='terms_accurate'>
The information I've provided is true and accurate
</label>
</td>
</tr>
<tr>
<th>
#Html.CheckBoxFor(x => x.TermsIdentityRelease)
#* #Html.CheckBox("terms_identity_release")*#
</th>
<td>
<label for='terms_identity_release'>
I authorize the release
</label>
</td>
</tr>
<tr>
<th>
#Html.CheckBoxFor(x => x.TermsScoreRelease)
#*#Html.CheckBox("terms_score_release")*#
</th>
<td>
<label for='terms_score_release'>
I agree
</label>
</td>
</tr>
</tbody>
</table>
</div>
<div class='actions'>
<input type="submit" value="Go To Checkout" class="button" />
<a class="button" onclick="getForMasterPage('#Url.Action("CheckOut", "Financial")', null);">BYPASS</a>
</div>
} </div>
Do you need to set the ReleaseScoreIndicator on the return from being posted? It looks like it gets set for the initial GET, but the subsequent one, it doesn't get set. Does the view use that property?
Related
I am practicing ASP and MVC by making a website like Twitter and I am having trouble with using a PartialView.
I have my User Home Page Controller here, which gets called from my Login Page Controller.
public class UserController : Controller
{
private readonly Twitter _twitter = null;
private readonly TwitterCloneDBContext _context;
public UserController(TwitterCloneDBContext context)
{
_twitter = new Twitter(context);
_context = context;
}
public ActionResult Index()
{
List<Tweet> tweets = _twitter.TweetList();
ViewBag.Tweets = tweets.Count;
ViewBag.Followers = 2;
ViewBag.Following = 3;
return View();
}
public PartialViewResult TweetList()
{
List<Tweet> tweetList = _twitter.TweetList();
return PartialView("TweetList",tweetList);
}
}
Here is the View for it.
#{
ViewData["Title"] = "Home Page";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#using Microsoft.AspNetCore.Http;
#model IEnumerable<Tweet>
#if (Context.Session.GetString("FullName") != null)
{
<div class="text-center">
<h1 class="display-4">Welcome, #Context.Session.GetString("FullName")!</h1>
</div>
<hr />
<div class="row">
<div class="col-sm-2">
<div class="text-left">
<h4>Follow</h4>
<form asp-action="Search">
<div class="input-group mb-3">
<input type="text" name="searchName" class="form-control" placeholder="Search User" />
<div class="input-group-append">
<button class="btn btn-primary" type="submit">Search</button>
</div>
</div>
</form>
<span class="text-danger">#ViewBag.SearchFail</span>
</div>
<div>
<h6>#ViewBag.Tweets Tweets</h6>
<br />
<h6>#ViewBag.Followers Followers</h6>
<br />
<h6>#ViewBag.Following Following</h6>
</div>
</div>
<div class=border></div>
<div class="col-4">
<h4>Tweet your thoughts!</h4>
<form asp-action="Tweet">
<textarea rows="5" cols="100" name="message" class="form-control"> </textarea>
<br />
<input type="submit" value="Tweet" class="btn btn-primary" />
</form>
<span class=" text-danger">#ViewBag.ErrMessage</span>
<div>
#Html.PartialAsync("TwitterList",Model)
</div>
</div>
</div>
}
else
{
<h2>You are not Authorized!</h2>
<script type="text/javascript">
window.setTimeout(function () {
window.location.href = '/Home/UserLogin';
}, 1000);
</script>
}
The Partial Line is supposed to call TwitterList View which is working perfectly and displaying List as it is supposed to.
#model IEnumerable<TwitterClone.Models.Tweet>
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.User_ID)
</th>
<th>
#Html.DisplayNameFor(model => model.Message)
</th>
<th>
#Html.DisplayNameFor(model => model.Created)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.User_ID)
</td>
<td>
#Html.DisplayFor(modelItem => item.Message)
</td>
<td>
#Html.DisplayFor(modelItem => item.Created)
</td>
</tr>
}
</tbody>
</table>
But when I call it using the #Html.PartialAsync() It fails by saying
System.NullReferenceException
HResult=0x80004003
Message=Object reference not set to an instance of an object.
Source=TwitterClone.Views
StackTrace:
at AspNetCore.Views_User_TweetList.<ExecuteAsync>d__0.MoveNext() in C:\Users\Cloud\source\repos\TwitterClone\TwitterClone\Views\User\TweetList.cshtml:line 19
and giving me this in the main page
See below Tweet Button, that is my Partial View, if I do the Partial View any other way I get NullReferenceException in both the places. This is the closes I've gotten to this and I cannot figure it out.
EDIT:
My ViewBags are in another Actions that are not relevant here. They basically print an error message.
The NullExceptions are gone, my Model is not empty when I open the Table View on its own. But its empty when being called through Partial. I suspect its because something isn't being called in the chain.
If I change my Index Action to like this,
public ActionResult Index()
{
List<Tweet> tweets = _twitter.TweetList();
ViewBag.Tweets = tweets.Count;
ViewBag.Followers = 2;
ViewBag.Following = 3;
return View("Index",tweets);
}
I get this error.
InvalidOperationException: The model item passed into the ViewDataDictionary is of type 'System.Collections.Generic.List`1[TwitterClone.Models.Tweet]', but this ViewDataDictionary instance requires a model item of type 'TwitterClone.Models.Person'.
I have no Idea where ViewDataDictionary is setting Person to. The only place where I can think of that connects to UserController is my HomeController.
EDIT
This was a dumb mistake, I left out an #model Person in my Layout file. Sorry.
EDIT
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly TwitterCloneDBContext _context;
public HomeController(ILogger<HomeController> logger, TwitterCloneDBContext context)
{
_logger = logger;
_context = context;
}
//GET: Home/UserLogin
public ActionResult UserLogin()
{
return View();
}
//POST: Home/UserLogin
[Microsoft.AspNetCore.Mvc.HttpPost]
[ValidateAntiForgeryToken]
public ActionResult UserLogin(Person userLogin)
{
var login = _context.Person.Where(a => a.UserID.Equals(userLogin.UserID)
&& a.Password.Equals(userLogin.Password)).FirstOrDefault();
if (login != null)
{
Person session = _context.Person.SingleOrDefault(u => u.UserID == userLogin.UserID);
session.Active = 1;
HttpContext.Session.SetString("FullName", login.FullName);
HttpContext.Session.SetString("UserID", login.UserID);
_context.SaveChanges();
return RedirectToAction("Index", "User");
}
else
{
ViewBag.ErrMsg = "Invalid Credentials";
return View();
}
}
}
And its View
#model Person
#{
ViewData["Title"] = "UserLogin";
Layout = "~/Views/Shared/LoginLayout.cshtml";
}
<h1>Welcome!</h1>
<h4>Enter Credentials</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="UserLogin">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="UserID" class="control-label">User ID</label>
<input asp-for="UserID" class="form-control" />
<span asp-validation-for="UserID" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Password" class="control-label">Password</label>
<input asp-for="Password" class="form-control" />
<span asp-validation-for="Password" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Login" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
New User? <a asp-action="Signup">Signup</a>
</div>
What is
<span class="text-danger">#ViewBag.SearchFail</span>
I can't see ViewBag.SearchFail or ViewBag.ErrMessage in your action.
You have a big bug. Move redirect from Index view to action, otherwise it will be always running after creating the page.
public ActionResult Index()
{
if (Context.Session.GetString("FullName") != null)
{
List<Tweet> tweets = _twitter.TweetList();
.....
return View("Index", tweets);
}
RedirectToAction("Login", "Users")
}
Since you are using the same model for both, try to replace
#Html.PartialAsync("TwitterList",Model)
with
<partial name="TwitterList" />
and fix the model of both views
#model List<TwitterClone.Models.Tweet>
also fix the partial view
#if(#Model!=null && Model.Count >0)
{
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model[0].User_ID)
</th>
<th>
#Html.DisplayNameFor(model => model[0].Message)
</th>
......
}
This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 1 year ago.
I get this returned when I try to add a comment. I can not really understand why I get error from create where i want to create a ticket ?
This is the contoller where my error comes from and it points on obj.Ticket.Ticket_Id == 0
public IActionResult Create(TicketVM obj)
{
if (obj.Ticket.Ticket_Id == 0)
{
_db.Tickets.Add(obj.Ticket);
}
else
{
_db.Tickets.Update(obj.Ticket);
}
}
This is the message i get:
System.NullReferenceException: 'Object reference not set to an instance of an object.'
WebApplication20.Models.TicketVM.Ticket.get returned null.
I try to create an application where I can create a project object that then you should be able to create tickets for, and inside my tickets i should be able to make comments for the specific ticket. To be able to do that, I have created a one to many relationship between project --> ticket then a one to many relationship between ticket --> comment.
This is what my ticket controller where im able to create update and delete Tickets look like:
[Authorize]
public class TicketController : Controller
{
private readonly ApplicationDbContext _db;
public TicketController(ApplicationDbContext db)
{
_db = db;
}
public IActionResult Index()
{
IEnumerable<Ticket> objList = _db.Tickets;
foreach (var obj in objList)
{
obj.Project = _db.Projects.FirstOrDefault(u => u.Project_Id == obj.Project_Id);
}
return View(objList);
}
/**This is the view i want to create my operation on**/
public IActionResult Info(int id)
{
CommentVM t = new CommentVM();
t.Ticket = _db.Tickets.FirstOrDefault(t => t.Ticket_Id == id);
t.Comments = _db.Commenents.Where(f => f.Ticket_Id == id);
return View(t);
}
// Create
public IActionResult Create(int? id)
{
TicketVM obj = new TicketVM();
obj.ProjectList = _db.Projects.Select(i => new SelectListItem
{
Text = i.Name,
Value = i.Project_Id.ToString()
});
if (id == null)
{
return View(obj);
}
// Status List
#region
List<SelectListItem> statusList = new List<SelectListItem>();
statusList.Add(new SelectListItem()
{
Value = "Open",
Text = "Open"
});
statusList.Add(new SelectListItem()
{
Value = "Closed",
Text = "Closed"
});
#endregion
// Status List End
if (obj == null)
{
return NotFound();
}
obj.Ticket = _db.Tickets.FirstOrDefault(u => u.Ticket_Id == id);
obj.StatusList = statusList;
return View(obj);
}
/**This is the controller where i get my error from:**/
// POST Create/Update
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(TicketVM obj)
{
if (obj.Ticket.Ticket_Id == 0)
{
_db.Tickets.Add(obj.Ticket);
}
else
{
_db.Tickets.Update(obj.Ticket);
}
_db.SaveChanges();
return RedirectToAction(nameof(Index));
}
// Delete
public IActionResult Delete(int? id)
{
var dbObj = _db.Tickets.FirstOrDefault(u => u.Ticket_Id == id);
_db.Tickets.Remove(dbObj);
_db.SaveChanges();
return RedirectToAction("Index");
}
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Comments(CommentVM obj)
{
if(ModelState.IsValid)
{
_db.Commenents.Add(obj.Comment);
_db.SaveChanges();
return RedirectToAction(nameof(Index));
}
return View();
}
}
At the bottom I have created a comment controller where I want to be able to add comments to the database. When I try to make a comment from my view that belongs to the InfoController in Ticket, I get an alarm that there is an error in my TicketController from Create / POST where it says 'Object reference not set to an instance of an object.' I do not understand at all why I get an error from Creaste / POST ticket?
This is what my Info view looks like
#model WebApplication20.ViewModel.CommentVM
#{
Layout = "_Dashboard";
var title = "About Ticket";
}
<html>
<body id="page-top">
<div class="card mx-auto" style="width: 18rem;">
<div class="card-header">
<h4><strong>Ticket Status</strong></h4> Created #Model.Ticket.TicketCreated
</div>
<ul class="list-group list-group-flush">
<li class="list-group-item"><strong>Name:</strong>#Model.Ticket.TicketName </li>
<li class="list-group-item"><strong>Descripton: #Model.Ticket.TicketDescription</strong></li>
<li class="list-group-item"><strong>Priority:</strong> #Model.Ticket.TicketPriority</li>
<li class="list-group-item"><strong>Type:</strong> #Model.Ticket.TicketType</li>
<li class="list-group-item"><strong>Status:</strong> #Model.Ticket.TicketStatus</li>
</ul>
</div>
<div class="card shadow mx-auto m-3" style="width: 42rem;">
<div class="card-header">
<h4><strong>Comments</strong></h4>
</div>
<div class="row">
<div class="col-md-4 p-4">
<form asp-action="Comments">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Message" class="control-label"></label>
<input asp-for="Message" class="form-control" />
<span asp-validation-for="Message" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Submit" class="btn btn-primary" />
</div>
</form>
</div>
</div>
#*TABLE*#
<div class="row">
<!-- Area Chart -->
<div class="col-xl-8 col-lg-7">
<div class="card shadow mb-4">
<!-- Card Header - Dropdown -->
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
<h6 class="m-0 font-weight-bold text-primary">Current Comments</h6>
</div>
#if (Model.Comments.Count() > 0)
{
<table class="table table-bordered table-striped" style="width:100%">
<thead>
<tr>
<th>
Message
</th>
<th>
Submitter
</th>
<th>
Created
</th>
</tr>
</thead>
<tbody>
#foreach (var comment in Model.Comments)
{
<tr>
<td width="10%">
#comment.Message
</td>
<td width="10%">
</td>
<td width="10%">
#comment.Created
</td>
</tr>
}
</tbody>
</table>
}
else
{
<h5 class="text-secondary m-1">There are no comments for this ticket yet..</h5>
}
</div>
</div>
</div>
#*END TABLE*#
</div>
<div class="text-center p-3">
<a asp-controller="Ticket" asp-route-Id="#Model.Ticket.Ticket_Id" asp-action="Create" class="btn btn-success btn-lg text-white w-30">Edit</a>
<a asp-controller="Ticket" asp-route-Id="#Model.Ticket.Ticket_Id" asp-action="Delete" class="btn btn-danger btn-lg text-white w-30">Delete</a>
</div>
<!-- Bootstrap core JavaScript-->
<script src="/TemplateInfo/vendor/jquery/jquery.min.js"></script>
<script src="/TemplateInfo/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
<!-- Core plugin JavaScript-->
<script src="/TemplateInfo/vendor/jquery-easing/jquery.easing.min.js"></script>
<!-- Custom scripts for all pages-->
<script src="/TemplateInfo/js/sb-admin-2.min.js"></script>
</body>
</html>
have you checked that TicketVM obj has data. I think your binding is not working and TicketVM obj is set to null. put a breakpoint and check it
I am working in an mvc problem and I found my self stuck in a problem trying to bind datetimepicker data to my controller action. I have a view that add a partial to collection of partial views when the user do some action.
My Models looks like
public class CreateOCVM
{
private string errors { get; set; }
public operaciones_confidenciales oc { get; set; }
[Display(Name = "Restringidas")]
public ICollection<PersonaMin> restringidas { get; set; }
public class PersonaMin
{
public int Id { get; set; }
public string motivo { get; set; }
[DataType(DataType.Date)]
public DateTime fecha_acceso;
In my view I have
#using (Html.BeginForm("CreateOC", "OC", FormMethod.Post, new { id = "form" }))
<table id="personasRestringidas" class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th>id</th>
<th>Motivo</th>
<th>Fecha de acceso</th>
<th>Eliminar</th>
</tr>
</thead>
<tbody id="person">
#foreach (PersonaMin item in Model.restringidas)
{
#Html.Partial("~/Views/OC/AddOCRestriccion.cshtml", item)
}
</tbody>
</table>
When user do some ation I add a new item to the ICOllection restringidas. By making an ajax call to a controller method as follows:
function addRestriccion(idPersona) {
if (jQuery.inArray(idPersona, dataset) != 0) {
$.get('/OC/AddOCRestriccion', { id: idPersona}, function (template) {
dataset.push(idPersona);
$("#person").append(template);
$('#datetimepicker' + idPersona).datetimepicker();
$('#datetimepicker' + idPersona).datetimepicker({ format: "DD/MM/YYYY hh:mm" });
$("#datetimepicker" + idPersona).on("change.dp", function (e) {
$('#fechaAcceso' + idPersona).val($("#datetimepicker" + idPersona).datepicker('getFormattedDate'))
});
});
}
This call a controller method an returns a partial view that will be added to the main view.
[HttpGet]
public ActionResult AddOCRestriccion(Int32 id)
{
PersonaMin item = new PersonaMin();
item.Id = id;
persona p = PersonaCollection.getPersonasById(id);
return PartialView("AddOCRestriccion", item);
}
Edit:
This controller returns the partial view to add in the main one.
<tr>
#using (Html.BeginCollectionItem("restringidas"))
{
<td>
#Html.HiddenFor(model => model.Id)
#Html.DisplayFor(model => model.Id, new { #placeholder = "id", #id = "ID" })
</td>
<td>
#Html.TextAreaFor(model => model.motivo, new { #placeholder = "motivo", #id = "motivo", #class = "form-control" })
</td>
<td>
<div class='input-group date' id="#("datetimepicker" + Model.Id)">
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
#Html.HiddenFor(model => model.fecha_acceso, new { #id = "fechaAcceso" + Model.Id })
</div>
</td>
<td class="text-center">
<span class="input-group-btn">
<button type="button" class="btn btn-primary" onclick="deleteAnother($(this).parent().parent())">
<i class="fa fa-minus"></i>
</button>
</span>
</td>
}
When I submit the form it is handled by the controller action
[HttpPost]
public ActionResult CreateOC(CreateOCVM ocvm)
{ ... do something ....
The problem is that when i check the values on my model all the values are ok but not the one for the datetime (fecha_acceso)
In my view the hidden field for my datetime property has value on it.
But the value change when i check it on the controller method.
I tried with diferent aproaches but i always get wrong data on my controller method. Does somebody knows what is happening? Or has somebody a different aproach that can help me to do the same?
Thanks.
By default controller doesn't allow date format as dd-mm-yyyy.
Add below lines in your web.config file to do it
<configuration>
<system.web>
<globalization culture="en-GB" />
</system.web>
</configuration>
Looks like my Html.BeginCollectionItem helper has problems with DateTime so y change de type of my viewmodel from datetime to string. I know it is a workaround and not the correct solution but the lack of time force me to do it.
I am encountering the following error:
A data source must be bound before this operation can be performed.
I have a text box, the user enters a name, and clicks the submit button. The name is added to a list. I have researched the error but everything I try gives me the same error. Any insight on what I am doing wrong will be appreciated.
Model:
namespace RangeTest.Models
{
public class UserNameModel
{
[Key]
public int Id { get; set; }
[Display(Name = "Names Added List")]
public string FullName { get; set; }
}
}
Controller:
public ActionResult Admin()
{
return View();
}
[HttpPost]
public ActionResult Admin(UserNameModel model, IEnumerable<RangeTest.Models.UserNameModel> t)
{
List<UserNameModel> userList = new List<UserNameModel>();
model.FullName = t.FirstOrDefault().FullName;
userList.Add(model);
return View(userList.ToList());
}
View (Admin.cshtml):
#model IEnumerable<RangeTest.Models.UserNameModel>
#{
ViewBag.Title = "";
}
<div class="container"></div>
<div class="jumbotron">
#using (Html.BeginForm("Admin", "UserNames", FormMethod.Post, new { #id = "WebGridForm" }))
{
#Html.ValidationSummary(true)
WebGrid dataGrid = new WebGrid(Model, canPage: false, canSort: false);
//Func<bool, MvcHtmlString> func =
//(b) => b ? MvcHtmlString.Create("checked=\"checked\"") : MvcHtmlString.Empty;
<div class="table-bordered">
<div class="Title">Admin - Add names to range list</div><br />
<table id="TblAdd"class="table">
<tr>
#{
RangeTest.Models.UserNameModel t = new RangeTest.Models.UserNameModel();
}
#Html.Partial("_AddDynTable", t)
</table>
</div>
<div class="table-responsive">
<div class="Title">Names Added to Range List</div>
<table class="table">
<tr>
<td >
#dataGrid.GetHtml(columns: dataGrid.Columns(dataGrid.Column(format: #<text>#item</text>),
dataGrid.Column("", format: (item) => Html.ActionLink("Delete", "Delete", new { id = item.id }))))
</td>
</tr>
</table>
</div>
}
</div>
Partial View (_addDynTable.cshtml)
#model RangeTest.Models.UserNameModel
<tr>
<td>
Enter Full Name: #Html.TextBoxFor(m => m.FullName)
#*<input type="button" value="Create" id="ClickToAdd" />*#<input class="CreateBtn" type="submit" value="Add to List" /></td>
</tr>
Can you link info about the error please?
One thing I can see is your t object is null when you pass it to the partial view
RangeTest.Models.UserNameModel t = new RangeTest.Models.UserNameModel();
A new UserNameModel with no data in it, if your error is there that might be the problem
How do I get the drop down to display as part of my editor template?
So I have a Users entity and a Roles entity. The Roles are passed to the view as a SelectList and User as, well, a User. The SelectList becomes a drop down with the correct ID selected and everything thanks to this sample.
I'm trying to get an all-in-one nicely bundled EditorTemplate for my entities using MVC 3 so that I can just call EditorForModel and get the fields laid out nicely with a drop down added whenever I have a foreign key for things like Roles, in this particular instance.
My EditorTemlates\User.cshtml (dynamically generating the layout based on ViewData):
<table style="width: 100%;">
#{
int i = 0;
int numOfColumns = 3;
foreach (var prop in ViewData.ModelMetadata.Properties
.Where(pm => pm.ShowForDisplay && !ViewData.TemplateInfo.Visited(pm)))
{
if (prop.HideSurroundingHtml)
{
#Html.Display(prop.PropertyName)
}
else
{
if (i % numOfColumns == 0)
{
#Html.Raw("<tr>");
}
<td class="editor-label">
#Html.Label(prop.PropertyName)
</td>
<td class="editor-field">
#Html.Editor(prop.PropertyName)
<span class="error">#Html.ValidationMessage(prop.PropertyName,"*")</span>
</td>
if (i % numOfColumns == numOfColumns - 1)
{
#Html.Raw("</tr>");
}
i++;
}
}
}
</table>
On the View I'm then binding the SelectList seperately, and I want to do it as part of the template.
My Model:
public class SecurityEditModel
{
[ScaffoldColumn(false)]
public SelectList roleList { get; set; }
public User currentUser { get; set; }
}
My Controller:
public ViewResult Edit(int id)
{
User user = repository.Users.FirstOrDefault(c => c.ID == id);
var viewModel = new SecurityEditModel
{
currentUser = user,
roleList = new SelectList(repository.Roles.Where(r => r.Enabled == true).ToList(), "ID", "RoleName")
};
return View(viewModel);
}
My View:
#model Nina.WebUI.Models.SecurityEditModel
#{
ViewBag.Title = "Edit";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Edit</h2>
#using(Html.BeginForm("Edit", "Security"))
{
#Html.EditorFor(m => m.currentUser)
<table style="width: 100%;">
<tr>
<td class="editor-label">
User Role:
</td>
<td class="editor-field">
<!-- I want to move this to the EditorTemplate -->
#Html.DropDownListFor(model => model.currentUser.RoleID, Model.roleList)
</td>
</tr>
</table>
<div class="editor-row">
<div class="editor-label">
</div>
<div class="editor-field">
</div>
</div>
<div class="editor-row"> </div>
<div style="text-align: center;">
<input type="submit" value="Save"/>
<input type="button" value="Cancel" onclick="location.href='#Url.Action("List", "Clients")'"/>
</div>
}
Hopefully that's clear enough, let me know if you could use more clarification. Thanks in advance!
Since you need access to the SelectList you can either create an editor template bound to SecurityEditModel or you can pass the SelectList in ViewData. Personally I would go with the strongly typed approach.