0

I am new to ASP.Net and I am sure this is a very basic question. I have a employee crud views . In create view i was created viewModel to pass different two model . One Model display emloyee and another model connect to db and retrieve all departments to my view . But I can't retrieve data to my employee create controller area. Vs send this err Abc.Models.MyViewModel.Employee.get returned null. On Debug.Print(employee.Employee.Name) line.

Here my Models ;

Employee.cs

 public class Employee
{
    public int Id { get; set; }
    [Required]
    public string Name { get; set; }
    [Required]
    public string Surname { get; set; }
    [Required]
    public string phoneNumber { get; set; }
    public string Detail { get; set; }

    //Bu kısımda veri tabanı ilişkisi 1 to many olacak
    public int DepartmentId { get; set; }
    public Department Department { get; set; }
}

Department.cs

public class Department
{
    public int Id { get; set; }
    public string depName { get; set; }

    public List<Employee> Employees { get; set; }
}

MyViewModel.cs

    public class MyViewModel
{
    public Employee Employee { get; set; }
    public IEnumerable<Department> departments { get; set; }
}

I added dropboxlist on my create.cshtml area with MyViewModel and i can't retrieve all data on my controller .

Here my EmployeeController.cs ;

// GET: Employee/Create
    [HttpGet]
    public ActionResult Create()
    {

        MyViewModel viewModel = new MyViewModel();
        Employee emp = new Employee();
        viewModel.Employee = emp;
        viewModel.departments = db.Departments;

        return View(viewModel);
    }

    // POST: Employee/Create
    // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
    // more details see https://go.microsoft.com/fwlink/?LinkId=317598.
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(/*[Bind(Include = "Id,Name,Surname,phoneNumber,Department,Detail")]*/ MyViewModel employee)
    {
        //string emName = employee.Employee.Name;
        Debug.Print(employee.Employee.Name);
        if (ModelState.IsValid)
        {
            db.Employees.Add(employee.Employee);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View(employee);
    }

Here Create.cshtml "this html codes are in @using (Html.BeginForm()");

@model TelefonRehberi.Models.MyViewModel

<div class="form-horizontal">
    <h4>Employee</h4>
    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    <div class="form-group">
        @Html.LabelFor(model => model.Employee.Name, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Employee.Name, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Employee.Name, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Employee.Surname, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Employee.Surname, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Employee.Surname, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Employee.phoneNumber, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Employee.phoneNumber, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Employee.phoneNumber, "", new { @class = "text-danger" })
        </div>
    </div>
    <!--Dropdown List Olacak-->
    <div class="form-group">
        @Html.LabelFor(model => model.Employee.Department, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            <!--Burada zorlandım umarım doğru kullanım olmuştur.-->
            @Html.DropDownListFor(m => m.Employee.Department, new SelectList(Model.departments.Select(i => i.depName)), " - Select or Add -", new { @class = "form-control" })
            @Html.ValidationMessageFor(model => model.Employee.Department, "", new { @class = "text-danger" })
        </div>

    </div>
    <!--Dropdown List Sonu Ayarlamalar Yapılacak.-->
    <div class="form-group">
        @Html.LabelFor(model => model.Employee.Detail, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Employee.Detail, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Employee.Detail, "", new { @class = "text-danger" })
        </div>
    </div>

    <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>
x.Ray
  • 1
  • 3
  • That is not a view model. View models do not contain data models when creating/editing data.Your view model contains the properties of `Employee` plus a `IEnumerable` for use in your `DropDownListFor()` method. But the problem is your `[Bind]` attribute - you need to remove it - your including property names which do not exist, and excluding everything that does exist (`MyViewModel` does not contain a property named `Id` or `Name` etc) –  Sep 16 '18 at 10:54
  • Thanks for answer , If you see my EmployeeController create parameter i do not use Bind attribute it is in comment line . I have one parameter MyViewModel . – x.Ray Sep 16 '18 at 11:43
  • Then the code you have shown works just fine (albeit it is bad practice) except that `Department` will be `null` because you cannot bind a ` –  Sep 16 '18 at 11:47
  • Actually, it will not bind because you have named the parameter in the POST method `employee` - change it to anything other than the name of a model property (refer the dupe) –  Sep 16 '18 at 11:49

2 Answers2

0

Add Form and try to do

@using (Html.BeginForm("ActionName","ControllerName", FormMethod.Post))
{
    <div class="form-horizontal">
        <!--add your other code here -->
        <!--add your other code here -->
       <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>
}

HTML Forms are required, when you want to collect some data from the site visitor. For example, during user registration you would like to collect information such as name, email address, credit card, etc.

A form will take input from the site visitor and then will post it to a back-end application such as CGI, ASP Script or PHP script etc. The back-end application will perform required processing on the passed data based on defined business logic inside the application.

There are various form elements available like text fields, textarea fields, drop-down menus, radio buttons, checkboxes, etc.

Udara Kasun
  • 2,182
  • 18
  • 25
  • Thanks for answer . I try your solution but still can't retrieve data . If you look my controller i wrote Debug.print(employee.Employee.Name) and in this area still null error retrieve. – x.Ray Sep 15 '18 at 17:57
0

Ok, you were really close. In Create method you need to create Employee employee and not MyViewModel employee. So in controller just put this Create method:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Employee employee)
{
    Debug.Print(employee.Name);
    if (ModelState.IsValid)
    {
        //db.Employees.Add(employee);
        //db.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(employee);
}

Then binding will work just fine and you will get your employee from the form. Just in case bellow is also the code for the form in the Create View.

<h2>Create</h2>

@using (Html.BeginForm("Create", "Employee", FormMethod.Post))
{
<div class="form-horizontal">
    <h4>Employee</h4>
    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    <div class="form-group">
        @Html.LabelFor(model => model.Employee.Name, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Employee.Name, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Employee.Name, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Employee.Surname, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Employee.Surname, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Employee.Surname, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Employee.phoneNumber, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Employee.phoneNumber, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Employee.phoneNumber, "", new { @class = "text-danger" })
        </div>
    </div>
    <!--Dropdown List Olacak-->
    <div class="form-group">
        @Html.LabelFor(model => model.Employee.Department, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            <!--Burada zorlandım umarım doğru kullanım olmuştur.-->
            @Html.DropDownListFor(m => m.Employee.Department, new SelectList(Model.departments.Select(i => i.depName)), " - Select or Add -", new { @class = "form-control" })
            @Html.ValidationMessageFor(model => model.Employee.Department, "", new { @class = "text-danger" })
        </div>

    </div>
    <!--Dropdown List Sonu Ayarlamalar Yapılacak.-->
    <div class="form-group">
        @Html.LabelFor(model => model.Employee.Detail, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Employee.Detail, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Employee.Detail, "", new { @class = "text-danger" })
        </div>
    </div>

    <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>
}
juramarin
  • 1,047
  • 1
  • 11
  • 13
  • Here the error message ; "The model item passed into the dictionary is of type 'TelefonRehberi.Models.Employee', but this dictionary requires a model item of type 'TelefonRehberi.Models.MyViewModel'." . I think ı must use MyViewModel in control because I was use myviewmodel in create view . I'm sending two models to view I have to use MyViewModel. – x.Ray Sep 15 '18 at 23:24