How to pass a value from razor page? - c#

How do you pass a value from razor into a C# class?
I want to pass the value from autoCreateSoldPart into the soldPartSetting, but I am not sure how to do that.
Razor
<p>
#Html.Label("Auto recreate sold part", new { #for= "autoCreateSoldPart" })
#{
var lstSelect = new List<SelectListItem>()
{
new SelectListItem() { Text = "Yes", Value = "true" },
new SelectListItem() { Text = "No", Value = "false" }
};
lstSelect.ForEach(o =>
{
if (o.Value == System.Configuration.ConfigurationManager.AppSettings["ReCreateSoldPart"])
{
o.Selected = true;
}
});
}
#Html.DropDownList("autoCreateSoldPart", lstSelect, new { #class = "form-control" })
</p>
Controller for razor
public class HomeController : Controller
{
public ActionResult Settings()
{
ViewBag.Message = return View();
}
}
C#
public class PartBLL
{
public static int AssignPartToShelf(string action, string userName, string itemNumber, string shelfNumber, string userToken)
{
if (soldPartSetting == true)
{
partService.ServiceInstance.UndoSoldItem(part.ID.Value, userToken);
return 0;
}
}
}

Related

How to convert Actionlink group to Dropdown List

the SiteLanguage cs file:
public class SiteLanguages
{
public static List<Languages> AvailableLanguages = new List<Languages>
{
new Languages{ LangFullName = "English", LangCultureName = "en"},
new Languages{ LangFullName = "Español", LangCultureName = "es"},
new Languages{ LangFullName = "বাংলা", LangCultureName = "bn"}
};
public class Languages
{
public string LangFullName { get; set; }
public string LangCultureName { get; set; }
}
}
cshtml file:
#{
foreach (var i in MvcMultilingual.SiteLanguages.AvailableLanguages)
{
#Html.ActionLink(i.LangFullName, "ChangeLanguage", "Home", new{lang = i.LangCultureName}, null) <text> </text>
}
}
I want to convert this action list group to dropdown list. How to change this code? I mean I just want to change cshtml side. Html.ActionLink to Html.DropdownList etc.
Try the following:
#using Languages = MvcMultilingual.SiteLanguages
#Html.DropDownListFor(m => Languages.AvailableLanguages.GetEnumerator().Current,
Languages.AvailableLanguages.Select(d =>
{
return new SelectListItem() {
Text = d.LangFullName,
Value = Url.Action("SetLanguage", "Home", new { lang = d.LangCultureName })
};
}),
"-Select Language-",
new { id = "urlddl" })
See the javascript function for processing the change event in this post: is it possible do have Html.ActionLink inside a DropDownList Without java script?
Processing the selected value on the controller side:
public ActionResult SetLanguage(string lang)
{
...
}

There is no ViewData item of type 'IEnumerable<SelectListItem>' that has the key “Geslacht”

