Populate DropDownList from Azure Database in MVC - c#

I am still new to MVC and working my way around it. I need to get the "name" column of my district table into a dropdownlist to be able to pick from different Districts. The end game is that the user will pick a District from the dropdownlist and then be directed to a page where a list of schools(in a different table) will be shown with the selected district (i think that would be a query on the database using the value given from the dropdownlist). Basically what I have done so far is:
Create an MVC Application.
Create a Entity Framework Model.
Create an empty controller.
Create a view model(since every tutorial/ site answer has said to do
so)
Create a view.
I replicate step by step what these tutorials are telling me to do, but I get a different result. My dropdownlist gives me this outcome:
I need help sorting out what could be going wrong and why the data is not showing up in my dropdownlist.

Try I believe you are using the wrong SelectList constructor. Assuming you want the value of the drop down list to be the "leaID" property
#Html.DropDownList("myList", new SelectList(ViewBag.districts, "leaId", "name")
I would however, approach it another way which will keep it mostly strongly typed:
public class DistrictViewModel
{
public string SelectedDistrictId { get; set; }
public IEnumerable<SelectListItem> Districts { get; set; }
}
Action:
public ActionResult Index()
{
var viewModel = new DistrictViewModel()
{
Districts = new SelectList(db.Districts.ToList(), "leaID", "name")
}
return View(viewModel);
}
cshtml:
#model DistrictViewModel
#Html.DropDownListFor(m => m.SelectedDistrictId, Model.Districts)

Here is my answer to your comment using ajax
//Model
public class DistrictViewModel
{
public string name {get;set;}
public SelectList District {get;set;}
public int SelectedDistrict {get;set}
}
//Controller
public class DistrictController : Controller
{
KUDEREntities db = new KUDEREntities();
public ActionResult Index()
{
var model = new DistrictViewModel();
model.Districts = db.Districts.ToList();
model.SelectedDistrict=0;
return view(model);
}
[HttpPost]
public ActionResult Search(int id)
{
//do the search with the id of the selected district
var data = db.Districts.Where(m=>m.leaId = id).FirstorDefault();//this would return the whole object.
return Json(data, JsonRequestBehavior.AllowGet);
}
}
//Index View
#Model DistrictViewModel
<div>
//with this your selector would be "#SelectedDistrict"
#Html.DropDownListFor(model=>model.SelectedDistrict, new SelectList(Model.Districts,"leaId","name",Model.SelectedDistrict), new {#class=""})
//with this your selector would be "#myList"
//#Html.DropDownList("myList", new SelectList(ViewBag.districts, "leaId", "name", Model.SelectedDistrict)
</div>
<script>
$(document).ready(function(){
//when you want to search for the id selected, you just need to call the Search function below
function Search() {
//... now you have the value of the selecteditem
var parameters = { id: $("#SelectedDistrict").val() };
$.ajax({
type: 'post',
url: '#Url.Action("Search", "District")',
cache: false,
contentType: "application/json; charset=utf-8",
dataType: "html",
async: true,
data: JSON.stringify(parameters),
success: function (data) {
//...do whatever with the data
},
failure: function (msg) {
//... show a message of error
}
});
}
});
</script>

Related

[dotNET Core]Passing model to view -> bind checkbox with it's data in POST method form -> sending whole model to controller

