In MVVM, the business logic is built into the Model. The ViewModel is there to bridge between the View and the Model, so it’s logic only pertains to driving the display and updating the model from user interactions with the View.
I think the disconnect you are having is trying to have an anemic model work for MVVM, and it can’t. By anemic model, I mean one that only holds data and has no logic. Even with MVC, the controller was only ever supposed to call the methods in the model layer. So your first point of what you think is right, does not in fact match the pattern.
The right approach is:
- Models are rich: containing data and business logic
- Views are strictly for drawing the UI
- ViewModels hold the logic to bridge the gap from the View to the Model
Now, how you build out your model can make use of services and dumb data objects, but you should have a consistent API. Domain Driven Design helps put some structure to the concept. For example, it’s not uncommon to have Repositories and such to retrieve Models and update them.
To drive this home, if you have a Button in your View, it will be bound to a Command, which in turn is invoked in the ViewModel. The Command then in turn calls a method on your Model, like
Save(), or if there are parameters will collect the values from the ViewModel before calling the method.