Lets i have following view model:
public class ViewModel
{
public string SomeValue {get; set;}
public int CountryId {get; set;}
}
And country list
var countryList = new[]{new[]{Country="Russia", Value=1},new[]{Country="USA", Value=2},new[]{Country="Germany", Value=3} }
I want to create a form with these fields. The problem is that country input must be TEXTBOX.
So i cannt just write something like Html.TextBoxFor(m => m.CountryId)
. What is best practices for such tasks? Is it hidden field or maybe something else?
EDIT
Interface looks like :
SomeValue: |_______|
Country: |_______|
|Submit button|
In field Country we can type only country name. In SomeValue some other value it doesnt matter what(you can imagine that SomeValue doesnt exists).
This is certainly a strange requirement when a dropdown list seems far more appropriate, but we've all had strange requirements before. :) Here's a simple example which will hopefully demonstrate everything you need to know in order to get this working.
Firstly, a simple model to relate a country name with an id:
public class CountryModel
{
public int Id { get; set; }
public string Country { get; set; }
}
Now the controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(string country)
{
var countryId = GetCountries()
.Where(c => c.Country.ToLower() == country.ToLower())
.Select(c => c.Id)
.SingleOrDefault();
if (countryId != 0)
return RedirectToAction("Thanks");
else
ModelState.AddModelError("CountryNotSelected", "You have selected an invalid country.");
return View();
}
private List<CountryModel> GetCountries()
{
return new List<CountryModel>
{
new CountryModel { Id = 1, Country = "Russia" },
new CountryModel { Id = 2, Country = "USA" },
new CountryModel { Id = 3, Country = "Germany" }
};
}
}
Here's the view:
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@using (Html.BeginForm()) {
@Html.ValidationSummary(false)
<fieldset>
<div class="editor-field">
@Html.TextBox("Country")
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
There are a couple of things to note here. Firstly, you've already stated that you have extra properties in this view. In that case, I'd put them in a CountryViewModel
and model bind to an instance of that in the HTTP POST method, rather than simply binding to a string. So, something like this:
public class CountryViewModel
{
public string SomeValue { get; set; }
public string SomeMoreFormData { get; set; }
public string Country { get; set; }
}
Then from here, the POST method would change to something like this:
[HttpPost]
public ActionResult Index(CountryViewModel viewModel)
{
var countryId = GetCountries()
.Where(c => c.Country.ToLower() == viewModel.Country.ToLower())
.Select(c => c.Id)
.SingleOrDefault();
if (countryId != 0)
return RedirectToAction("Thanks");
else
ModelState.AddModelError("CountryNotSelected", "You have selected an invalid country.");
return View(viewModel);
}
Secondly, notice how I'm creating the country list via GetCountries()
. This would allow you to easily refactor this later to grab a country list from a database if your requirements change.
@using (Html.BeginForm("Index", "Home")) {
<p>
Page number:
@Html.TextBox("CountryId")
<input type="submit" value="CountryId" />
</p>
}
[HttpPost]
public ActionResult Index(int countryId)
{
CountryId= countryId;
}
I don't understand your question 100%. Am I correct in saying that the user can type in the country id and name?
It is better to send a view model to your view. Lets say that you have the following view model:
public class YourViewModel
{
public string CountryName {get; set;}
public string CountryId {get; set;}
}
Your action method could look like:
public ActionResult Index()
{
YourViewModel viewModel = new YourViewModel();
return View(viewModel);
}
[HttpPost]
public ActionResult Index(YourViewModel viewModel)
{
// Check viewModel for nulls
// Whatever was typed in on the view you have here,
// so now you can use it as you like
string country = viewModel.CountryName;
string id = viewModel.CountryId;
// Do whatever else needs to be done
}
Your view could look like this:
@model YourProject.DomainModel.ViewModels.YourViewModel
@using (Html.BeginForm())
{
<div>
@Html.TextBoxFor(x => x.CountryName)<br />
@Html.ValidationMessageFor(x => x.CountryName)
</div>
<div>
@Html.TextBoxFor(x => x.CountryId)<br />
@Html.ValidationMessageFor(x => x.CountryId)
</div>
<button id="SaveButton" type="submit">Save</button>
}
I hope this helps.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.