First of all, I'm a beginner in what concerns C#, Razor, ASP.NET... I want to make a 'DropDownListFor' for the genders with a 'List' but the problem is that I get the errormessage as described in the title. Here is my code:
Model
namespace Hoofdstuk5_MvcStudentForm1.Models.ViewModels
{
public class StudentViewModel
{
public string Geslacht { get; set; }
}
}
Controller
namespace Hoofdstuk5_MvcStudentForm1.Controllers
{
public class StudentController : Controller
{
// GET: Student/Index
public ActionResult Index()
{
return View();
}
// GET: Student/Index
[HttpPost]
public ActionResult Index(string groep)
{
ViewBag.Geslacht = new List<SelectListItem>
{
new SelectListItem { Text = "Female", Value = "1" },
new SelectListItem { Text = "Male", Value = "2" }
};
return View(groep);
}
}
}
View
#Html.DropDownListFor(model => model.Geslacht, ViewBag.Geslacht as IEnumerable<SelectListItem>, "--- Select ---", new { htmlAttributes = new { #class = "form-control" } })
#Html.DropDownListFor(model => model.Geslacht, new List<SelectListItem> {
new SelectListItem { Text = "Male", Value = "1" },
new SelectListItem { Text = "Female", Value = "2" }
}, "--- Select ---", new { htmlAttributes = new { #class = "form-control" } })
#Html.DropDownListFor(model => model.Geslacht, null, "--- Select ---", new { htmlAttributes = new { #class = "form-control" } })
The second 'DropDownListFor' works, but the first and third has to be from the controller, but it doesn't work and I don't know why? Can somebody help me please?
The error means that the 2nd parameter of DropDownListFor() (IEnumerable<SelectListItem>) is null and therefore the method expects that the first parameter is IEnumerable<SelectListItem> (which it's not)
In the first example, the value of ViewBag.Geslacht is null because you did not populate it in the GET method (although you do populate it in the POST method). Add ViewBag.Geslacht = new List<SelectListItem>(...) to the GET method.
In the 3rd example, you secifically set the 2nd parameter to null
You are sending a string to your view as the model:
return View(groep);
Therefore, you are getting that error. You have to pass a model to your view. Create a model like this:
// Give this a better name
public class SomeModel
{
public List<SelectListItem> Geslacht { get; set; }
}
And then change your controller code to this:
// GET: Student/Index
[HttpPost]
public ActionResult Index(string groep)
{
var model = new SomeModel();
model.Geslacht = new List<SelectListItem>
{
new SelectListItem { Text = "Female", Value = "1" },
new SelectListItem { Text = "Male", Value = "2" }
};
return View(model);
}
If you need more things then just add more properties to your model.
I would suggest you change a bit your model:
public class StudentViewModel
{
public string Geslacht { get; set; }
public IEnumerable<SelectListItem> Geslachts { get; set; }
public StudentViewModel()
{
Geslachts = GetGeslachts();
}
public StudentViewModel(string geslacht)
{
Geslacht = geslacht;
Geslachts = GetGeslachts();
}
private IEnumerable<SelectListItem> GetGeslachts()
{
return new List<SelectListItem>
{
new SelectListItem
{
Text = "Select ---",
Value = string.Empty
},
new SelectListItem
{
Text = "Male",
Value = "1"
},
new SelectListItem
{
Text = "Female",
Value = "2"
}
}
}
}
Then you could change your controller like below:
public class StudentController : Controller
{
// GET: Student/Index
public ActionResult Index()
{
return View(new StudentViewModel());
}
// GET: Student/Index
[HttpPost]
public ActionResult Index(string groep)
{
return View(new studentViewModel(groep));
}
}
Doing this changes entails that you should also change your View, to accept a StudentViewModel. Now at your view you could have the following:
#model oofdstuk5_MvcStudentForm1.Models.ViewModels.StudentViewModel
#Html.DropDownListFor(model=>model.Geslacht, Model.Geslachts, new { htmlAttributes = new { #class = "form-control" } )

asp.net mvc Html.DropDownListFor: how to handle selected id

I have a problem with using #Html.DropDownListFor element.
What i have:
Model 'DatabaseModel':
public class DirectionEntity
{
public string Id { get; set; }
public string DirectionName { get; set; }
}
public class ViewModel
{
public int SelectedDirectionID { get; set; }
public List<DirectionEntity> DirectionList { get; set; }
}
Model 'DataFactory':
public class DataFactory
{
public static ViewModel Refresh()
{
using (var db = new MyDatabase())
{
return new ViewModel()
{
DirectionList = db.Directions.Select(_ => new { _.Id, _.DirectionName })
.ToList()
.Select(_ => new DirectionEntity() { Id = _.Id.ToString(), DirectionName = _.DirectionName })
.ToList(),
};
}
}
}
Controller:
public System.Web.Mvc.ActionResult AddNewDocument()
{
var db = DataFactory.Refresh();
return View(db);
}
[HttpPost]
public System.Web.Mvc.ActionResult AddNewEntry(ViewModel m)
{
m = DataFactory.Save(m);
ModelState.Clear();
return View(<some view>);
}
View:
#using (Html.BeginForm())
{
#Html.DropDownListFor(m => m.SelectedDirectionID, new SelectList(Model.DirectionList.Select(x => new SelectListItem { Value = x.Id.ToString(), Text = x.DirectionName }), "Value", "Text"), new { #class = "Duration", required = "required" })
<button type="submit" class="btn btn-default SaveAll">Save</button>
}
The question:
How to handle 'SelectedDirectionID' value, after user selected some position on dropdownlist, but not yet sent the request to the server using a POST-method.
See what the id of your dropdown is and then you can subscribe to the change event on the client side. You can do this using jQuery.
$("#idOfYourDropDown").change(function () {
// Do whatever you need to do here
// Here are some ways you can get certain things
var end = this.value;
var selectedText = $(this).find("option:selected").text();
var selectedValue = $(this).val();
alert("Selected Text: " + selectedText + " Value: " + selectedValue);
});
Also you should see my answer here on why you should not return a view from a POST action the way you are.
In this case you have to use Jquery. As per your view id for your drop down is 'SelectedDirectionID';
Your Js:
$(document).ready(function () {
var selectedValue = $('#SelectedDirectionID').val();
var selectedText = $("#SelectedDirectionID option:selected").text();
});
Or Inside drop down change event.
$('#SelectedDirectionID').change(function () {
var selectedValue = $(this).val();
var selectedText = $(this).find("option:selected").text();
});

validate a state dropdownlist if the US is selected as a country in another dropdownlist

Need some advice I am trying to write a validator which only fires when a specific value in a dropdownlist is selected.
I have two drop down lists on this form one for Countries and the other for US States, the States dropdownlist only shows when the United States is selected from the Countries dropdownlist.
I need a validator that makes the State dropdownlist list a required field only if the United States is selected as a country.
As background information this a MVC3 Web Application and the show/hide code for the States dropdownlist is JQuery.
Another alternative is to dynamically add the rule to jQuery for validation.
You would need to check on the server side this custom logic as well however.
You can do this in your controller, or ideally your VieWModel would implement IValidateableObject to check if country="usa" then county is required.
Use jQuery's .rules.add and .remove:
http://docs.jquery.com/Plugins/Validation/rules#.22remove.22rules
So you could do something along the lines of:
$(document).ready(function() {
$("#country").change(function(){
if($(this).val()=="usa")
{
$("#yourCountyDropDown").rules("add", {
required: true,
messages: {
required: "County is required"
}
});
}
else
{
$("#yourCountyDropDown").rules("remove");
}
});
});
and for your ViewModel
public class WhateverYourObjectNameCreateViewModel : IValidatableObject
{
#region Validation
public IEnumerable Validate(ValidationContext validationContext)
{
if (this.Country=="USA" && string.IsNullOrEmpty(this.County))
{
yield return new ValidationResult("County is required");
}
}
#endregion
}
You could write a custom validation attribute:
public class RequiredIfAttribute : ValidationAttribute
{
public RequiredIfAttribute(string otherProperty, object otherPropertyValue)
{
OtherProperty = otherProperty;
OtherPropertyValue = otherPropertyValue;
}
public string OtherProperty { get; private set; }
public object OtherPropertyValue { get; private set; }
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var property = validationContext.ObjectType.GetProperty(OtherProperty);
if (property == null)
{
return new ValidationResult(string.Format("Unknown property: {0}", OtherProperty));
}
object otherPropertyValue = property.GetValue(validationContext.ObjectInstance, null);
if (!object.Equals(OtherPropertyValue, otherPropertyValue))
{
return null;
}
if (value != null)
{
return null;
}
return new ValidationResult(this.FormatErrorMessage(validationContext.DisplayName));
}
}
Now you could have a view model:
public class MyViewModel
{
public string Country { get; set; }
[RequiredIf("Country", "usa", ErrorMessage = "Please select a state")]
public string State { get; set; }
public IEnumerable<SelectListItem> Countries
{
get
{
return new[]
{
new SelectListItem { Value = "fr", Text = "France" },
new SelectListItem { Value = "usa", Text = "United States" },
new SelectListItem { Value = "spa", Text = "Spain" },
};
}
}
public IEnumerable<SelectListItem> States
{
get
{
return new[]
{
new SelectListItem { Value = "al", Text = "Alabama" },
new SelectListItem { Value = "ak", Text = "Alaska" },
new SelectListItem { Value = "az", Text = "Arizona" },
};
}
}
}
a controller:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyViewModel();
return View(model);
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
return View(model);
}
}
and a view:
#model MyViewModel
#using (Html.BeginForm())
{
<div>
#Html.DropDownListFor(x => x.Country, Model.Countries, "-- Country --")
#Html.ValidationMessageFor(x => x.Country)
</div>
<div>
#Html.DropDownListFor(x => x.State, Model.States, "-- State --")
#Html.ValidationMessageFor(x => x.State)
</div>
<button type="submit">OK</button>
}
You might also find the Foolproof package of validation attributes useful.

