Saving a Html.DropDownList - c#

How can I save into my db this the selected option, Right now It's saving all the data but the ProfileText that is what I need...
I think I need to add an asp-for but I dont know where to be honest, or if it's a different way please tell me.
Here is my view:
#model HCCBPOHR.Data.Candidate
#*#model HCCBPOHR.DomainModel.CandidateModel*#
#*#model HCCBPOHR.Services.CandidateService.PostBoth*#
#{
ViewData["Title"] = "CandidateCreate";
}
<h2>CandidateCreate</h2>
<h4>Candidate</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form method="post" enctype="multipart/form-data" asp-action="CandidateCreate">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Name" class="control-label"></label>
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Number" class="control-label"></label>
<input asp-for="Number" class="form-control" maxlength="9" />
<span asp-validation-for="Number" class="text-danger"></span>
</div>
<div class="form-group">
#Html.DropDownList("ProfileText", "Select Profile")
</div>
<div class="form-group">
<label asp-for="CV" type="file" class="control-label"></label>
<input asp-for="CV" type="file" class="form-control" />
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-default" onclick="this.disabled=true;this.form.submit();" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
Here is my Model:
public class Candidate : BaseEntity
{
public int Id { get; set; }
public string Name { get; set; }
public int Number { get; set; }
public string ProfileText { get; set; }
public Byte[] CV { get; set; }
public string CVNAME { get; set; }
public List<Profile> ProfileList { get; set; }
}
This is how I'm sending the List to the View:
public IActionResult CandidateCreate(int postId)
{
using (var applicationcontext = new ApplicationContext())
{
IEnumerable<SelectListItem> items = applicationcontext.Profile.Select(c => new SelectListItem{Value = c.ProfileText,Text = c.ProfileText});
ViewBag.ProfileText = items.ToList();
return View();
}
}
The error that I'm having right now is
NullReferenceException: Object reference not set to an instance of an object.

In your view change the code to:
<div class="form-group">
<select asp-for="ProfileText" asp-items="#Model.ProfileList"></select>
</div>
Then in your model you'll have a property which we can call ProfileText which will then get post to the server when the form is submitted.
Change your model by introducing a new prop as follows:
public SelectList ProfileList { get; set; }
Now in your action your will need to do:
var model = new Candidate();
...
model.ProfileList = new SelectList(YourProfileListFromDbOrSomeWhereElse);
return View(model);
Please note you can also use SelectList(IEnumerable, string dataValueField, string dataTextField)Constructor if you want to set the dataValueField and dataTextField. I do not know how you get your ProfileList and what it contains so hence why I've only made use of the SelectList(IEnumerable items); Constructor.
Further reading here

As I can see, you are not populating the dropdownlist. I think it's better practice to have the values that can be selected(in a SelectList or string list) and a variable that will hold the selected value in your model and use DropDownListFor. the syntax would be:
#Html.DropDownListFor(model => model.ProfileText, new SelectList(Model.ProfileList, "name"), new {(here html attributes)#class = "form-control"})
After doing that you will get the selected value when posting the model

Related

Populate DropDown List in MVC App that Consumes a Web API

