Using View model instead of data to create

crud operation using viewmodel in mvc
how to use viewmodel in asp.net mvc with example
asp.net mvc viewmodel best practices
difference between model and viewmodel in mvc
viewmodel example
mvvm
viewmodel c#
view model razor

I am trying to use viewmodels instead of using data directly for most of the things i am trying to do.

One such thing is trying to book a Passenger/Customer on a flight. The data uses two keys/IDs, the passenger Id and the Flight Id.

now the view model looks something like this:

namespace WebSite.Models.PassengerViewModels
    {
        public class FlightBookingViewModel
        {
            [Display(Name = "Passenger ID ")]
            public int IdC { get; set; }

            [Display(Name = "E-mail Address ")]
            [Required]
            [DataType(DataType.EmailAddress)]
            public string Email { get; set; }

            [Display(Name = "Flight ID ")]
            public int IdF { get; set; }

            [Display(Name = "Flight Name ")]
            public int Name { get; set; }

        }
    }

But the scaffold code to create a booking looks something like this:

public IActionResult Create()
        {
            ViewData["IdC"] = new SelectList(_context.Passengers, "Id", "Email");
            ViewData["IdF"] = new SelectList(_context.Flights, "Id", "Name");

            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Create([Bind("IdC,IdF,Attended")] FlightBooking model)
        {
            if (ModelState.IsValid)
            {
                _context.Add(model);
                await _context.SaveChangesAsync();
                return RedirectToAction(nameof(Index));
            }
            ViewData["IdC"] = new SelectList(_context.Customers, "Id", "Email", model.IdF);
            ViewData["IdF"] = new SelectList(_context.Events, "Id", "Name", model.IdE);
            return View(model);
        }

Then the view page for the create is this:

@model WebSite.Data.FlightBooking

@{
    ViewData["Title"] = "Create";
}

<h2>Create</h2>

<h4>FlightBooking</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Create">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="IdC" class="control-label"></label>
                <select asp-for="IdC" class ="form-control" asp-items="ViewBag.IdC"></select>
            </div>
            <div class="form-group">
                <label asp-for="IdF" class="control-label"></label>
                <select asp-for="IdF" class ="form-control" asp-items="ViewBag.IdF"></select>
            </div>
            <div class="form-group">
                <div class="checkbox">
                    <label>
                        <input asp-for="Attended" /> @Html.DisplayNameFor(model => model.Attended)
                    </label>
                </div>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Now i tried to implement the viewmodel into this but it just wouldnt bring the data into the dropdown list. and i am unsure how to get that working.

Try using this in the view -

   @Html.DropDownList("IdC", 
                         ViewData["IdC"],
                        "Select Flight ID",
                        new { @class = "form-control" })

Managing Data With ViewModel In ASP.NET MVC, Where we should use ViewModel � Managing or creating dropdown lists for a specific entity � Creating Master-Details View in data-driven websites� Why use ViewModels instead of Blocks Create View using ViewModel. in a phtml file so by this we can get the ViewModel and call the function of ViewModel from which we want to render data

Now i tried to implement the viewmodel into this but it just wouldnt bring the data into the dropdown list. and i am unsure how to get that working.

If you'd like to pass data of Passengers and Flights via a ViewModel (rather than ViewData) to your view page, then populate two dorpdown lists with these data, you can refer to the following code snippet.

Passenger, Flight and FlightBookingViewModel class

public class FlightBookingViewModel
{
    public List<Passenger> Passengers { get; set; }
    public List<Flight> Flights { get; set; }

    public FlightBooking FlightBooking { get; set; }
}

public class Passenger
{
    [Display(Name = "Passenger ID ")]
    public int IdC { get; set; }

    [Display(Name = "E-mail Address ")]
    [Required]
    [DataType(DataType.EmailAddress)]
    public string Email { get; set; }
}

public class Flight
{
    [Display(Name = "Flight ID ")]
    public int IdF { get; set; }

    [Display(Name = "Flight Name ")]
    public string Name { get; set; }
}

In View page

@model FlightBookingViewModel

@{
    ViewData["Title"] = "Create";
}

<h1>Create</h1>

<h4>FlightBooking</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Create">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="@Model.FlightBooking.IdC" class="control-label"></label>
                <select asp-for="@Model.FlightBooking.IdC" class="form-control" asp-items="@(new SelectList(Model.Passengers,"IdC","Email"))"></select>
            </div>
            <div class="form-group">
                <label asp-for="@Model.FlightBooking.IdF" class="control-label"></label>
                <select asp-for="@Model.FlightBooking.IdF" class="form-control" asp-items="@(new SelectList(Model.Flights,"IdF","Name"))"></select>
            </div>
            <div class="form-group">
                <div class="checkbox">
                    <label>
                        <input asp-for="@Model.FlightBooking.Attended" /> @Html.DisplayNameFor(model => model.FlightBooking.Attended)
                    </label>
                </div>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </form>
    </div>
</div>

In controller action

public IActionResult Create([Bind("FlightBooking")] FlightBookingViewModel model)
{

    // replace following test code with your code logic

    var passengers = new List<Passenger>
    {
        new Passenger
        {
            IdC = 1,
            Email = "p1@test.com"
        },
        new Passenger
        {
            IdC = 2,
            Email = "p2@test.com"
        },
        new Passenger
        {
            IdC = 3,
            Email = "p3@test.com"
        }
    };

    var flights = new List<Flight>
    {
        new Flight
        {
            IdF = 1,
            Name = "F1"
        },
        new Flight
        {
            IdF = 2,
            Name = "F2"
        },
        new Flight
        {
            IdF = 3,
            Name = "F3"
        }
    };

    var fb_viewmodel = new FlightBookingViewModel
    {
        Passengers = passengers,
        Flights = flights,
        FlightBooking = new FlightBooking()
    };

    return View(fb_viewmodel);
}

Test Result

How to Use ViewModel in Asp.Net MVC with Example, In view to display both entities (Customer entity + Order entity) data then we need to create� A ViewModel is always created in association with a scope (a fragment or an activity) and will be retained until its associated Activity or Fragment is disposed of forever — that means view data survives events like a Fragment / Activity being recreated due to rotation.

So i finally gotten help with this from my tutor, so the first bit of the controller code which is this:

public IActionResult Create()
        {
            ViewData["PassengerId"] = new SelectList(_context.Passengers, "Id", "Email");
            ViewData["FlightId"] = new SelectList(_context.Flights, "Id", "Name");

            return View();
        }

Is already a viewmodel in a sense and protects the data.

now the work in the second bit of code of the controller:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("PassengerId,IdF,Attended")] FlightBookingViewModel model)
        {
            if (ModelState.IsValid)
            {
                FlightBooking flightBooking = new FlightBooking
                {
                    PassengerId = model.PassengerId,
                    FlightId = model.FlightId,
                    Attended = model.Attended
                }
                await _context.Guests.AddAsync(flightBooking);
                await _context.SaveChangesAsync();
                return RedirectToAction(nameof(Index));
            }
            ViewData["PassengerId"] = new SelectList(_context.Customers, "Id", "Email", model.PassengerId);
            ViewData["FlightId"] = new SelectList(_context.Events, "Id", "Name", model.FlightId);
            return View(model);
        }

