5

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?

Dangerous
  • 4,818
  • 3
  • 33
  • 48
refresh
  • 1,319
  • 2
  • 20
  • 71
  • 2
    You are passing the model using `ViewBag` but `@ViewBag.Employee` displays the `.ToString()` value of `Employee` There is no need to include `ViewBag.EmployeeId = emp.EmployeeID;` and `ViewBag.Fname = emp.Fname;` - you can just use `ViewBag.Employee = emp;` and in the view - `EmployeeID: @((Employee)ViewBag.emp).EmployeeId` etc. But why do this instead of passing the model to the view - `return View(emp)`? –  Oct 02 '15 at 12:23
  • @tabby - What did you expect to see displayed for the Employee field? – Dangerous Oct 02 '15 at 15:28
  • @Stephen: so I can't use '@ViewBag.emp' to display the whole model with its properties? – refresh Oct 02 '15 at 15:38
  • @Dangerous: I thought ViewBag.emp would display the whole model. Is that possible? – refresh Oct 02 '15 at 15:39
  • @tabby - I expect you want to display the model as a string, but you need to dictate what format that string should be in. You should either override the ToString() method of your employee object or create a field in a view model containing the information. – Dangerous Oct 02 '15 at 15:49
  • @tabby - The [default](https://msdn.microsoft.com/en-us/library/system.object.tostring(v=vs.110).aspx) ToString() will just display the object implementation which is a string that represents the object which is what you are seeing. – Dangerous Oct 02 '15 at 15:54

1 Answers1

2

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);
    }
}
Dangerous
  • 4,818
  • 3
  • 33
  • 48
  • @tabby - How did you get on with this solution? – Dangerous Oct 04 '15 at 16:51
  • No, this is not what I want. Here you are not using ViewBag. What I want is to transfer a model from a controller to a view, using a ViewBag. What I am getting when doing 'ViewBag.Employee = emp' in the controller and 'Employee : @ViewBag.Employee' in the view, is the path of my model. I want to display the model itself, not the path. What is wrong with the way I am doing it? – refresh Oct 05 '15 at 04:47
  • @tabby - Fair enough, I didn't directly answer your question. I have provided an update to my answer. – Dangerous Oct 05 '15 at 06:49
  • That's what I wanted! Thanks! – refresh Oct 05 '15 at 07:01