I need some help. I am trying to pass ShowSeatsViewModel to Seats.cshtml bind it with passed view model's field and send it back with new values to controller.
ViewModel :
using System.Collections.Generic;
namespace theatre_dotNET.Models
{
public class SpectacleShowsViewModel : Spectacle
{
public List<Show> IncomingShows { get; set; }
public Show pickedShow { get; set; }
public int[] availableSeats { get; set; }
public int[] bookedSeats { get; set; }
public SpectacleShowsViewModel(Spectacle s, List<Show> incomingShows)
{
this.SpectacleId = s.SpectacleId;
this.Title = s.Title;
this.Description = s.Description;
this.Price = s.Price;
this.VideoLink = s.VideoLink;
this.Rating = s.Rating;
IncomingShows = incomingShows;
}
}
}
Two methods of controller :
[Authorize]
public IActionResult Seats(Show chosenShow)
{
int[] availableSeats = _context.Seats.Select(s => s.SeatId).ToArray();
int[] bookedSeats = _context.BookedSeats.Where(i => i.ShowId == chosenShow.ShowId).Select(s => s.SeatId).ToArray();
return View(new ShowSeatsViewModel(chosenShow, availableSeats, bookedSeats));
}
[Authorize]
[HttpPost]
public IActionResult Seats(ShowSeatsViewModel chosenShowSeatsViewModel)
{
return Content("Picked seats : "+chosenShowSeatsViewModel.PickedSeats);
}
View:
#model ShowSeatsViewModel
<h1>Chosen Spectacle : Model.SpectacleId</h1>
<form asp-controller="Booking" asp-action="Seats" method="post">
<div class="row">
#foreach(var seat in Model.AvailableSeats)
{
#if(Model.UnavailableSeats.Contains(#seat))
{
<div class="col">
#Html.CheckBoxFor(m=>m.PickedSeats[#seat-1])
#Html.LabelFor(m=>m.PickedSeats[#seat-1],#seat.ToString())
</div>
}
else
{
<div class="col">
#Html.CheckBoxFor(mdl => mdl.PickedSeats[#seat-1])
#Html.LabelFor(mdl => mdl.PickedSeats[#seat-1],#seat.ToString())
</div>
}
}
</div>
<button type="submit">Submit</button>
</form>
And an error - after choosing checkboxes and clicking submit button:
InvalidOperationException: Could not create an instance of type 'theatre_dotNET.Models.ShowSeatsViewModel'. Model bound complex types must not be abstract or value types and must have a parameterless constructor. Alternatively, give the 'chosenShowSeatsViewModel' parameter a non-null default value.
How could I send existing(passed from Controller) ViewModel via post method? Is it possible?
EDIT: I'm updating my answer.
In your case, you can't model bind to that Object without custom model binding.
It's a complex object that doesn't have a parameterless constructor.
You need to have all of the properties in the form to pass the entire model with. As you stated that's not what you want.
In your case a custom model binder is a complex implementation that you would have to do over and over throughout the app. I wouldn't recommend this approach.
On the client side I would use a library like JQUERY to perform the post for complex objects.
Here is an example.
Create a JS script to run these POST requests with complex objects with the following function.
Here is an example with JQuery
function ajaxRequest(httpVerb, url, model, onSuccess, onFail, onComplete) {
if (httpVerb === null || httpVerb.length === 0) httpVerb = "POST";
$.ajax({
url: url,
type: httpVerb,
cache: false,
traditional: true,
data: JSON.stringify(model),
dataType: "json",
contentType: 'application/json; charset=utf-8'
}).done(function (data) {
//onSuccess()...
}).fail(function (err) {
//onFail()...
}).always(function (data) {
//onComplete()...
});
}
Here is how you would call it
var model = #Html.Raw(Json.Encode(Model)); //this gets your view model and converts it to a JS object.
//Or you can take the time and create it manually
var model = {...}
//take the form values and replace the model properties as needed
// make sure to give your HTML elements in the forms ID attributes so you can select them.
model.PickedSeats = $('#myCheckboxById').is(':checked');
...
// do the same with the other form values
ajaxRequest("POST", "/Booking/Seats", model , null, null, null);
//the null values being passed in are the callback functions you would perform in the method signature. I just left them null to simplify things.

How return list object to show in view

I have controller where I use service. That service do some querys and return List like this:
Controller:
public ActionResult GetTareas(string tiporesponsable, int responsableID, int? cuadrillaID, int? sucursalID, int regionID, int solicitudID, string chkFinalizadas)
{
var consulta = ag.ConsultarAgenda(tiporesponsable, responsableID,
cuadrillaID, sucursalID, regionID, solicitudID, chkFinalizadas);
return View();
}
Now I want to get some value of that service (ag.ConsultarAgenda) for example: "SucursalCodigo" and receive into view into div like:
<div id="event_box" class="margin-bottom-10"></div>
Can anyone explain me how can I do it? Regards
Can I do sending Json? like:
return Json(consulta, JsonRequestBehavior.AllowGet);
but How can I receive specific object into view?
ASP.NET MVC offers us several options for passing data from controller to view upon request, one of them is ViewBag.
As of your example above you can do the following in the controller part:
public ActionResult GetTareas(string tiporesponsable, int responsableID, int? cuadrillaID, int? sucursalID, int regionID, int solicitudID, string chkFinalizadas)
{
ViewBag.ConsultarAgenda = ag.ConsultarAgenda(tiporesponsable, responsableID,
cuadrillaID, sucursalID, regionID, solicitudID, chkFinalizadas);
return View();
}
And in the view :
<div id="event_box" class="margin-bottom-10">#ViewBag.ConsultarAgenda</div>
The best practice to consume Json is via AJAX on the frontend(The View):
<script type="text/javascript">
$.ajax({
url: '#Url.Action("GetTareas", "ControllerName")',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data){
//consume the returned data here
$(".margin-bottom-10").html(data);
},
error: errorFunc});
</sript>
<div id="event_box" class="margin-bottom-10"></div>
A ViewBag should work:
#ViewBag.TexttoLargo
You may want to parse the ViewBag result as it it looks like it is terminated with a return.
As Mike McCaughan mentioned you should go throught some tutorials.
You have multiple options based on this
ViewBag
The ViewBag is a dynamic object that provides a convenient late-bound way to pass information to a view
#model Keyword
Strongly typed class.
example
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Movie movie = db.Movies.Find(id);
if (movie == null)
{
return HttpNotFound();
}
return View(movie);
}
then accessing model in view:

