Index error in my code controller? - javascript

When I run my project index, it shows this error. I have googled it but I have not found a proper solution for this error. So, please someone help me.
The Error message:
"The parameters dictionary contains a null entry for parameter
'chapterIdS' of non-nullable type 'System.Int32' for method
'System.Web.Mvc.ActionResult Index(Int32)' in
'opr.Controllers.QuizeController'. An optional parameter must be a
reference type, a nullable type, or be declared as an optional
parameter.
Parameter name: parameters"
This is my Index code:
#model List<opr.Data.Chapter>
#{
ViewBag.Title = "Index";
}
<h4>Select Chapter</h4>
<div class="container">
<div class="alert-info form-control m-auto w-75 custom-form col-6">
#using (Html.BeginForm("Index", "Quize", FormMethod.Get))
{
<h4>Quizes</h4>
<hr />
foreach (var std in Model)
{
<div class="row">
<div class="col-4"></div>
<div class="col-4">
#Html.RadioButton("searchBy",#std.Chapter_Name, true)
<text>#std.Chapter_Name</text>
</div>
<div class="col-4"></div>
</div>
<hr />
<h3>Questions</h3>
<hr />
<table>
<tbody>
#foreach (var quesion in std.C_QuestionTable)
{
<tr>
<td>
<h5>#quesion.QuestionText</h5>
</td>
</tr>
foreach (var answer in quesion.C_AnswerTable)
{
<tr>
<td>#answer.Options</td>
</tr>
}
}
</tbody>
</table>
}
<input type="submit" value="Create Question" />
}
</div>
</div>
this my controller
public class QuizeController : Controller
{
examsEntities db = new examsEntities();
public ActionResult Index(int chapterIdS)
{
List<C_QuestionTable> ques = new List<C_QuestionTable>();
ViewBag.ques = db.C_QuestionTable.Where(w => w.Id == chapterIdS).ToList();
List<Chapter> model = new List<Chapter>();
model = db.Chapters.Where(w=>w.Id==chapterIdS).ToList();
return View(model);
}
}

Default route expects optional parameter named id:
public ActionResult Index(int id)
{
...
}
Therefore, if your url looks like .../Quize/Index/1 you need to call this parameter id, or register your own route for this controller.

Try with this...
public ActionResult Index(int? chapterIdS)
{
List<C_QuestionTable> ques = new List<C_QuestionTable>();
ViewBag.ques = db.C_QuestionTable.Where(w => w.Id == chapterIdS).ToList();
List<Chapter> model = new List<Chapter>();
model = db.Chapters.Where(w=>w.Id==chapterIdS).ToList();
return View(model);
}
Now parameter will accept the null value.

Related

Dynamic row add & delete in html table in Blazor web assembly

I am developing a blazor webassembly app where i have this feature to add or delete html row. Can we do it easily in Blazor? or we have to go for javascript? Thanks in advance
I am looking for some output like this or anything similar to my requirement. Any link to such solution also should be helpful. Just the example image:
Something like this?
<table style="width:100%">
<tr>
<th>Name</th>
<th>Value</th>
<th>Command</th>
</tr>
#foreach(var model in models)
{
<tr>
<td>#model.Name</td>
<td>#model.Value</td>
<td>
<button #onclick="() => models.Remove(model)">
X
</button>
</td>
</tr>
}
</table>
<button #onclick="#(() => models.Add(new Model(){Name = nameTextField, Value = Int32.Parse(valueTextField)}))">
New value
</button>
<div>
Name: <input #bind="#nameTextField" #oninput="(e)=> { nameTextField = e.Value ==null? string.Empty:(string)e.Value; }" />
</div>
<div>
Value: <input type="number" #bind="#valueTextField" #oninput="(e)=> { valueTextField = e.Value ==null? string.Empty:(string)e.Value; }" />
</div>
#code {
string nameTextField = "";
string valueTextField = "";
List<Model> models = new()
{
new Model(){Name="Row1",Value = 1},
new Model(){Name="Row2",Value = 2}
};
}
Model.cs:
public class Model
{
public string Name {get;set;}
public int Value {get;set;}
}
Working demo.

Serialized select2 value not available in the controller of asp.net mvc

