Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing a model object through ViewBag

I was wondering if it is possible to pass a model object through ViewBag. I tried the following codes but somehow in my View, it is only the path of the model which is displayed.

Controller:

public ActionResult Tempo()
{
    DateTime date1 = new DateTime(1990, 1, 1);
    Employee emp = new Employee(3, "fara", "hass", date1, 56.6m, 0);
    ViewBag.EmployeeId = emp.EmployeeID;
    ViewBag.Fname = emp.Fname;
    ViewBag.Employee = emp;
}

View:

@{
    ViewBag.Title = "Tempo";
}

@model LayoutProject.Models.Employee

<h2>Tempo</h2>
<div>
    <h4>ViewBag</h4>
    <br />
    EmployeeID: @ViewBag.EmployeeId
    <br />
    Fname: @ViewBag.Fname
    <br />
    Employee : @ViewBag.Employee
</div>

The Fname and EmployeeId is correctly displayed but not the Employee itself. Am I missing something here or it is simply not possible to pass a model through ViewBag?

like image 588
refresh Avatar asked Oct 31 '22 18:10

refresh


1 Answers

It would be better to create a view model to pass to the view:

public class TempoViewModel
{
    public int EmployeeId { get; set; }
    public string FirstName { get; set; }

    public string LastName { private get; set; }
    public DateTime EmployeeStartDate { private get; set; }
    //any other properties here that make up EmployeeInformation

    public string EmployeeInformation
    { 
        get
        {
            //Format your employee information in the way you intend for the view
            return string.Format("Employee: {0}, {1}, {2}", this.FirstName, this.LastName, this.EmployeeStartDate);
        }
    }
}

Then have a controller create the view model:

public ViewResult Tempo()
{
    employee = //logic to retrieve employee information

    //map model to viewmodel
    var viewModel = new TempoViewModel()
    {
        EmployeeId = employee.EmployeeID,
        FirstName = employee.Fname,
        LastName = employee.Lname, //or set whatever properties are required to display EmployeeInformation
        EmployeeStartDate = employee.StartDate,
    };

    return View(viewModel);
}

And then display the view model in the view:

@model TempoViewModel

@{
    ViewBag.Title = "Tempo";
}

<h2>Tempo</h2>
<div>
    <h4>Tempo Employee Information</h4>
    <br />
    EmployeeID: @Model.EmployeeId @* Do you really want to display the employee id? *@
    <br />
    Fname: @Model.FirstName
    <br />
    Employee: @Model.EmployeeInformation
</div>

Update:

With your current implementation, what you are trying to achieve when you call @ViewBag.Employee in the view, is to write the model out as a string representation. With the current implementation, to convert the model to a string, the ToString() method of the model is called. As you (probably) have not overridden the ToString() method, the inherited object implementation is called instead which writes out the complete namespace and class name (which is what I assume you mean when you say path).

To correct your current solution, you can add an implementation of ToString() to your Employee class. For example:

public class Employee
{
    public Employee(int employeeId, string firstName, string lastName)
    {
        this.EmployeeId = employeeId;
        this.FName = firstName;
        this.LName = lastName;
        //etc
    }

    public int EmployeeId { get; set; }
    public string FName { get; set; }
    public string LName { get; set; }

    public override string ToString()
    {
        //Implement your required string representation of the object here
        return string.Format("EmployeeId: {0}, FName: {1}, LName: {2}", EmployeeId, FName, LName);
    }
}
like image 162
Dangerous Avatar answered Jan 04 '23 14:01

Dangerous