How to create custom Html.ControlFor?

I have a class called Entity
public class Entity
{
public string Name { get; set; }
public Location Place { get; set; }
}
and one class called Location
public class Location
{
public string Country { get; set; }
public string State { get; set; }
public string City { get; set; }
}
One Entity contains a Location, so I want to generate 3 dropdowns for Location.
Country
State
City
I could do it manually like
#Html.DropDownListFor(o => o.Country, new [] { new SelectListItem() { Text = "United States", Value="US" } })
<br />
#Html.DropDownListFor(o => o.State, new [] { new SelectListItem() { Text = "Some State", Value="SS" } })
<br />
#Html.DropDownListFor(o => o.City, new[] { new SelectListItem() { Text = "Some city", Value = "City" } })
But I have several places on my website that will need the exact same 3 dropdowns, like Restaurant, Hotel and other classes that also have a Location. I've tried to make a partial view that starts a new form, but I get an exception:
The model item passed into the dictionary is of type 'TestMVC3Razor.Controllers.Entity', but this dictionary requires a model item of type 'TestMVC3Razor.Controllers.Location', with this code:
#model TestMVC3Razor.Controllers.Entity
#using (Html.BeginForm())
{
#Html.Partial("LocationSelector", Model.Place)
<br />
<input type="submit" value="Submit" />
}
And the partial view is
#model TestMVC3Razor.Controllers.Location
#using (Html.BeginForm())
{
#Html.DropDownListFor(o => o.Country, new [] { new SelectListItem() { Text = "United States", Value="US" } })
<br />
#Html.DropDownListFor(o => o.State, new [] { new SelectListItem() { Text = "Some State", Value="SS" } })
<br />
#Html.DropDownListFor(o => o.City, new[] { new SelectListItem() { Text = "Some city", Value = "City" } })
}
This obviously shouldn't work, but I want to do something like it, a helper like this would be perfect
#Html.LocationSelectFor(o => o.Location)
But how do I do this? I need to generate 3 dropdowns and when I post to an action I need to get the object with bidden values.
public ActionResult(Location loc)
{
var x = String.Format("{0}, {1} - {2}", loc.City, loc.Country, loc.State);
}
How can I make this helper to create 3 dropdowns and bind values when I post?
Just create your own extension off of HtmlHelper:
public static HtmlHelperExtensions {
public static MvcString LocationSelectFor<TModel, TProperty>(this HtmlHelper<TModel> helper, System.Linq.Expressions.Expression<Func<TModel,TProperty>> expression) {
// examine expression and build html
}
}
The trick is looking at the expression. This blog post should get you started: http://geekswithblogs.net/Madman/archive/2008/06/27/faster-reflection-using-expression-trees.aspx
Alternately, you can create an EditorTemplate for your Location class. Just google for asp.net mvc editortemplate. http://www.codecapers.com/post/Display-and-Editor-Templates-in-ASPNET-MVC-2.aspx
Personally I would stick with EditorTemplates, as you can change the view without the need to recompile typically.
You can follow this example to use expression and expression body
Get Custom Attributes from Lambda Property Expression
Or just use string expression and manipulate that as here http://www.joelscode.com/post/Use-MVC-Templates-with-Dynamic-Members-with-custom-HtmlHelper-Extensions.aspx
Following xixonia little hints I got what I needed.
#Html.EditorFor(o => o.Place, "LocationSelector",
new CreateLocation{ Country = "US", State = "A", City = "Y" })
And I have a template under
Views
|- Shared
|- EditorTemplates
LocationSelector.cshtml
#model TestMVC3Razor.Controllers.CreateLocation
#using TestMVC3Razor.Controllers
#Html.DropDownListFor(o => o.Country, Model.CountryList)
<br />
#Html.DropDownListFor(o => o.State, Model.StateList)
<br />
#Html.DropDownListFor(o => o.City, Model.CityList)
And then I made
public class CreateEntity
{
[Required]
public string Name { get; set; }
public CreateLocation Place { get; set; }
}
public class CreateLocation
{
public CreateLocation(Location location = null)
{
if (location != null)
{
Country = location.Country;
State = location.State;
City = location.City;
}
}
public string Country { get; set; }
public string State { get; set; }
public string City { get; set; }
public IEnumerable<SelectListItem> CountryList
{
get
{
var list = new[]
{
new SelectListItem() { Text = "US", Value = "US" },
new SelectListItem() { Text = "BR", Value = "BR" },
new SelectListItem() { Text = "ES", Value = "ES" },
};
var selected = list.FirstOrDefault(o => o.Value == Country);
if (selected != null)
{
selected.Selected = true;
}
return list;
}
}
public IEnumerable<SelectListItem> StateList
{
get
{
var list = new[]
{
new SelectListItem() { Text = "A", Value = "A" },
new SelectListItem() { Text = "B", Value = "B" },
new SelectListItem() { Text = "C", Value = "C" },
};
var selected = list.FirstOrDefault(o => o.Value == State);
if (selected != null)
{
selected.Selected = true;
}
return list;
}
}
public IEnumerable<SelectListItem> CityList
{
get
{
var list = new[]
{
new SelectListItem() { Text = "X", Value = "X" },
new SelectListItem() { Text = "Y", Value = "Y" },
new SelectListItem() { Text = "Z", Value = "Z" },
};
var selected = list.FirstOrDefault(o => o.Value == City);
if (selected != null)
{
selected.Selected = true;
}
return list;
}
}
}
And my controller
public class HomeController : Controller
{
public ActionResult Index()
{
// can load data for edit
return View(new CreateEntity { Place = new CreateLocation(TempData["Location"] as Location) });
}
[HttpPost]
public ActionResult Index(Entity ent)
{
var loc = ent.Place;
var x = String.Format("{0} {1} {2}", loc.Country, loc.State, loc.City);
ViewBag.Result = x; // display selected values
TempData["Location"] = loc;
return Index();
}
}
I don't know if it is the best solution, but at least I can call
#Html.EditorFor(o => o.Place, "LocationSelector", obj)
from any place and have a default place selector on my website.

Categories

Resources