I have a view which has multiple controls inside a div which I want to serialize and pass it to the controller via AJAX.The SchoolType field in the view is a select2 multi select dropdown.
Model :
public class SchoolModel
{
public string StudentName{ get; set; }
public List<string> SchoolType{ get; set; }
public List<SelectListItem> SchoolTypeList{ get; set; }
}
View :
<div id="divSchool">
<div class="row">
<div class="col-md-12">
<div class="col-md-6">
<div class="form-group">
<label asp-for="SchoolType" class="col-md-3 control-label">School Type</label>
<div class="col-md-9">
<select asp-for="SchoolType" asp-items="Model.SchoolTypeList" class="form-control medium"></select>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label asp-for="StudentName" class="col-md-3 control-label">Student Name</label>
<div class="col-md-9">
<input asp-for="StudentName" class="form-control" />
</div>
</div>
</div>
</div>
</div>
</div>
Controller:
[HttpPost]
public ActionResult Index(SchoolModel model)
{
}
My JS Code:
$('#SchoolType').select2({
placeholder: "Filter by school"
}
$("document").on("click", ".btnCheck", function () {
var model = $('#divSchool').find('select, textarea,input').serialize();
$.ajax({
url: "/Student/Index",
type: 'POST',
data: { model: model },
cache: true,
async: true,
}).done(function (result) {
}).fail(function (error) {
})
});
However the serialized div appears something like
model = "StudentName=Test&SchoolType=1b&SchoolType=26a"
While these values are right on the client side, on AJAX the StudentName value appears fine whereas the SchoolType value appears as null on the server side in the controller. How do I fix this?
Possible issue: Because the SchoolType value is a List of string, it's not getting mapped to the individual strings.
EDIT 1: I tried to change the div into form but the same issue persists.
EDIT 2: This issue is handled in PHP by changing the select name. This answer shows an example.
While I am not sure you can manipulate the serialization part; you can get that structure manually.
You can serialize other controls like how you are doing using serialize() and assign it to model. And for the Select2, do it this way and add it to the model.
model = {};
$(".select2").each(function () {
var selectedValue = $(this).val();
if (selectedValue != null) {
model[this.name] = selectedValue;
}
});
This will give you the structure you need.

How do I retrieve a viewmodel from another viewmodel?

I have this ViewModel which incorporates 3 other viewmodels and a list:
public class GroupPageViewModel{
public string GroupName { get; set; }
public GroupSelectViewModel _groupSelectVM {get; set;}
public List<User> _users { get; set; }
public ViewModelStudent _studentVM { get; set; }
public ViewModelGroupMembers _groupMembersVM { get; set; }
}
In the view I can access each of these sub-ViewModels by Model._groupSelectVM, each of the sub-ViewModels are associated with a partial view. The problem arises when I need to refresh just one or two partial views, I'm not sure how to access the inner ViewModels returned in an Ajax success, and as I'm relatively new to MVC and asp.net in general. And I literally know next to nothing about JavaScript, jquery or Ajax.
How would I go about getting a specific ViewModel from the main ViewModel in an Ajax success?
This is just one example for the clarification requested all the others are pretty much the same (although some of them might need to update mutliple partial views -
From the controller:
[HttpPost]
public ActionResult Index(string groupChoice = "0", string newGroup = "")
{
string groupName = "";
if (groupChoice == "0" && newGroup != "")
{
if (ModelState.IsValid)
{
Group group = new Group
{
GroupName = newGroup,
Active = true
};
db.Groups.Add(group);
db.SaveChanges();
PopulateLists();
}
}
else if (groupList == null)
{
groupList = (List<SelectListItem>)Session["groupList"];
Session["groupName"] = groupName = groupList.Where(m => m.Value == groupChoice).FirstOrDefault().Text;
MembersInSpecificGroup(groupName, groupMembers, groupMembersList);
groupPageVM._groupMembersVM = groupMembers;
}
return View("GroupSelection", groupPageVM);
}
The script:
$(document).ready(function () {
$('#selectedGroup').change(function () {
var data = {
groupChoice: $('#selectedGroup').val()
};
var groupChoice = $('#selectedGroup').val();
$.ajax({
url: '/Group/Index/',
type: 'POST',
data: { groupChoice: groupChoice },
success: function (data) {
setTimeout(function () {
delayGroupSuccess(data);
}, delay);
}
});
})
});
function delayGroupSuccess(data) {
$("#groupSelect").html(data);
}
The main page:
#model EMBAProgram.ViewModels.GroupPageViewModel
#{ Layout = "~/Views/Shared/_Layout.cshtml"; }
<h2>Group Selection</h2>
<div class="row" id="groupSelect">
#{ Html.RenderPartial("_GroupSelect", Model._groupSelectVM);}
</div>
<hr size="5" />
<div style="display: flex;">
<div>
#{Html.RenderPartial("_Students", Model._studentVM);}
</div>
<div>
#{ Html.RenderPartial("_GroupMembers", Model._groupMembersVM);}
</div>
<div>
#{ Html.RenderPartial("_Users", Model._users);}
</div>
<br style="clear: left;" />
</div>
The partial view:
#model EMBAProgram.ViewModels.ViewModelGroupMembers
<div class="table-responsive" id="groupResults">
<table class="table table-condensed table-responsive">
<thead>
<tr>
<th>#Html.DisplayName("M-Number")</th>
<th>#Html.DisplayName("Name")</th>
<th>#Html.DisplayName("Student")</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model._groupVM) {
<tr>
<td>#Html.DisplayFor(m => item.MNumber)</td>
<td>#Html.DisplayFor(m => item.Name)</td>
<td>#Html.DisplayFor(m => item.Student)</td>
</tr>
}
</tbody>
</table>
</div>
Basically I need to be able pull the ViewModel for the partial view from the main ViewModel (which I believe is what is being returned in the Ajax,) and refresh the partial view.
I removed the original answer, it's available in the edit log if folks want to see it I think. But it was taking up too much space and was incorrect.
You can return multiple partial views, I thought it was a built in way to get them to a string (I was in a rush in my comment), but I've got a working example.
In the controller I have the following:
public ActionResult Index()
{
var model = new TestViewModel
{
Students = GetStudents(),
Categories = GetCategories(),
Groups = GetGroups()
};
return View("Index", model);
}
// Returns multiple partial views as strings.
public ActionResult StudentsAndGroups()
{
return Json(new
{
Students = RenderRazorViewToString("_Students", GetStudents()),
Groups = RenderRazorViewToString("_Groups", GetGroups())
}, JsonRequestBehavior.AllowGet);
}
// Creates a string from a Partial View render.
private string RenderRazorViewToString(string viewName, object model)
{
ControllerContext.Controller.ViewData.Model = model;
using (var stringWriter = new StringWriter())
{
var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
var viewContext = new ViewContext(ControllerContext, viewResult.View, ControllerContext.Controller.ViewData, ControllerContext.Controller.TempData, stringWriter);
viewResult.View.Render(viewContext, stringWriter);
viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View);
return stringWriter.GetStringBuilder().ToString();
}
}
I have my main index view that looks like the following:
<button class="refresh">Refresh</button>
<div class="row">
<div class="col-md-4 students">
#{
Html.RenderPartial("_Students", Model.Students);
}
</div>
<div class="col-md-4">
#{
Html.RenderPartial("_Category", Model.Categories);
}
</div>
<div class="col-md-4 groups">
#{
Html.RenderPartial("_Groups", Model.Groups);
}
</div>
</div>
#section scripts
{
<script type="text/javascript">
$(".refresh").click(function () {
$.get("/Home/StudentsAndGroups", function (d) {
$(".students").html(d.Students);
$(".groups").html(d.Groups);
})
});
</script>
}
The controller action StudentsAndGroups turns two partial views into strings. From there, the javascript calls that view and accesses the elements and returns them.
Helper method for rendering a view as a string was found here: https://stackoverflow.com/a/34968687/6509508