I have a simple MVC app that is consuming a web api via REST. The controller in the MVC app makes http calls to the web api to populate views within the MVC app with razor syntax.
I am trying to figure out how to populate a drop down list on one of the 'create' actions. I'm currently just using the scaffolded page:
#model ComicBookInventory.Shared.ComicBookWithAuthorsAndCharactersViewModel
#{
ViewData["Title"] = "CreateComicBook";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h1>CreateComicBook</h1>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="CreateComicBook">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Id" class="control-label"></label>
<input asp-for="Id" class="form-control" />
<span asp-validation-for="Id" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Title" class="control-label"></label>
<input asp-for="Title" class="form-control" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Description" class="control-label"></label>
<input asp-for="Description" class="form-control" />
<span asp-validation-for="Description" class="text-danger"></span>
</div>
<div class="form-group form-check">
<label class="form-check-label">
<input class="form-check-input" asp-for="IsRead" /> #Html.DisplayNameFor(model => model.IsRead)
</label>
</div>
<div class="form-group">
<label asp-for="DateRead" class="control-label"></label>
<input asp-for="DateRead" class="form-control" />
<span asp-validation-for="DateRead" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Rating" class="control-label"></label>
<input asp-for="Rating" class="form-control" />
<span asp-validation-for="Rating" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Genre" class="control-label"></label>
<input asp-for="Genre" class="form-control" />
<span asp-validation-for="Genre" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="CoverUrl" class="control-label"></label>
<input asp-for="CoverUrl" class="form-control" />
<span asp-validation-for="CoverUrl" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
#section Scripts {
#{
await Html.RenderPartialAsync("_ValidationScriptsPartial");
}
}
Which gets populated from this action in the controller:
public async Task<IActionResult> CreateComicBook(ComicBookWithAuthorsAndCharactersViewModel model)
{
string uri = $"https://localhost:5001/api/comicbook/add-book/";
HttpClient client = _httpClientFactory.CreateClient(
name: "ComicBookInventory.Api");
var postTask = await client.PostAsJsonAsync<ComicBookWithAuthorsAndCharactersViewModel>(uri, model);
if (postTask.IsSuccessStatusCode)
{
return RedirectToAction("GetAllComics");
}
else
{
return View(model);
}
}
Here is the view model definition:
namespace ComicBookInventory.Shared
{
public class ComicBookWithAuthorsAndCharactersViewModel
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public bool IsRead { get; set; }
public DateTime? DateRead { get; set; }
public int? Rating { get; set; }
public string Genre { get; set; }
public string? CoverUrl { get; set; }
/// <summary>
/// Navigation properties
/// </summary>
/// a book can have many authors
public ICollection<string>? AuthorNames { get; set; }
public ICollection<string>? CharacterNames { get; set; }
}
}
My question is, I want to add a drop down checklist to the view, so that when I am creating a comic book, I can select Authors that currently exist in the database. The same for characters.
Here is the entire code base in case anyone is interested: https://github.com/rnemeth90/ComicBookInventoryApp
I normally try and figure things out on my own (I'm relatively new to EF Core, and have very little experience with many-to-many relationships in EF core). I have tried various things and struggled with this for most of my weekend. I feel like this should be relatively simple but cannot figure it out. Please help.
In your Code, I noticed that you used #Html.DropDownList to realzie the selector element, and using form submit to handle the data. So I did a test in my side:
#{
List<SelectListItem> listItems= new List<SelectListItem>();
listItems.Add(new SelectListItem
{
Text = "Exemplo1",
Value = "Exemplo1_v"
});
listItems.Add(new SelectListItem
{
Text = "Exemplo2",
Value = "Exemplo2_v",
Selected = true
});
listItems.Add(new SelectListItem
{
Text = "Exemplo3",
Value = "Exemplo3_v"
});
}
<form asp-action="Create">
<div class="form-group">
AuthorNames
<div class="col-md-10">
#Html.DropDownListFor(model => model.Author, listItems, "-- Select author --")
</div>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
My model contains a public string? Author { get; set; } property, and when I click the submit button, the select value will be submitted, so when you want to pass the FullName to your controller, you need to set it as the Value of the SelectListItem.

ASP.NET Core Razor Page binding properties and preserve data in model

I have a question about model binding in razor pages .net core 3.1. Lets say I have a model such as this:
public Boolean bEmailMessages { get; set; }
public string sUserEmail { get; set; }
public Boolean bIcal { get; set; }
public Boolean bEventNotice { get; set; }
public string EPRLogin { get; set; }
public string EPRPWD { get; set; }
public string EPRLaunch { get; set; }
On one of my razor pages I use this model for only the top 4 items as inputs that are bound to those items. In my constructor I am initializing this model with data from the database. On my HTTPPOST I get the model back, but the last 3 items are null (EPRLogin, EPRPWD, and EPRLaunch) because I have another page where the user updates those items.
Is there a way to preserve the data in that model and only have the binding update the data from the page? The reason I ask, is because I have a function that I get the model from and I send it to save it to the database.
The only way I can think of doing this would be to get my model within the save method, change only the items I got back from the page model and then send my modified model to be saved.
I hope I explained this well enough...
As you said, I think the best way is to update only the first four items. Below is a work demo.
You can add an Id into your model.
Then in your pagemodel(Assuming Id=1 is the initial value):
public IActionResult OnGet()
{
Simple = _context.Simples.Find(1);
return Page();
}
public IActionResult OnPost(Simple simple)
{
_context.Simples.Attach(simple);
_context.Entry(simple).Property(x => x.bEmailMessages).IsModified = true;
_context.Entry(simple).Property(x => x.bEventNotice).IsModified = true;
_context.Entry(simple).Property(x => x.bIcal).IsModified = true;
_context.Entry(simple).Property(x => x.sUserEmail).IsModified = true;
_context.SaveChanges();
if (!ModelState.IsValid)
{
return Page();
}
return RedirectToPage("./Index");
}
}
And your page:
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="Simple.Id" />
<div class="form-group">
<label asp-for="Simple.bEmailMessages" class="control-label"></label>
<input asp-for="Simple.bEmailMessages" />
<span asp-validation-for="Simple.bEmailMessages" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Simple.bEventNotice" class="control-label"></label>
<input asp-for="Simple.bEventNotice" />
<span asp-validation-for="Simple.bEventNotice" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Simple.bIcal" class="control-label"></label>
<input asp-for="Simple.bIcal" />
<span asp-validation-for="Simple.bIcal" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Simple.sUserEmail" class="control-label"></label>
<input asp-for="Simple.sUserEmail" class="form-control" />
<span asp-validation-for="Simple.sUserEmail" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</form>
Result:

Is my ViewModel flow right? How to send it back to controller and refresh it on a controller action?

Is my ViewModel flow right? The 'SubObjectViewModel' class usage is a bad or a good practice? Or should I try other option, like creating a ViewModel only to this class?
And also, how should I return the ViewModel 'ObjectViewModel' to the controller with all its values, change them and refresh values from page view?
My ViewModel
Public class ObjectViewModel{
public string name { get; set; }
public int value { get; set; }
public bool IsCameraPermited { get; set; }
public List<SubObjectViewModel> choosenSubObjects{ get; set; } // need to get it back on controller;
public class SubObjectViewModel
{
public int IdObject { get; set; }
public string Name { get; set; }
public string Config { get; set; }
}
public List<Object> listSub{ get; set; } //list that will be filled on 'Create' Controller
}
My Controller
public IActionResult Create(int id)
{
List<Object> listSubObject = new List<Object>();
listSubObject = _getAllSubObjectsDAO.ListByID(id);
List<Object> choosenObjects= new List<Object>();
choosenObjects = _getChoosenObjectsDAO.ListByID(id);
List<SubObjectViewModel> listSubObject = new List<SubObjectViewModel>();
foreach (Object item in choosenObjects )
{
string config = _configurationDAO.GetConfigurationById(item.configId);
ObjectViewModel .SubObjectViewModel SubObject = new ObjectViewModel .SubObjectViewModel { IdObject = item.Id, Name = item.Name , Config = config };
listSubObject.Add(setorVM);
}
ObjectViewModel objVM = ObjectViewModel{
name ="test",
value = 2,
IsCameraPermited =true,
listSub = listSubObject,
choosenSubObjects = listSubObject
};
return View(objVM);
}
My View
#model Project.Models.ViewModels.ObjectViewModel
... more code
<form asp-action="Create">
<div class="row">
<div class="col-sm-6 ctnFullHeight">
<div class="shadowBoxForm formCreateLeft position-absolute col-sm-11 ctnFullHeight">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<input asp-for="name " class="form-control" />
<span asp-validation-for="name " class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="IsCameraPermited" class="control-label"></label>
<input asp-for="IsCameraPermited" type="checkbox" />
</div>
<div class="form-group float-right position-relative">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
<div class="col-sm-6">
<div class="shadowBoxForm formCreateLeft position-absolute col-sm-11 ">
#foreach (var item in listSub)
{
<div class="txt">
#item
</div>
}
</div>
</div>
</div>
</form>
Thanks in advance.
how should I return the ViewModel 'ObjectViewModel' to the controller with all its values
To achieve above requirement, you can refer to the following code snippet.
#model ObjectViewModel
#{
ViewData["Title"] = "Create";
var choosenSubObjects = Model.choosenSubObjects;
}
<form method="post">
<div class="row">
<div class="col-sm-6 ctnFullHeight">
<div class="shadowBoxForm formCreateLeft position-absolute col-sm-11 ctnFullHeight">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<input asp-for="name " class="form-control" />
<span asp-validation-for="name " class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="IsCameraPermited" class="control-label"></label>
<input asp-for="IsCameraPermited" type="checkbox" />
</div>
<div class="form-group float-right position-relative">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
<div class="col-sm-6">
<div class="shadowBoxForm formCreateLeft position-absolute col-sm-11 ">
#for (var i = 0; i < Model.choosenSubObjects.Count; i++)
{
<div class="txt">
<div class="form-group">
<label asp-for="#choosenSubObjects[i].IdObject" class="control-label"></label>
<input asp-for="#choosenSubObjects[i].IdObject" type="text" />
</div>
<div class="form-group">
<label asp-for="#choosenSubObjects[i].Name" class="control-label"></label>
<input asp-for="#choosenSubObjects[i].Name" type="text" />
</div>
<div class="form-group">
<label asp-for="#choosenSubObjects[i].Config" class="control-label"></label>
<input asp-for="#choosenSubObjects[i].Config" type="text" />
</div>
</div>
}
</div>
</div>
</div>
</form>
Controller Actions
[HttpGet]
public IActionResult Create(int id)
{
//code logic here
//...
return View(objVM);
}
[HttpPost]
public IActionResult Create(ObjectViewModel objectViewModel)
{
//code logic here
//...
Test Result

How to Edit Enumerable or List View in MVC Net Core

How do I create a Edit View for a List?
The following is a sample view and model for a single item, which works correctly.
Next question is, I have a list of items I want to edit. How would I conduct this?
Model:
public partial class ProductViewModel
{
public int ProductId { get; set; }
public string ProductName { get; set; }
public string ProductDescription { get; set; }
public string ImageLocation { get; set; }
}
Successful View:
#model ProductViewModel
#{
ViewData["Title"] = "Edit";
}
<h2>Edit</h2>
<h4>Product</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Edit">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="ProductId" />
<div class="form-group">
<label asp-for="ProductName" class="control-label"></label>
<input asp-for="ProductName" class="form-control" />
<span asp-validation-for="ProductName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ProductDescription" class="control-label"></label>
<input asp-for="ProductDescription" class="form-control" />
<span asp-validation-for="ProductDescription" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</form>
</div>
</div>
Now, I have a model with a list of items, how do I access them in the view? I want to edit all the items in my shopping cart, more specifically the quantity. Trying to call the delegate linq queries correctly.
Error:
The name 'modelItem' does not exist in the current context.
Model:
using System.Collections.Generic;
public class ShoppingCart : List<CartLine>
{
public ShoppingCart() { }
public ShoppingCart(IEnumerable<CartLine> collection) : base(collection) { }
public ShoppingCart(int capacity) : base(capacity) { }
}
public class ShoppingCartViewModel
{
public ShoppingCart ShoppingCart { get; set; }
public string ReturnUrl { get; set; }
}
public class CartLine
{
public int CartLineId { get; set; }
public Product Product { get; set; }
public int Quantity { get; set; }
}
View is not working, error below at input type and further:
#model ShoppingCartViewModel
#{
ViewData["Title"] = "Index";
}
<h2>Edit Shopping Cart</h2>
<h4>edit</h4>
<hr />
<div class="row">
<div class="col-md-4">
#foreach (var item in Model.ShoppingCart)
{
<form asp-action="Edit">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="modelItem=>item.CartLineId" />
<div class="form-group">
<label asp-for="modelItem=>item.Product.ProductName" class="control-label"></label>
<input asp-for="modelItem=>item.Product.ProductName" class="form-control" />
<span asp-validation-for="modelItem=>item.Product.ProductName" class="text-danger"></span>
</div>
You don't need to use a model expression in asp tag helpers. You can use the # symbol to access the item directly within the foreach loop.
So instead of asp-for="modelItem=>item.Product.ProductName" it would become asp-for="#item.Product.ProductName".
#foreach (var item in Model.ShoppingCart)
{
<form asp-action="Edit">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="#item.CartLineId" />
<div class="form-group">
<label asp-for="#item.Product.ProductName" class="control-label"></label>
<input asp-for="#item.Product.ProductName" class="form-control" />
<span asp-validation-for="#item.Product.ProductName" class="text-danger"></span>
</div>
</form>
}
Have a look at the docs for more info.

Issues with Binding Model to view

When attempting to bind a model to a view, I'm getting a 404 error. The ActionResult is called 'SortDesc' but the view is just a standard 'Index' view. I understand that this isn't loading because the there is now view called 'SortDesc'. However I have two buttons one to sort data ascending and one to sort data decending hence the two seperate functions. I'm just not sure what the best solution would be here, either to continue with the two seperate functions and somehow pass in the correct view to load or to create a new, single HttpPost function on Index that will know which button has been clicked and sort accordingly. Here's the code I have so far:
Models:
public class NumberSetList
{
public int NumberSetListId { get; set; }
public List<NumberList> Numbers { get; set; }
public string SortOrder { get; set; }
}
public class NumberList
{
public int NumberListId { get; set; }
public int Number1 { get; set; }
public int Number2 { get; set; }
public int Number3 { get; set; }
public int Number4 { get; set; }
public int Number5 { get; set; }
public string SortOrder { get; set; }
}
Razor:
#{
ViewBag.Title = "csi media web test";
}
<div class="jumbotron">
<h1>csi media web test</h1>
<p class="lead">Liane Stevenson</p>
</div>
<div class="row">
<div class="col-md-12">
<div class="panel panel-info">
<div class="panel-heading"><i class="glyphicon glyphicon-arrow-right"></i> Enter Your Four Numbers</div>
<div class="panel-body">
<form class="form-inline">
<div class="col-md-9">
<div class="form-group">
<label class="sr-only" for="number1">1st Number</label>
<input type="number" class="form-control" id="number1" name="Number1" placeholder="#1">
</div>
<div class="form-group">
<label class="sr-only" for="number2">2nd Number</label>
<input type="number" class="form-control" id="number2" name="Number2" placeholder="#2">
</div>
<div class="form-group">
<label class="sr-only" for="number3">3rd Number</label>
<input type="number" class="form-control" id="number3" name="Number3" placeholder="#3">
</div>
<div class="form-group">
<label class="sr-only" for="number4">4th Number</label>
<input type="number" class="form-control" id="number4" name="Number4" placeholder="#4">
</div>
</div>
<div class="col-md-3 text-right">
<a class="btn btn-default" href="#Url.Action("SortDesc", "Home")"><i class="glyphicon glyphicon-arrow-down"></i> Sort Desc</a>
<a class="btn btn-default" href="#Url.Action("SortAsc", "Home")"><i class="glyphicon glyphicon-arrow-down"></i> Sort Asc</a>
</div>
</form>
<p>
#if (Model != null)
{
foreach (int number in Model.Numbers)
{
<span class="label label-info">#number</span>
}
}
</p>
</div>
</div>
</div>
</div>
Home Controller:
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult SortDesc([Bind(Include = "Number1, Number2, Number3, Number4")] NumberSetList model)
{
if (!ModelState.IsValid)
{
return View();
}
else
{
NumberSetList list = new NumberSetList();
List<int> numbers = new List<int>();
numbers.Add(model.Number1);
numbers.Add(model.Number2);
numbers.Add(model.Number3);
numbers.Add(model.Number4);
numbers.OrderByDescending(i => i);
list.SortOrder = "Desc";
return View(list);
}
}
Try this
public class NumberSetList {
public int NumberSetListId { get; set; }
public List<NumberSetItem> Numbers { get; set; }
public string SortOrder { get; set; }
}
public class NumberSetItem {
public int Value { get; set; }
}
, use for loop to create inputs for the numbers
#using (Html.BeginForm()) {
<div class="col-md-9">
<div class="form-group">
#if (Model != null && Model.Numbers != null) {
#for (int i = 0; i < Model.Numbers.Count; i++) {
<div class="form-group">
#Html.LabelFor(m => m.Numbers[i].Value, "Number " + (i+1).ToString())
#Html.TextBoxFor(m => m.Numbers[i].Value, new { #class = "form-control" })
</div>
}
<div class="col-md-3 text-right">
<input id="SortOrder" value="Desc" type="button" class="btn btn-default"><i class="glyphicon glyphicon-arrow-down"></i> Sort Desc</input>
<input id="SortOrder" value="Asc" type="button" class="btn btn-default"><i class="glyphicon glyphicon-arrow-down"></i> Sort Asc</input>
</div>
}
</div>
</div>
}
And in the View
[HttpPost]
public ActionResult Index(NumberSetList model) {
if (!ModelState.IsValid) {
return View();
} else {
var numbers = model.SortOrder == "Desc" ?
model.Numbers.OrderByDescending(n => n.Value) :
model.Numbers.OrderBy(n => n.Value);
model.Numbers = numbers.ToList();
return View(model);
}
}
You can fix the issue using a variety of techniques.
Pass the name of the view into the View method like this:
return View("Index", list);
The View method has many overloads and you can see them all here. It is nice to get yourself familiar with the overloads for scenarios like the one you are facing.
If your view is not in the same folder as the action, you will need to pass the path for the view instead of just the name.
Another way is to have a single action and you can call this one Index as well but this one will take a model as an argument. Your model can have the numbers and an enum for sort: Desc, Asc. In your action method you can analyze the model, and do whatever is needed.
The approach with the model is the one I prefer.
EDIT
I just noticed you have this line of code in your view:
<a class="btn btn-default" href="#Url.Action("SortDesc", "Home")"><i class="glyphicon glyphicon-arrow-down"></i> Sort Desc</a>
That will trigger an HTTP GET and therefore it will not hit your SortDsc action method. Remove POST from your action method or use a post technique (Form) to hit your action method using POST.
EDIT 2
Honestly what you are doing is far simpler than you are making it. First thing is when you are using Url.Actio you are not passing nothing to your action method so how will it know about the numbers? I would normally call my action method using AJAX and get the result and display the result.
Without AJAX, you need to use one form for ascending and one for descending. Or you can use a radio button so user can select the order first.
Here is some code to do it using radio buttons.
Action:
[HttpPost]
public ActionResult SortDesc([Bind( Include = "Number1, Number2, Number3, Number4, SortOrder" )] NumberList model) {
if( !ModelState.IsValid ) {
return View("Index");
}
model.Numbers = new List<int>();
model.Numbers.Add( model.Number1 );
model.Numbers.Add( model.Number2 );
model.Numbers.Add( model.Number3 );
model.Numbers.Add( model.Number4 );
model.Numbers.Add( model.Number5 );
if (model.SortOrder == "Desc" ) {
model.Numbers = model.Numbers.OrderByDescending( i => i ).ToList();
}
else {
model.Numbers = model.Numbers.OrderBy( i => i ).ToList();
}
return View("Index", model);
}
Model:
public class NumberList {
public int Number1 { get; set; }
public int Number2 { get; set; }
public int Number3 { get; set; }
public int Number4 { get; set; }
public int Number5 { get; set; }
public int NumberListId { get; set; }
public List<int> Numbers { get; set; }
public string SortOrder { get; set; }
}
View:
#using( Html.BeginForm( "SortDesc", "Home", FormMethod.Post ) ) {
<div class="row">
<div class="col-md-12">
<div class="panel panel-info">
<div class="panel-heading"><i class="glyphicon glyphicon-arrow-right"></i> Enter Your Four Numbers</div>
<div class="panel-body">
<form class="form-inline">
<div class="col-md-9">
<div class="form-group">
<label class="sr-only" for="number1">1st Number</label>
<input type="number" class="form-control" id="number1" name="Number1" placeholder="#1">
</div>
<div class="form-group">
<label class="sr-only" for="number2">2nd Number</label>
<input type="number" class="form-control" id="number2" name="Number2" placeholder="#2">
</div>
<div class="form-group">
<label class="sr-only" for="number3">3rd Number</label>
<input type="number" class="form-control" id="number3" name="Number3" placeholder="#3">
</div>
<div class="form-group">
<label class="sr-only" for="number4">4th Number</label>
<input type="number" class="form-control" id="number4" name="Number4" placeholder="#4">
</div>
<div class="form-group">
<input type="radio" class="form-control" id="number4" name="SortOrder" value="Desc">
</div>
<div class="form-group">
<input type="radio" class="form-control" id="number4" name="SortOrder" value="Asc">
</div>
</div>
<div class="col-md-3 text-right">
<button class="btn btn-default"><i class="glyphicon glyphicon-arrow-down"></i> Sort </button>
#*<a class="btn btn-default"><i class="glyphicon glyphicon-arrow-down"></i> Sort Asc</a>*#
</div>
</form>
<p>
#if( Model != null ) {
foreach( int number in Model.Numbers ) {
<span class="label label-info">#number</span>
}
}
</p>
</div>
</div>
</div>
</div>
}

Categories

Resources