.NET MVC jQuery AJAX - JSON object as parameter not serializing values

I'm trying to figure out how to simply pass a JSON object into a controller method param. I'll often use JSON.serialize() when posting forms and the serialization to C# is automatic. However, I'm struggling to get this to work using GET while trying to load a partial.
I built a small sample project as a basic simulation of what I need, which is a controller method that accepts an int param and a separate model class, which I'd like to pass in as JSON. The partial html response is loaded into a div.
The view:
<div class="row">
Loading a partial via Ajax, passing a JSON object as a param!
</div>
<div class="row">
<div id="peoplePartial"></div>
</div>
#section Scripts {
<script>
$(function() {
var id = 1;
var person = {
Name: "Homer Simpson",
Age: 45
};
load(id, person);
});
function load(id, person) {
$.ajax({
cache: false,
type: "GET",
dataType: "html",
url: '/Home/PeoplePartial',
data: {
id: id,
person: JSON.stringify(person)
}
}).done(function(data) {
$("#peoplePartial").html(data);
}).fail(function(data) {
console.log(data.responseText);
});
}
</script>
}
The partial:
#model MVCLearning.Models.PeoplePartialModel
<div>
<span>Person found! Name is #Model.Person.Name</span>
</div>
The partial ViewModel:
public class PeoplePartialModel {
public int Id { get; set; }
public PersonModel Person { get; set; }
}
The data model/entity I'm trying to serialize:
public class PersonModel {
public string Name { get; set; }
public int Age { get; set; }
}
And finally, the controller:
public class HomeController : Controller {
public ActionResult Index() {
return View();
}
public ActionResult PeoplePartial(int id, PersonModel person) {
if (person != null) {
var model = new PeoplePartialModel {
Id = id,
Person = person
};
return PartialView("_People", model);
} else {
throw new System.Exception("An Error Has occoured");
}
}
}
The "id" param always works, of course, but the PeopleModel param is always null when using JSON.stringify(). I would have expected it to serialize to the model and contain the JSON values I passed in from the JS in the view. I can fix this by not using JSON.stringify() but then the values are always ignored e.g. always passed in as Name: null, Age: 0. I just can't seem to pass values like this.
I've tried changing the ajax call to POST but it changes nothing. I've tried setting the contentType to html and json, neither change anything.
Thanks in advance.
I got it. Here's the magic combination of properties:
function load(id, person) {
$.ajax({
type: "POST",
dataType: "html",
url: "/Home/PeoplePartial",
data: {
id: id,
person: person
}
}).done(function(data) {
$("#peoplePartial").html(data);
}).fail(function(data) {
console.log(data.responseText);
});
}
I think one of the variations I had tried was POST with the contentType set. That throws an error saying both controller method params are null, strangely. I also could have omitted dataType on this and it works. I could not get any variation of GET to work, even though GET is what I'm trying to do. I'd really like to know why this is the case.

How to preserve cascading dropdownlist items after httppost if form has invalid ModelState