How to get Model value in javascript function and pass it to controller?

I have a Model on my CSHTML page that which I use this way:
#model Web.Models.Element
#using (Html.BeginForm("Search", "Company"))
{
#Html.HiddenFor(c => c.Person)
<div class="panel panel-default">
<div class="panel-heading"> Company Search</div>
<div class="panel-body collapse" id="screenCompanySearch">
<form id="formSearch" name="formSearch" method="post">
<fieldset style="margin: 20px;">
<legend>Search</legend>
<div class="row">
<div class="col-xs-2 col-sm-2">
#Html.Label("Company Name")
#Html.TextBoxFor(c => c.Company.Name, new { #class = "form-control" })
</div>
</fieldset>
</form>
</div>
</div>
My Javascript function is called by a button click this way:
$("#btnSearch").on("click", function() { searchCompany(); })'
In my JavaScript function I need to get this Model entirely loaded with the TextBoxFor values:
<script type="text/javascript">
function searchCompany() {
var data = $("#formSearch").serialize();
$.ajax({
url: "#(Url.Action("SearchCompany", "Company"))",
cache: false,
data: data,
type: "POST",
success: alert("sucesso!")
});
}
</script>
My Controller method is being loaded correctly, but the model passed in the Ajax "data" parameter is not filled with the TextBoxFor values.
This is my Controller ActionResult for the View:
public ActionResult Consulta()
{
Element model = new Element();
model.Person = new Person();
return View(model);
}
What is happening is that my Model is being instantiated on my Controller but the values from the TextBoxFor is not recorded on the properties of the Model.
How can I solve this? Thanks for now.
UPDATED
<div class="col-xs-2 col-sm-2">
#Html.Label("Person Name")
#Html.TextBoxFor(c => c.Person.Name, new { #class = "form-control" })
</div>
So, 'c' equals my Element object. When I reach the Controller Method "Search", the parameter Element passed via ajax call does not instantiate the Element.Person which gives me Person = null.
In my ActionResult I have:
Element model = new Element();
model.Person = new Person();
Element class:
public Element()
{
this.Contacts = new List<Contact>();
this.DataType = new DataType();
}
public int ID_Element { get; set; }
public int ID_ElementType { get; set; }
public virtual List<Contact> Contacts { get; set; }
public virtual DataType DataType { get; set; }
public virtual Person Person {get; set; }
Controller Action
[HttpPost]
public JsonResult SearchCompany(Element model)
{
...
}
The serialize method is not giving your the serialized version of the form because you have nested form tags.
The #using (Html.BeginForm("Search", "Company")) will create an outer form tag and you have your other form inside that, hence creating a nested form structure. Nested forms are invalid. You can have 2 forms in the same page, parallel to each other, not nested.
If you fix the nested form issue, the serialize method will give you valid string for you form inputs.
#using (Html.BeginForm("Search", "Company"))
{
<!-- Your other form -->
}
<form id="formSearch" name="formSearch" method="post">
<fieldset style="margin: 20px;">
<legend>Search</legend>
<div class="col-xs-2 col-sm-2">
#Html.Label("Company Name")
#Html.TextBoxFor(c => c.Company.Name, new { #class = "form-control" })
</div>
</fieldset>
</form>
Keep in mind that, the serialize method will give you the input element values of items inside this specific form. If you want to send some other data (ex : Id), you need to keep that in an input field inside this form.

getting modelbound object property in jquery

My viewmodel contains a list of objects that I'm iterating through, and each one has a certain class associated with them. My goal is on click of that item to open it up to view, but I'm unclear on how to get the id of that row in my jquery click function.
foreach (var item in Model.PatientViewModel)
{
<div class="patientBox patientBox-unselected">
<h7>
<div class="pvb-mrn">MRN: #Html.DisplayFor(modelItem => item.MRN)</div>
<div class="pvb-dob">DOB: #Html.DisplayFor(modelItem => item.DOB)</div>
<br />
<div class="pvb-link">
#Html.ActionLink("Update Patient >", "Edit", new { id = item.PatientID })
</div>
</h7>
</div>
}
and then my script with a test alert just to ensure i was hitting the function, which works fine, but how can I get the ID of the clicked item here?
$('.patientBox').click(function () {
window.location.href("/View/" + #item.ID);
})
view model:
public class PatientScreenViewModel
{
public List<PatientDTO> PatientViewModel { get; set; }
public PatientSearchDTO SearchViewModel { get; set; }
}
Put the item.ID in html Attribute and get it with jQuery like so:
foreach (var item in Model.PatientViewModel){
<div class="patientBox patientBox-unselected" data-item-id="<%= item.ID %>">
...
...
</div>
}
jQuery:
$('.patientBox').click(function () {
window.location.href("/View/" + this.getAttribute('data-item-id');
})

Categories

Resources