I have two components like this:
<div class="col">
<p>To Do</p>
<Dropzone Items="MyFirstList" Class="h-100">
<ChildContent>
<div class="card" style="border-left: 3px solid black">
<div class="card-body">
<h6>#context.Title</h6>
</div>
</div>
</ChildContent>
</Dropzone>
</div>
<div class="col">
<p>In Progress</p>
<Dropzone Items="MyThirdList" Class="h-100">
<ChildContent>
<div class="card" style="border-left: 3px solid orange">
<div class="card-body">
<h6>#context.Title</h6>
</div>
</div>
</ChildContent>
</Dropzone>
</div>
The two components take these data respectively:
public List<TodoItem> MyFirstList = new List<TodoItem>()
{
new TodoItem(){Title = "Item 1"},
new TodoItem(){Title = "Item 2"},
new TodoItem(){Title = "Item 3"},
new TodoItem(){Title = "Item 4"},
new TodoItem(){Title = "Item 5"},
new TodoItem(){Title = "Item 6"},
new TodoItem(){Title = "Item 7"},
};
public List<TodoItem> MyThirdList = new List<TodoItem>()
{
};
Now there is no issue with the code I provided above (code is from https://github.com/Postlagerkarte/blazor-dragdrop) it's a drag and drop function that works perfectly
You drag items from MyFirstList component to MyThirdList.
Since it works, I wanted to get rid of the dummy data and replace it with my own data model, and here is the data for the first component:
protected override async Task OnInitializedAsync()
{
await this.GetTestSuites();
}
TestSuiteModel MyFirstList;
protected async Task GetTestSuites()
{
// url = ...
MyFirstList = await TestSuiteService.GetTestSuites(url);
await base.OnInitializedAsync();
}
And the component as:
<Dropzone Items="MyFirstList.value" Class="h-100">
<ChildContent>
<div class="card" style="border-left: 3px solid black">
<div class="card-body">
<h6>#context.id</h6>
</div>
</div>
</ChildContent>
</Dropzone>
So the above works perfectly but I need my second component to be empty, but for some reason feeding it an empty data throw an error
public List<TestSuiteModel> MySecondList = new List<TestSuiteModel>()
{
new Value () {id = 1}, // disambiguous error here
};
<Dropzone Items="MyThirdList.value" Class="h-100">
<ChildContent>
<div class="card" style="border-left: 3px solid black">
<div class="card-body">
<h6>#context.id</h6>
</div>
</div>
</ChildContent>
</Dropzone>
So the problem is with the above component and List. I don't know how to provide is an empty list.
This is what TestSuiteModel looks like btw:
namespace ABC.Models.TestSuiteModel
{
public class TestSuiteModel
{
public List<Value> value { get; set; }
public int count { get; set; }
}
public class Value
{
public int id { get; set; }
public string name { get; set; }
}
}
Instead of the new Value () {id = 1}, // disambiguous error here in the list initiaizer, write new TestSuiteModel() { value = new Value () { id = 1 } }.
This should initialize the list with an empty TestSuiteModel.
Edit: Forgot the value list, here's the initialization including everything:
public List<TestSuiteModel> MySecondList = new List<TestSuiteModel>()
{
new TestSuiteModel()
{
value = new List<Value>()
{
new Value() { id = 1 }
}
}
};
You should make sure the collection property is initialized, as internally, this library iterates the collection, which throws if null for obvious reasons.
Add the following initialization:
public class TestPlansModel
{
public List<Value> value { get; set; } = new List<Value>();
public int count { get; set; }
}
So the above works perfectly but I need my second component to be empty, but for some reason feeding it an empty data throw an error
in the example you have provided, the type of the list is different than the type of the model you are initializing.
Related
I have a dropdown list for a set of items. The items have several properties including "ModifiedDate", "CreatedDate", "Id" and "Name". The dropdown list is bound to Id and Name and is sorted by Name.
However, I would like to provide an option to the user to change the sort column to either of "ModifiedDate', "CreatedDate" or "Id". The user will also have an option to sort order "Ascending" or "Descending".
I can do so using ASP.NET MVC with Postback.
Class definitions
public class ItemList
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("createdDate")]
public DateTime CreatedDate { get; set; }
[JsonProperty("lastModifiedDate")]
public DateTime LastModifiedDate { get; set; }
}
public class Item
{
public string Id { get; set; }
public string Name { get; set; }
}
public class MainViewModel
{
[DisplayName("List of Items")]
public List<Item> Items { get; set; }
public string Id { get; set; }
public string SortBy { get; set; }
public string SortOrder { get; set; }
}
C# code to render the view
using Newtonsoft.Json;
public ActionResult Index()
{
//Json array
string s = "[
{\"id\": 1, name: \"A\", \"createdDate\": \"2019-01-16T14:07:11.01Z\", \"lastModifiedDate\": \"2019-01-31T22:45:33.33Z\"},
{\"id\": 2, name: \"B\", \"createdDate\": \"2019-10-02T18:55:53.24Z\", \"lastModifiedDate\": \"2019-10-16T19:47:32.407Z\"},
{\"id\": 3, name: \"C\", \"createdDate\": \"2015-12-31T16:15:46.94Z\", \"lastModifiedDate\": \"2018-08-08T14:03:02.773Z\"},
{\"id\": 4, name: \"D\", \"createdDate\": \"2016-10-21T20:56:55.553Z\", \"lastModifiedDate\": \"2016-10-21T21:00:29.323Z\"},
{\"id\": 5, name: \"E\", \"createdDate\": \"2018-08-10T18:51:30.907Z\", \"lastModifiedDate\": \"2018-08-10T18:51:30.907Z\"}
]";
List<ItemList> list = JsonConvert.DeserializeObject<ItemList>(s);
List<Item> items = list.OrderByDescending(k => k.LastModifiedDate).Select(k => new Item { Id = k.Id, Name = k.Name }).ToList();
MainViewModel model = new MainViewModel();
model.Items = items;
return View(model);
}
View Extract - Index.cshtml
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label class="col-md-6 control-label">#Html.LabelFor(m => m.Items)</label>
<div class="col-md-6">
#Html.DropDownListFor(x => x.Id, new SelectList(Model.Items , "Id", "Name"), "Select item", new { #class = "form-control" })
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<div class="col-md-2">
<label class="control-label">Sort on:</label>
</div>
<div class="col-md-2">
#Html.DropDownList("SortBy", new SelectList(new List<SelectListItem>() {
new SelectListItem(){Text="Created Date", Value="CreatedDate"},
new SelectListItem(){Text="Modified Date", Value="ModifiedDate"},
new SelectListItem(){Text="Query Name", Value="QueryName"}
}, "Value", "Text", "..Select.."))
</div>
<div class="col-md-2">
<label class="control-label">Sort Order:</label>
</div>
<div class="col-md-2">
#Html.DropDownList("SortBy", new SelectList(new List<SelectListItem>() {
new SelectListItem(){Text="Descending", Value="D"},
new SelectListItem(){Text="Ascending", Value="A"}
}, "Value", "Text", "..Select.."))
</div>
<div class="col-md-2">
<input class="btn btn-default" value="Reload Item List" />
</div>
</div>
</div>
</div>
Is it possible to update the dropdown list without having the refresh the page? Can I achieve this with a partial post back with jQuery?
I have a number of awards in my view and within each award there is a corresponding list of qualifications. I have created a ViewModel to display each award and with a click of a button a modal should appear with its relevant qualifications which can be marked as completed/updated by the user. However on the Post of the data only my first Award will bind in my controller method.The rest will comeback as Null when I debug in VS. The data is appearing in my view as expected with each Award only showing its relevant qualifications. Thanks in advance for helping with this.
ViewModel
public class CandidateExtended
{
public CandidateExtended()
{
this.Qualifications = new List<Qualification_Extended>();
}
public int AwardID { get; set; }
public int FrameworkID { get; set; }
public string ULN { get; set; }
public string Forename { get; set; }
public string Surname { get; set; }
public string TitleShort { get; set; }
public string TitleFull { get; set; }
public DateTime DOB { get; set; }
public string Award { get; set; }
public int AwardLevel { get; set; }
public string Status { get; set; }
public string Completion { get; set; }
public string SelectedRoute { get; set; }
public List<Qualification_Extended> Qualifications { get; set; }
public void addQualification(Qualification_Extended qualification)
{
Qualifications.Add(qualification);
}
}
Controller
[HttpGet]
public ActionResult Index()
{
var awardDetails = (from award in db.award
join candidate in db.candidate
on award.ULN equals candidate.ULN
join framework in db.framework
on award.QAN equals framework.QAN
where award.OrganisationIdentityID == organisationID
select new AwardDetails_Extended
{
AwardID = award.AwardID,
ULN = award.ULN,
AwardStatus = award.AwardStatus,
Forename = candidate.Forename,
Surname = candidate.Surname,
DOB = candidate.DOB,
FrameworkID = framework.FrameworkID,
TitleFull = framework.TitleFull,
TitleShort = framework.TitleShort,
AwardLevel = framework.AwardLevel,
Award = framework.Award,
Completion = framework.Completion
}).ToList();
var qualificationDetails = (from candidateQualification in db.candidateQualification
join qualification in db.qualification
on candidateQualification.QualificationID equals qualification.QualificationID
select new Qualification_Extended
{
ID = candidateQualification.ID,
QualificationID = candidateQualification.QualificationID,
ULN = candidateQualification.ULN,
FrameworkID = candidateQualification.FrameworkID,
Achieved = candidateQualification.Achieved,
DateAchieved = candidateQualification.DateAchieved
}).ToList();
List<CandidateExtended> candidateVM = new List<CandidateExtended>();
foreach (var item in awardDetails)
{
CandidateExtended vm = new CandidateExtended();
vm.AwardID = item.AwardID;
vm.FrameworkID = item.FrameworkID;
vm.ULN = item.ULN;
vm.Forename = item.Forename;
vm.Surname = item.Surname;
vm.DOB = item.DOB;
vm.TitleShort = item.TitleShort;
vm.TitleFull = item.TitleFull;
vm.Award = item.Award;
vm.AwardLevel = item.AwardLevel;
vm.Status = item.AwardStatus;
vm.Completion = item.Completion;
vm.SelectedRoute = item.SelectedRoute;
foreach (var qualification in qualificationDetails)
{
if (qualification.ULN == item.ULN && qualification.FrameworkID == item.FrameworkID)
{
vm.addQualification(qualification);
}
}
candidateVM.Add(vm);
}
return View(candidateVM);
}
View
#model List<Apprenticeship_SingleAward.ViewModels.CandidateExtended>
#{
ViewBag.Title = "Single Award Apprenticeships";
Layout = "~/Views/Shared/_Organisation.cshtml";
}
<div class="application-table table-responsive">
<table class="table table-striped administration-table">
<thead>
<tr class="admin-table-heading">
<th>ULN</th>
<th>First Name</th>
<th>Last Name</th>
<th>Title</th>
<th>Award</th>
<th>Level</th>
<th>Qualifications</th>
<th>Status</th>
</tr>
</thead>
<tbody>
#for (int j = 0; j < Model.Count(); j++)
{
var award = Model[j];
<tr>
<td>#award.ULN</td>
<td>#award.Forename</td>
<td>#award.Surname</td>
<td>#award.TitleShort</td>
<td>#award.Award</td>
<td>#award.AwardLevel</td>
<td>
<button class="btn qualificationbutton" data-toggle="modal" data-target="##qualificationModal">#displayQualTotal<i class="glyphicon glyphicon-pencil org-edit-icon"></i></button>
#using (Html.BeginForm("UpdateAward", "Organisation", FormMethod.Post, new { id = award.AwardID}))
{
#Html.HiddenFor(a => Model[j].AwardID)
<div id="#qualificationModal" class="modal fade" role="dialog">
<div class="modal-dialog organisationmodal">
<div class="modal-content">
<div class="modal-body">
<h4 class="org-modal-subheading">#award.TitleShort</h4>
<br />
<div class="row">
<div class="col-md-12">
<div class="row org-row-main">
<div class="col-md-7"><h4 class="org-type">Qualification</h4></div>
<div class="col-md-2"><h5 class="org-completed">Completed</h5></div>
<div class="col-md-3"><h5 class="org-date">Date</h5></div>
</div>
<hr class="org-hr"/>
#for (int i = 0; i < Model[j].Qualifications.Count(); i++)
{
<div class="row org-row">
<div class="col-md-7">
#Html.HiddenFor(a => Model[j].Qualifications[i].ID)
</div>
<div class="col-md-2">
#Html.CheckBoxFor(a => Model[j].Qualifications[i].Achieved)
</div>
<div class="col-md-3"
>#Html.TextBoxFor(a => Model[j].Qualifications[i].DateAchieved, "{0:dd/MM/yyyy}")
</div>
</div>
}
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn ccea-signout" data-dismiss="modal">Close</button>
<button type="submit" class="btn admin-button" style="margin-top: 0;">Save</button>
</div>
</div>
</div>
</div>
}
</td>
<td>
#{
var status = award.Status;
if (status == "In Progress")
{
<button class="btn progressbutton" style="margin: 0;">#status</button>
}
}
</td>
</tr>
}
</tbody>
</table>
UpdateAward
[HttpPost]
public ActionResult UpdateAward(List<CandidateExtended> Model)
{
return RedirectToAction("Index", "Login");
}
The way it is set up now (with BeginForm inside the #for, and a Submit button for every 'mini'-Form), every submit will do a Form Post containing exactly one item from the list.
If that is how you want it to work (edit one item at a time), then you may keep it. Do keep in mind however (add a comment?) that even though the Post Action method is ready to receive a List, there never will be multiple items in the List because each 'mini'-Form contains just one item.
If on the other hand you want to be able to save multiple items at once, then move the BeginForm outside the #for, and use just one Submit button at the end of the Form, e.g. just before the closing }.
I am struggling getting a DropDownListFor to work. The system is a timesheet system, and the relevant classes are Week:
public class Week
{
public int WeekId { get; set; }
public List<TimeEntry> TimeEntries { get; set; }
public Week()
{
TimeEntries = new List<TimeEntry>();
}
}
Each Week contains a list of TimeEntries:
public class TimeEntry
{
public int TimeEntryID { get; set; }
public double MonHours { get; set; }
public double TueHours { get; set; }
public double WedHours { get; set; }
public double ThuHours { get; set; }
public double FriHours { get; set; }
public int BillingStatusID { get; set; }
[ForeignKey("BillingStatusID")]
public virtual BillingStatus BillingStatus { get; set; }
}
And each TimeEntry has a BillingStatus (e.g. Paid, Pending, Invoiced):
public class BillingStatus
{
public int BillingStatusID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
The way that data is entered is from the WeekController. This has a series of rows, one for each entry in the database. Additional rows can be added too, so there is dual functionality for Edit/Create of TimeEntries via the WeekController:
I am having trouble getting the DropDownLists for BillingStatus to work, however. I think this is because I am rendering the rows by means of a loop. It is made more complex however, by the fact that the BillingStatus is not stored in the Week class, but in the TimeEntry class. (So kind of "one level down" from the Controller I am using.
If I hard code the list in the DropDownListFor control it works:
#for (int i = 0; i < Model.TimeEntries.Count; i++)
{
<div class="panel-body">
<div class="index" style="display:none">#Model.TimeEntries[i].TimeEntryID</div>
<div class="col-md-2">
#Html.DropDownListFor(m => Model.TimeEntries[i].ClientID, (SelectList)ViewBag.ClientID, "Select...", new { style = "width:100%" })
</div>
<div class="col-md-2">
#Html.DropDownListFor(m => Model.TimeEntries[i].TaskTypeID, (SelectList)ViewBag.TaskTypeID, "Select...", new { style = "width:100%" })
</div>
<div class="col-md-1">#Html.TextBoxFor(x => Model.TimeEntries[i].MonHours, new { style = "width:100%", #class = "hours mon" })</div>
<div class="col-md-1">#Html.TextBoxFor(x => Model.TimeEntries[i].TueHours, new { style = "width:100%", #class = "hours tue" })</div>
<div class="col-md-1">#Html.TextBoxFor(x => Model.TimeEntries[i].WedHours, new { style = "width:100%", #class = "hours wed" })</div>
<div class="col-md-1">#Html.TextBoxFor(x => Model.TimeEntries[i].ThuHours, new { style = "width:100%", #class = "hours thu" })</div>
<div class="col-md-1">#Html.TextBoxFor(x => Model.TimeEntries[i].FriHours, new { style = "width:100%", #class = "hours fri" })</div>
<div class="col-md-2">#Html.TextBoxFor(x => Model.TimeEntries[i].Comment)</div>
<div class="col-md-1">
#Html.DropDownListFor(x => Model.TimeEntries[i].BillingStatusID,
new SelectList(new List<Object>{
new { BillingStatusID = 0 , Name = "Pending" },
new { BillingStatusID = 1 , Name = "Invoiced" },
new { BillingStatusID = 2 , Name = "Paid" },
}, "BillingStatusID", "Name", Model.TimeEntries[i].BillingStatusID))
</div>
</div>
}
However, if I try and populate it from the database it fails. I have tried the following:
#Html.DropDownListFor(m => item.BillingStatusID, new SelectList(Model.TimeEntries[0].BillingStatuses, "BillingStatusId", "Name", "Select..."))
and have also tried using a ViewBag in the WeekController:
#Html.DropDownListFor(x => Model.TimeEntries[i].BillingStatusID,
new SelectList(ViewBag.BSID,
"BillingStatusID", "Name", Model.TimeEntries[i].BillingStatusID))
but neither approach works. I also want to make sure I am not hitting the database every time a row is rendered, as this seems really inefficient.
I guess what I want to be able to do is to get this:
new List<Object>{
new { BillingStatusID = 0 , Name = "Pending" },
new { BillingStatusID = 1 , Name = "Invoiced" },
new { BillingStatusID = 2 , Name = "Paid" },
}
in one hit when the page is loaded, and then use the SelectList to wrap around it. However, I don't know where I should get it from. Should I return it from the Controller?
I'm pretty new to MVC, so only just getting my head round concepts like ViewModels, ViewBags and EditorFor - so please asssume I know nothing when answering!!
I would like to create a view which is linked to multiple tables. From what I understand I need to create a View Model and link that to the page.
I get a couple of errors using the below
'PaymentViewModel' is a type, which is not valid in the given context.
An expression tree may not contain a dynamic operation (related to first error?)
I am new to MVC - come from ASP....Any help is appreciated
public class PaymentViewModel
{
public string playername { get; set; }
public DateTime dob { get; set; }
public string phone { get; set; }
public string email { get; set; }
public string clubname { get; set; }
public string productname { get; set; }
public decimal amount { get; set; }
public int transactionID { get; set; }
public bool approved { get; set; }
public string subtype { get; set; }
public DateTime subdate { get; set; }
}
Controller
I need to start with a blank view as this is the first step to register a player so the information is not in the database.
Below is the code I use to get a populated View.
public ActionResult Payment()
{
DateTime blank = Convert.ToDateTime("01-01-1900");
var prod = from p in db.Product
join c in db.Club on p.clubname equals c.clubname
where p.clubname == "Club1"
select new PaymentViewModel
{
productname = p.prodname,
clubname = c.clubname,
playername = c.add1,
dob = blank,
phone = c.phone,
email = c.email,
transactionID = 0,
amount = p.amount,
approved = Convert.ToBoolean("1"),
subtype = c.city,
subdate = blank
};
return View(prod);
}
View
#S4C.BAL.PaymentViewModel;
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Player Name</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
<b class="control-label col-md-2" style="">Full Name</b>
<div class="col-md-10">
#Html.EditorFor(model => model.playername, new { htmlAttributes = new { autofocus = "autofocus", #maxlength = "25", #class = "form-control" } })
#Html.ValidationMessageFor(model => model.playername, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<br /><br />
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
</div>
}
<div>#Html.ActionLink("Back to List", "Index")</div>
#section Scripts {#Scripts.Render("~/bundles/jqueryval")}
You cannot do approved = Convert.ToBoolean("1") in your select because the whole projection will happen at the database side and it does not know what Convert.ToBoolean() is. You need to do this in your view model:
public class PaymentViewModel {
// other properties ...
public string approved { get; set; }
public bool IsApproved {get {return this.approved == "1" }}
}
Also change the first line in your view to this:
#model S4C.BAL.PaymentViewModel
Not sure if I am understanding this correctly so please tell me if I'm wrong here.
Sounds like you know how to get a view filled with data from your database and you want to get an empty view without the data filled. To get an empty view request with just return a view without the model.
// Must request with /{Controller}/PaymentEmpty
Public ActionResult PaymentEmpty()
{
return View("Payment", new PaymentViewModel());
}
If you look at the default templates for ASP MVC applications the controller contains actions for Index, Details, Create, Edit and Delete. Thinking of actions in this manner can help with structuring your requests. Maybe place Payment into its own controller named PaymentsController and having the actions from the controller follow the default template.
Well there are many questions asked on this topic and I went through many of them but unfortunately I did not found any solutions for my problem. I want to auto-populate my dropdown list of Countries, State, Cities from DB. Below is my model I designed.
Model:
public class Registration
{
[Required(ErrorMessage="Please Select a Country")]
public int CountryId { get; set; }
public IList<SelectListItem> AvailableCountries { get; set; }
[Required(ErrorMessage = "Please Select a State")]
public int StateId { get; set; }
public IList<SelectListItem> AvailableStates { get; set; }
[Required(ErrorMessage = "Please Select a City")]
public int CityId { get; set; }
public IList<SelectListItem> AvailableCities { get; set; }
}
When a new user logs in I redirect him to registration page of user Controller.
Below is my Get ActionResult of User Controller
public ActionResult Registration()
{
UserModel.Registration userreg = new UserModel.Registration();
try
{
userreg.AvailableCountries.Add(new SelectListItem { Text = "Please Select your Country", Value = "Countries" });
var query = from countries in user.Countries orderby countries select countries;
var content = query.ToList();
foreach (var country in content)
{
userreg.AvailableCountries.Add(new SelectListItem
{
Text = country.Name,
Value = country.Id.ToString()
});
}
return View(userreg);
}
catch(Exception ex)
{
Helpers.Functions_ErrorLog.LogMessage("Error from User/Registration - " + ex.Message.ToString());
}
return View(userreg);
}
This is my Registration View
#model I_am_a_Fresher.Models.UserModel.Registration
#using (Html.BeginForm("", "", FormMethod.Post, new { #id = "formstep1", #class = "active" }))
{
<div id="stepsbody" class="col-md-12 col-xs-12 col-lg-12 col-sm-12 mar-top-22">
<div class="form-group col-md-6 col-lg-6 col-sm-12 col-xs-12">
<span class="ico-state-city"></span>
#Html.DropDownListFor(model => model.CountryId, Model.AvailableCountries)
#Html.ValidationMessageFor(m => m.CountryId, null, new { #class = "text-danger error-bold" })
</div>
<div class="form-group col-md-6 col-lg-6 col-sm-12 col-xs-12">
<span class="ico-state-city"></span>
#Html.DropDownListFor(model => model.StateId, Model.AvailableStates)
#Html.ValidationMessageFor(m => m.StateId, null, new { #class = "text-danger error-bold" })
<span id="states-loading-progress" style="display: none;">Please wait..</span>
</div>
</div>
}
Why I get this error I am not clear. This should work according to me. Can anyone suggest why this error is coming?
Your problem is that you are adding SelectListItems to AvailableCountries inside a try block, but the property has not been initialized so an exception is thrown. You then return the view but AvailableCountries is still null which results in the error message you are seeing.
Either initialize it in a parameter-less constructor in the model
public class Registration
{
public Registration()
{
AvailableCountries = new List<SelectListItem>();
}
....
}
or in the controller method
UserModel.Registration userreg = new UserModel.Registration();
userreg.AvailableCountries = new List<SelectListItem>();
try
.....
However I would suggest you change the model property to
public SelectList AvailableCountries { get; set; }
and the controller to (2 lines of code vs 10)
var query = (from countries in user.Countries orderby countries select countries).ToList();
userreg.AvailableCountries = new SelectList(query, "Id", "Name");
and in the view
#Html.DropDownListFor(m => m.CountryId, Model.AvailableCountries, "Please Select your Country")
which renders the first option as "Please Select your Country" but without a value attribute which is more appropriate
Note also you will need to initialise an empty SelectList for AvailableStates and AvailableCities assuming they are being populated using javascript/jquery
userreg.AvailableStates = new SelectList(Enumerable.Empty<SelectListItem>());