I have three dropdown (cascaded) in a View. First dropdown elements come from the ViewModel. I'm populating 2nd dropdown elements when 1st dropdown changes. and same for the 3rd dropdown. Classic cascading dropdownlist example you can find on anywhere (ex: http://www.c-sharpcorner.com/UploadFile/4d9083/creating-simple-cascading-dropdownlist-in-mvc-4-using-razor/ )
Problem occurs when user submits the form. If ModelState is invalid, 2nd and 3rd dropdown loses their items and 1st dropdown conserves its state. I understand why they behave like that but can't figure it out how to populate them again with the users selected values.
Scenario
User request /Country/Index
After page loaded, user selects CountryId DropDownList
Send Country Id to method and if result is not null, load StateId DropDownList.
Do not fill PostalCode Textbox and submit form.
Examine that CountryId DropDownlist is filled and selected but StateId ropdownlist is empty.
Cry
View
//HTML Code
//...
#Html.DropDownListFor(m => m.CountryId, ViewBag.Country as IEnumerable<SelectListItem>, "Select Country")
#Html.DropDownListFor(m => m.StateId, new SelectList(string.Empty, "Value", "Text"), "Select State")
#Html.DropDownListFor(m => m.CityId, new SelectList(string.Empty, "Value", "Text"), "Select City")
#Html.TextBoxFor(m=> m.PostalCode)
<script type="text/javascript">
var countryDDL = $("#CountryId");
countryDDL.change(function () {
$.ajax({
type: 'POST',
url: '#Url.Action("LoadStateList")',
dataType: 'json',
data: { countryId: countryDDL.val() },
success: function myfunction(states) {
$("#StateId").empty();
$.each(states, function (i, state) {
$("#StateId").append('<option value="' + state.Value + '">' + state.Text + '</option>');
}); }
});
return false;
});
//Code for 2nd (state) dropdownlist.change() method.
//...
</script>
Controller
public ActionResult Index()
{
ViewBag.CountryList = LoadCountryList();
return View();
}
[HttpPost]
public ActionResult Index(CountryViewModel cvm)
{
if(ModelState.IsValid)
{
//Save or do whatever you want
}
ViewBag.CountryList = LoadCountryList();
return View();
}
View Model
public class CountryViewModel
{
public int CountryId {get;set;}
public int StateId {get;set;}
public int CityId {get;set;}
[Required]
public string PostalCode {get;set;}
}
The actual select options are not posted (nor should they be). Therefore, when you get to the post action, your select list is empty. The solution? Simply repopulate it the same as you would in your get action. Granted, here, you're not populating those in the get action, but rather retrieving them via AJAX. You could technically do it the same way on post, if you wanted. You'd just have to run the AJAX calls on page load to refetch the select lists. However, it would be much better at this point to just do it in your post action.

how to get selected value of drop down list in asp.net mvc3?

This is my code Display data from the database into DropDownList in asp.net MVC3
In this I can now display data from database into dropdownlist but now I want that if I select any thing from dropdownlist data I want that selected value pass in my stored procedure. I know there is same question might be available or has already been asked but I am not getting my answer which I want. If anyone can explain me step by step or provide me some useful links.
This code is not completly tested and implemented.
You can acheive it using onchange event of dropdownlist.
#Html.DropDownListFor(x => x.SelectedItemValue,new {#onchange="passvalue(this);"})
Handle it using javascript and ajax
<script type="text/javascript">
function passvalue(e){
$.ajax({
type: 'POST',
dataType: 'json',
url: '#Url.Action("Index", "Home")',
data: ({ selectedValue: e.innerHTML }),
success: function (result) {
},
error: function (result) {
alert('error');
}
});
}
</script>
Now you can get the selected value to the controller
[HttpPost]
public ActionResult Index(int selectedValue)
{
// do whatever you want with `selectedValue`
}
Hope it helps
This is a way to achieve this:
Subscribe the change event of the dropdown and call the action method(with ajax for example) that passes the selected value to the stored procedure.
There are several approaches. One of the simplest is to have a ViewModel with a collection of SelectListItems to render in the drop-down and an item to take the selection. In my example code below of course I am using hard-coded values etc to demo the point!
ViewModel
public class TestViewModel
{
public IEnumerable<SelectListItem> TestListItems
{
get
{
return new List<SelectListItem>
{
new SelectListItem { Text = "Item 1", Value = "1" },
new SelectListItem { Text = "Item 1", Value = "1" },
new SelectListItem { Text = "Item 1", Value = "1" },
};
}
}
public string SelectedItemValue { get; set; }
}
View
<p>#Html.DropDownListFor(x => x.SelectedItemValue, new SelectList(Model.TestListItems, "Value", "Text"))</p>
Controller
public ActionResult Index()
{
var viewModel = new TestViewModel();
return View(viewModel);
}
[HttpPost]
public ActionResult Index(TestViewModel viewModel)
{
string youChose = viewModel.SelectedItemValue;
// ...
}
Also, to highlight the collection doesn't have to be of SelectListItem and could be another type. Then all you would need to do is change your view to perform a .Select to convert into a SelectListItem. For simplicity I've just made the ViewModel use it directly.

Categories

Resources