1
votes

I'm new in ASP.net MVC and Razor.

I want to save user birthdate using Drop down list , But I don't know how access selected value in controller . I used TextBoxFor before that it's not appropriate for get date from user . I read a lot of similar question but I didn't understand .

a part of my Register.cshtml :

 <div class="form-group">
        <label class="label">BirthDate</label>
        <div class="col-md-10">
            @Html.TextBoxFor(model => model.UserBirthDate)
            @Html.ValidationMessageFor(model => model.UserBirthDate)            
            <select name="Year">
                <option value="2000">2000</option>
                <option value="2001">2001</option>
                <option value="2002">2002</option>
                <option value="2003">2003</option>
                <option value="2004">2004</option>
                <option value="2005">2005</option>
                <option value="2006">2006</option>
            </select>
            <select name="Month">
                <option value="7">July</option>
                <option value="9">September</option>
                <option value="12">December</option>
            </select>
            <select name="Day">
                <option value="1">1</option>
                <option value="2">2</option>
                <option value="3">3</option>
                <option value="4">4</option>
            </select>
        </div>
    </div>

a part of my Controller :

[HttpPost]
    public ActionResult Register(User user)
    {

        UserRepositories bluser = new UserRepositories();

        if (ModelState.IsValid)
        {
            if(user.UserBirthDate != null)
            {
               /////
            }

            if (bluser.Add(user))
            {

                return MessageBox.Show("Succsess", MessageType.Success);
            }
            else
            {

                return MessageBox.Show(" UNSuccsess", MessageType.Error);
            }
        }
        else
        {


            return MessageBox.Show(ModelState.GetErrors(), MessageType.Warning);
        }

    }

user model :

public partial class User
{
    public int UserID { get; set; }
    public string UserEmail { get; set; }
    public string UserFirstName { get; set; }
    public string UserLastName { get; set; }
    public string UserPassWord { get; set; }
    public string UserCellPhone { get; set; }
    public string UserTell { get; set; }
    public string UserImage { get; set; }
    public string UserAddress { get; set; }
    public Nullable<byte> UserStatus { get; set; }
    public Nullable<System.DateTime> UserBirthDate { get; set; }
    public string UserGender { get; set; }
}

usermetaData.cs

internal class UserMetaData
{
    [ScaffoldColumn(false)]
    [Bindable(false)]
    public int UserID { get; set; }

    public string UserEmail { get; set; }


    public string UserFirstName { get; set; }


    public string UserLastName { get; set; }


    [DataType(DataType.Password)]
    public string UserPassWord { get; set; }

    public string UserCellPhone { get; set; }


    public string UserTell { get; set; }

    public string UserImage { get; set; }
    public string UserAddress { get; set; }


    public Nullable<byte> UserStatus { get; set; }

    public Nullable<System.DateTime> UserBirthDate { get; set; }


    public string UserGender { get; set; }
}
 }
namespace NP1.Models
{
[MetadataType(typeof(NP1.Models.MetaData.UserMetaData))]
public partial class User
{

    public string UserConfirmPassWord { get; set; }

    public string Year { get; set; }
    public string Month { get; set; }
    public string Day { get; set; }
}
2
A text box certainly can be appropriate if it's used to input a date value. Between HTML5 and readily available JavaScript plugins (jQuery UI Datepicker, for example) that's pretty trivial. As for getting that data in your controller, that all depends on what your User model looks like. According to your view, you're expecting it to have three properties named Year, Month, and Day. Does it? That's where those three values would be found when you post that form. - David
I updated my post @David , I used year,month,day . really I Know how use dateTimePicker but I don't like it . I think dropdown is better - shima
In that case the values will be in those properties on your model. The ASP.NET MVC framework's model binding logic matches up posted field names with model property names. - David
I used this code like you said , but it saves null :( : DateTime TempDt =Convert.ToDateTime( user.Year + "-" + user.Month + "-" + user.Day); user.UserBirthDate = TempDt; @David , could you explain a little more please ? - shima

2 Answers

2
votes

As David suggested in the comments, You should consider using a java script date picker library(Ex: JQuery UI,Bootstrap etc..) to set the date in UI which most of the users are familiar with. Dropdowns for dates seems to be a little old ! :(

If you still want to use dropdown's as you have in your question, you should create a view model for your view and add 3 properties for all the selected option values.

public class CreateUserVm
{
    public int Year { set; get; }
    public int Month { set; get; }
    public int Day{ set; get; }
    public string UserEmail { set; get; }
    pubic string UserFirstName  {set;get;}
    //Add other properties as needed
}

And in your GET action, you will send an object of this to your view,

public IActionResult Index()
{
  return View(new CreateUserVm());
}

And your view which is strongly typed to this view model

@model YourNameSpaceHere.CreateUserVm
<form asp-action="Index" asp-controller="Home" enctype="multipart/form-data">
        <label class="label">BirthDate</label>
        <div class="col-md-10">
            @Html.TextBoxFor(model => model.UserEmail)
            @Html.TextBoxFor(s=>s.UserFirstName)                
            <select name="Year">
                <option value="2000">2000</option>
                <option value="2001">2001</option>                   
            </select>
            <select name="Month">
                <option value="7">July</option>
                <option value="12">December</option>
            </select>
            <select name="Day">
                <option value="1">1</option>
                <option value="2">2</option>                   
            </select>
        </div>
    <input type="submit" />
</form>

As long as your select element's name property value matches with the property names we have in our view model, MVC model binding will map the form data to an object of our view model when the form is submitted.

[HttpPost]
public IActionResult Index(CreateUserVm model)
{
    if (ModelState.IsValid)
    {
      var bluser = new UserRepositories();
      //read the model.Year and model.UserName etc and create a user entity here
       //to do :Save and return something
        User u = new User { UserEmail= model.UserEmail};
        u.UserFirstName = model.UserFirstName ;  
        // Set other properties also.     
        bluser.Add(u);
    }
    return View(logos);
}

And if you ever want to set the selected option for the dropdown in an edit action method, take a look at this answer.

1
votes

You can change your ViewModel this way:

public class UserVM
{
   public string Year { set; get; }
   public string Month { set; get; }
   public string Day{ set; get; }
   // other properties
}

Then inside your action method you can populate those properties like this:

[HttpGet]
public ActionResult Register(User user)
{
     // It should be better to read this data from database
     ViewBag.Year = new SelectList(
                                    new List<SelectListItem>
                                    {
                                        new SelectListItem { Text = "1368", Value = "1987" },
                                        new SelectListItem { Text = "1369", Value = "1988"}, //....
                                    }, "Value" , "Text");
    // Also other properties like Month and Day
     return View();
}

Then inside your view:

@model ProjectName.VM
@using (Html.BeginForm())
{
    <div class="form-group">
        @Html.DropDownListFor(m => m.Year, (SelectList)ViewBag.Year, "Select one")
    </div>

    <button type="Submit" class="btn btn-success submit">Send</button>
}

Finally your action method for posting the data:

    [HttpPost]
    public ActionResult Register(VM model) 
    {
        if(!ModelState.IsValid) {}
        var Year = model.Year;
        // Here you can get other data like Day, Month
        // rest of your code for saving the data

        return View();
    }

dotnetfiddle.