Use model in c# without a database? - c#

I am relatively new to c# and ASP.NET MVC 5, but I was hoping for some help. I have an application where I have a class with about 20 variables. It has some Guid, some List<string>, int, string, etc. relatively simple. My controller will be passed this class, and then I need to send the data from the class down to the view, and then get it back to the controller on a form submit. Everywhere I see tutorials on how to use a model with entity framework, but nowhere have I found anything on just using a model without a database. Is it possible, (and if so, how) to use model without a database? If it is not possible, what other ways could I go about using this? I thought about a session variable, but that seemed like a lot of overhead per user, i'm kind of stumped here. Thanks in advance :)

Here's an example of how you use models in MVC...
The Controller
public class ExampleController : Controller
{
public ActionResult Test()
{
TestViewModel model = new TestViewModel
{
Id = Guid.NewGuid().ToString(),
Name = "Foo bar"
};
return this.View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Test(TestViewModel model)
{
if (!this.ModelState.IsValid)
{
return this.View(model);
}
return this.Content("Success");
}
}
The View Model
public class TestViewModel
{
[Required]
public string Id { get; set; }
[Required]
public string Name { get; set; }
}
The View
#model TestViewModel
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
#using (this.Html.BeginForm())
{
#(this.Html.ValidationSummary(false))
#(this.Html.AntiForgeryToken())
#(this.Html.EditorFor(model => model.Id))
#(this.Html.ValidationMessageFor(model => model.Id))
#(this.Html.EditorFor(model => model.Name))
#(this.Html.ValidationMessageFor(model => model.Name))
<input type="submit" value="Submit!"/>
}
Also by default MVC generates your routing table based on a simple naming convention, in this instance,navigate to http://yoursite/example/test to see this example in action

You do not need a database to have models. Models just define the data to pass back and forth, so a database is definitely not necessary. In fact, the model should ideally be database agnostic. For instance, you might have a CustomerOrder model and Product model.
public class CustomerOrder
{
public int Id {get; set;}
public List<Product> Products {get; set;}
public int CustomerId {get; set;}
}
public class Product
{
public int Id {get; set;}
public string Name {get; set;}
public string Description {get; set;}
public double Price {get; set;}
}
You probably will need some sort of data storage (flat files, relational database, non-relational database, web based storage) but depending on the data you want to pass, it came from anywhere.

mvc models are pure c# objects to cary your information between controller and view. So you can use them independent from data base.
If you later need your information be persist you can use EntityFramework code first or serialize them in a flat file.

Related

Model or ViewModel when representing a subset of data in MVVM?

If I have a complex model representing a large amount of data, and I only wish to display a cut-down version of that model (e.g. Name, Description), what is the best approach in MVVM?
Most solutions I can find seem to assume that the data is already present in memory and recommend using a new ViewModel that exposes only the fields required.
However rather than select out all of the data from the database, it would be preferable to select just what is necessary. Do I then create a new model to hold that data? Selecting directly into the ViewModel is possible but feels like the wrong thing to do. Likewise using a new model to represent a different version of the same data also feels off somehow.
What is the accepted method of doing this?
As a simple example (Simple enough class that I wouldn't ordinarily do this):
public class User {
public int UserID {get;set;}
public string FirstName
public string LastName
public int AccessLevelID
public List<Groups> UserGroups
}
but I only really need:
public class PreviewUser {
int UserID
string FirstName
}
You can create another type with is a subset of the business type.
usually this is known as a
DTO - Data transfer Object which encapsulates only what you need. so the database needs to query only the subset of the entity.
public class UserDto
{
public int ID { get;set;}
public string Name{ get;set;}
}
Secondly if you need to add some ui logic to the display it is common to wrap the specific DTO in a more specific UI model.
public class UserUI
{
UserDTO _userDto;
UserUI(UserDTO userDto)
{
_userDto = userDto;
}
public string Name
{
get{return IsAfter_21_hours ? "The user as gone home" : _userDto.Name;}
}
}
the UserViewModel will reference an instance of UserUI.
You can either remove properties you don't need from the model (to slightly improve performance) or you can create a viewmodel that will provide only properties that you want to show.
Here is an example:
public class UserViewModel
{
private readonly User _user;
public UserViewModel(User user)
{
_user = user;
}
public int UserID
{
get { return _user.UserID; }
}
public string FirstName
{
get { return _user.FirstName; }
}
}
...
var viewModels = userRepository.GetUsers().Select(user => new UserViewModel(user));
UPDATED:
If performance is really important for you, you can use inheritance. Base class will be smaller version of the data and derived class will contain complete data. You can use the base class when you need to get only some fields from DB and save bandwidth.
public class BaseUser
{
public int UserID { get; set; }
public string FirstName { get; set; }
}
public class User : BaseUser
{
public string LastName { get; set; }
public int AccessLevelID { get; set; }
public List<Groups> UserGroups { get; set; }
}
There are number of approaches you may use:
use "full version" of source model. Since you're building UI, the user will see only what you want to display;
use view model, and wrap source model into this view model. The implementation is trivial, and amount of data is limited before UI;
use view model, and copy data from source model into this view model. The implementation is more complex (either mapping from existing model, or loading only required data from database), but view model and model are totally decoupled.
Actually, it depends on what is more suitable for you.
Note, that often the difference between "view model" and "model" is blurred. If the model looks like this:
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
...and view model - like this:
public class PersonViewModel
{
public int Id { get; set; }
public string Name { get; set; }
}
then throw this view model away. While there's no difference, you don't need to create extra classes.
I think you don't have to create new model class to hold user data for view . Instead create a view model class and map the model properties to VM. See the example below
public class UserViewModel
{
Public UserViewModel(User user)
{
//initialize required viewmodel properties here
}
int UserID {get;set;}
string FirstName{get;set;}
}

Posting objects containing other models

I've been searching for a way to post all the information of a model which contains other models and I believe I can just send the object to my view and go off of the 50 examples I've looked at and can render everything just fine.
Here's my model I'm talking about named Equipment.
public int id { get; set; }
public String name { get; set; }
public ManufacturerItem manufacturerItem { get; set; }
public EquipmentType equipmentType { get; set; }
public SupportItem supportItem{ get; set; }
public Placement placement{ get; set; }
public Boolean status { get; set; }
public DateTime endOfLife{ get; set; }
public String notes{ get; set; }
public Purchase purchase{ get; set; }
public Boolean mes{ get; set; }
public DateTime reviewedDate{ get; set; }
Based on the tons of examples I've read I know I can render these like this:
#Html.EditorFor(model => model.name)
#Html.EditorFor(model => model.manufacturerItem.model.name)
In other research I did stumble upon building forms for deep View Model graphs in ASP.NET MVC which I may consider in using, but that was posted back in MVC 2 days. I'm using MVC 5. So I don't know how relative that is today.
So let's say I have another model named Book with {id, Title, Author} and you could edit the book name and author. Now in this model, on edit, my controller could be as such:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include="ID,Title,Author)"] Book book)
{ ... -insert code- ...}
Going off of this idea, what would be my controller method signature be for the Equipment model? Do I include the other objects as their own types?
I'm not using EF or linq-to-sql because I have to use stored procedures. So I want to get all this information neatly packaged and passed off to the repository that will take care of parameter assignment and calling of the stored procedure.
Going off of this idea, what would be my controller method signature
be for the Equipment model?
Have you tried using the following signature:
[HttpPost]
public ActionResult Edit(Equipment model)
{
...
}
By the way if your view doesn't contain a form allowing to edit all the properties of the Equipment model object graph you may consider using a view model containing only the properties that are included as input fields in your form. Then on the server you will get the corresponding Equipment instance from your backend using the id, update only the properties that were sent from the HTML form and save the results back.
For example:
[HttpPost]
public ActionResult Edit(EquipmentViewModel model)
{
Equipment equipement = backend.GetById(model.Id);
// set the properties that are coming from the UI:
equipment.name = model.Name;
equipment.supportItem = model.SupportItem;
...
// save the updated entity back
backend.Update(equipment);
}
In this example the EquipmentViewModel will contain only the properties that you have corresponding input fields in your view and which the user is supposed to edit and not the entire domain model object graph.

Null values on model after sending model to controller

I'm using .net MVC.
I have some values in a form like:
#Html.TextBoxFor(model => model.Name, new { #class = "form-control" })
On the controller, I get the data like:
public ActionResult NovaPessoa(Person person)
{
The problem is that I just can get values that I have placed the #Html.TextBoxFor markup.
All the other complex information, like person.ContactInformation is lost after submiting and I can't use the SaveChanges in Entity Framework, because it will give me an invalid object after using the Atach method.
The question is: Do I need to use the #Html.TextBoxFor markup for all my model properties, even if I'm not using then to display anything, just to have them on Controller?
You are correct. What people (incorrectly) do normally, is use HiddenFor:
#Html.HiddenFor(model => model.ContactInformation)
What you should be doing, is cutting down your model into a view model with only the appropriate properties.
So, don't use this model:
public class PersonVM {
public int PersonId { get; set; }
public string FirstName { get; set; }
public string Surname { get; set; }
public string ContactInformation { get; set; }
}
..if all you're doing is updating the contact information. Instead, create a new class for your model:
public class PersonContactInfoEditVM {
public int PersonId { get; set; }
public string ContactInformation { get; set; }
}
That's all you need. This saves you from creating invalid objects when you don't add 30 HiddenFor elements to your page .. resulting in very broken data.
You might be thinking "ugggghhhh, all that manual mapping from PersonContactInfoEditVM to Person... I don't want to be writing that sort of code". No one does.. which is why the following libraries exist:
AutoMapper
ValueInjector

Can I have two view models in a single controller?

I am having trouble understanding if this is possible or not. I have a stored procedures and a view model classes and one controller. Is it possible that I could add another view model class with a different stored procedure to use one controller and display the the information from both stored procedures into one view?
This is my current Model:
public class People
{
public class Jobs
{
public int jobID { get; set; }
public string jobName { get; set; }
}
public class Names
{
public int userId{get;set}
public string userName {get; set;}
}
}
Yes, this is totally possible. Simply create a view model that contains the properties that would be populated by your stored procedures and then pass that to your view:
public class PeopleViewModel
{
public List<Job> Jobs { get; set; }
public List<Name> Names { get; set; }
}
Then the action method:
public ActionResult Index()
{
var model = new PeopleViewModel();
model.Jobs = // ... fetch from database
model.Names = // ... fetch from database
return View(model);
}
Update per comments
As you've stated Jobs and Names are collections, the model code you've shown won't solve your problem. It sounds like this is what you really want:
public class Job // Notice I've removed the pluralisation
{
public int jobID { get; set; }
public string jobName { get; set; }
}
public class Name // Notice I've removed the pluralisation
{
public int userId { get; set; }
public string userName { get; set; }
}
Now, your People class can contain lists of those:
public class People
{
public List<Job> Jobs { get; set; }
public List<Name> Names { get; set; }
}
Now you can wrap this in a view model:
public class PeopleViewModel
{
public People People { get; set; }
}
Then you would populate it from your action:
public ActionResult Index()
{
var model = new PeopleViewModel();
model.People = // ... fetch from database
return View(model);
}
The thing is, if Jobs and Names are unrelated, there's no point in wrapping them in a People class first. You'd simply do the following (as discussed above):
public class PeopleViewModel
{
public List<Job> Jobs { get; set; }
public List<Name> Names { get; set; }
}
Think of a view model as a way of representing just a slice of the data you want to display in your view, nothing more, nothing less. All the code above does is define what data you'd like to see in that view. As the properties on the view model are public, you can populate them in your controller's action using whatever method you currently use.
Second Update
I think it would probably be helpful to show you a full example as to how fits together for your views. Firstly, I'll show you the quick and dirty way of accessing the data in your view model and then afterwards I'll show you how to do the same with DisplayTemplates.
Quick and Dirty Approach
So first up, let's assume we have an action called Index like the following:
public ActionResult Index()
{
var model = new PeopleViewModel();
model.Jobs = // ... fetch from database
model.Names = // ... fetch from database
return View(model);
}
Here's the Index view:
#model PeopleViewModel
#foreach (var job in Model.Jobs)
{
#Html.DisplayFor(m => job.JobId)
#Html.DisplayFor(m => job.JobName)
}
#foreach (var name in Model.Names)
{
#Html.DisplayFor(m => name.UserId)
#Html.DisplayFor(m => name.UserName)
}
Notice how the view expects an instance of PeopleViewModel and it's simply looping over each individual item in each collection, printing the contents. However, whilst this is fine for very simple views, mixing logic with your HTML becomes a maintenance headache with more complicated views and larger projects. With that in mind, we can make use of DisplayTemplates instead.
Second Approach - Using Templates
The action in your controller remains the same. However, we need to make some other changes. What we're working towards is turning the Index view into this:
#model PeopleViewModel
#Html.DisplayFor(m => m.Jobs)
#Html.DisplayFor(m => m.Names)
By calling Html.DisplayFor in this way, it will try to locate a DisplayTemplate which corresponds to the data type it's being passed. In this case, the helper is smart enough to know that we're passing collections to it and so it will look for a template that matches the data type the collection contains. That means we need to make templates for the types Job and Name. To do that, follow these steps:
Create a DisplayTemplates folder inside your view's current folder (e.g. if your view is Home\Index.cshtml, create the folder Home\DisplayTemplates).
Create a strongly-typed view in that directory with the name that matches your model (i.e. in this case you would make two views, which would be called Job.cshtml and Name.cshtml, respectively).
Now you can move all of the display logic into those two templates. So they would look like the following:
Job.cshtml
#model Job
#Html.DisplayFor(m => m.JobId)
#Html.DisplayFor(m => m.JobName)
Name.cshtml
#model Name
#Html.DisplayFor(m => m.UserId)
#Html.DisplayFor(m => m.UserName)
Hopefully that clears things up a little.

Controller using multiple models?

Untill now in C# MVC3 i only had to use one controller which used only one model.
But now i think i need access to two models in my controller. I'm wondering if this is allowed in the MVC pattern?
I have a ProfileController. The ProfileController shows the profile info of a user obviously. But there's also some other data that i wish to show, like the groups a user created. For that i also have a GroupsModel.
How am i supposed to get both data from one controller?
How am i supposed to get both data from one controller?
By using a view model:
public class MyViewModel
{
public ProfileModel Profile { get; set; }
public GroupsModel Groups { get; set; }
}
and then passing this view model to the view:
public ActionResult ShowProfile()
{
var model = new MyViewModel();
model.Profile = ...
model.Groups = ...
return View(model);
}
And now your view will be strongly typed to the view model:
#model MyViewModel
and you can display information:
#Html.DisplayFor(x => x.Profile.SomeProperty)
Assuming that you aren't putting too much into a single view/controller, why not compose a simple view model which has the data you need?
public class ProfileInfo
{
public Person Person
{
get;
set;
}
public List<Group> Groups
{
get;
set;
}
}

Categories