This way i can get the drop down menu working when the viewmodel id's are named the same as the data id's

The problem seemed like it was in the id names not being recognised. so once the viewmodels id names are the same as that of the data the issues went away and i am still using viewmodels

Model-View-ViewModel (MVVM) Explained, The view takes certain liberties to make this data more presentable. For example, a date might Instead, it will synchronize this with the viewmodel. Here is an� Generally View Models in asp.net mvc are easy to use if we clear with information like where we want to display data or get input data from various domain models then always use ViewModels. This is how we can create viewmodel in asp.net mvc and use it in mvc applications based on our requirements.

ViewModel Overview, If the system destroys or re-creates a UI controller, any transient UI-related data you store in them is lost. For example, your app may include a list of users in one of� As you can see, now we are passing the view model as a parameter to the view. This is the view model that contains all the data required by the Details view. As you can notice, now we are not using any ViewData or ViewBag to pass the Page Title and Header to the view instead they are also part of the ViewModel which makes it a strongly typed view.

Is creating ViewModels in Web API a bad practice?, It seems like your colleague is simply suggesting to not make an explicit viewmodel and instead is trying to reuse existing DTOs but with� In the above code, we’ve populated the model classes with data. Now it is time to make ViewModel. Conventionally create a folder into the project, and give it name “ViewModels”. Look, ViewModel is simply a class having “ViewModel” as a suffix. So, create a class and give it a name as “CustomerViewModel”. Place the following code

Is that good idea to add ViewModel exactly same as Model , I want to use this model on the view (for example home page) AND I want to use Id, Name & Value , so if I want to create ViewModel, I'll add following: Here Mudassar Ahmed Khan has explained with an example, how to use a DataSet or DataTable as Model in View in ASP.Net MVC Razor. Though it is not a good practice to use DataSet or DataTable as Model in View in MVC architecture, thus user’s please make a note that this is just an informative article and does not recommend to use DataSet or DataTable as Model in View in ASP.Net MVC.

Comments
  • Hi @SSM, any updates about this case? Have you achieved the requirement?
  • @FeiHan Yes sorry. i actually gotten the answer from one of my tutors. I have posted the answer to show what i have done and why.
  • Where in the view would i need to put it in?