In such a simple example, this answer would be yes (it is unreasonably redundant). But, presumably, the page will contain more than just one model object. You may have a page state, as well as several other model objects that you need to track. This is done in the ViewModel.
For example, you may have additional information about a registered user displayed in the status bar, as well as a service running to detect changes in a text file.
You may also have a form for editing the Student object. If you intend to verify these changes, you will not want to directly edit the Student object until the changes are verified. ViewModel can act as a temporary storage place in this case.
Note on the above: in the model, checks are not rare, but even then you probably want the user to be able to enter invalid values while editing the form. For example, if your model does not allow a value of zero length in a field, you still want your user to delete the value, move to another field (for example, to copy it), then return to the field and finish editing (paste). If you are tied directly to the model, your verification logic may not process this state “in the gap”, “not yet finished”, as you would like. For example, you may not want to contact your user with verification errors until they have finished and clicked "Save."
You probably also have Command objects in the ViewModel to handle button clicks, etc. These would be domain specific objects that would be useless in the model.
ViewModels are also useful when you need to filter or somehow temporarily “modify” model objects to get something useful on the screen. For example, you can display a list of all users in the system along with a list of the ten best artists from them in real time (updated every 10 seconds). Or you can show a list of reports and a graph showing the overall speed of use, etc. Filtering, sorting and tuning this data will take place in the ViewModel.
A model, on the other hand, is usually as clean as possible. Ideally, you want POCOs , which (as a rule) simulate exactly what is in your persistent storage (database or what you have). If your persistent storage has FirstName and LastName fields, then your model also. Only in your ViewModel would you combine them to get the Name field (either "First Last" or "Last, First" depending on the needs of the View).
For instance:
namespace Model { public class Student { public string FirstName { get; set; } public string LastName { get; set; } } public class Class { public string Name { get; set; } public float Score { get; set; } } } namespace ViewModel { public class EditStudentRecordViewModel { private Model.Student _student; private IEnumerable<Model.Class> _studentClasses; public string FullName { return _student.LastName + ", " + _student.FirstName; } public string FirstName { get; set; } public string LastName { get; set; } public IEnumerable<Model.Class> PassingClasses { get { return _studentClasses.Where( c => c.Score >= 78 ); } } public IEnumerable<Model.Class> FailingClasses { get { return _studentClasses.Where( c => c.Score < 78 ); } } public void Save() { List<string> l_validationErrors = new List<string>(); if ( string.IsNullOrEmpty( this.FirstName ) ) l_validationErrors.Add( "First Name must not be empty." ); if ( string.IsNullOrEmpty( this.LastName ) ) l_validationErrors.Add( "Last Name must not be empty." ); if ( l_validationErrors.Any() ) return; _student.FirstName = this.FirstName; _student.LastName = this.LastName; Model.Utilities.SaveStudent( _student ); } } }