4 Replies - 8186 Views - Last Post: 01 August 2013 - 07:04 AM

#1 Psyguy   User is offline

  • D.I.C Regular
  • member icon

Reputation: 84
  • View blog
  • Posts: 365
  • Joined: 12-January 11

How do I use ViewModel in this situation

Posted 25 July 2013 - 02:16 PM

I am new to ASP.NET and MVC as well. That being said, i have a functioning web application, but I want to make sure I am doing it right from the get go. Unfortunately, I have still not been able to figure out one of my problems.

I have my model and it has a set of properties that need to be entered by the users. Some of those properties need to be filled with specific codes which come from the company's ERP system. I have figured out how to use LINQ to Entities in the controller to accomplish what I want, but I know that you are not supposed to do that in true MVC.

My question is this: Given the following code example, how do I implement a ViewModel to ensure that the application is conforming to MVC standards?


My Model:
 public class SalesSection
    {
        [DisplayName("New Product ID")]
        [Key, ForeignKey("NewProduct")]
        public int NewProductID { get; set; }
        //used for the FK
        public virtual NewProduct NewProduct { get; set; }

        [DisplayName("Lead Salesperson Name")]
        [DefaultValue("")]
        public string LeadName { get; set; }

        [DisplayName("Completed Date")]
        public DateTime? CompletedDate { get; set; }

        /*********Product Identification Tab*********/
        [DisplayName("Product Name")]
        [DefaultValue("")]
        [MaxLength(45)]
        public string ProductName { get; set; }

        [DisplayName("Stocked Item")]
        [DefaultValue("")]
        [MaxLength(3)]
        public string IsStocked { get; set; }//drop down list

//more properties, but one for example should be sufficient
}



My Controller (the edit one):
[HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(SalesSection salessection)
        {
            ActionResult ret;


            if(ModelState.IsValid)
            {
                FillViewBag(salessection);
                db.Entry(salessection).State = EntityState.Modified;
                db.SaveChanges();

                ret = RedirectToAction("Index", "NewProduct");
            }
            else
            {
                ViewBag.NewProductID = new SelectList(db.NewProducts, "ID", "TempName", salessection.NewProductID);

                ret = View(salessection);
            }

            return ret;
        }

//one of the queries that is run during the FillViewBag
public SelectList IsStockedOpt(SalesSection salessection)
        {
            var query = aLinqQuery;

            return new SelectList(query, "ID", "Text", salessection.IsStocked);
        }



The "FillViewBag" function is the one where I add all the SelectLists for use in the view. I would like to move this part to the ViewModel. Any ideas?

Is This A Good Question/Topic? 0
  • +

Replies To: How do I use ViewModel in this situation

#2 BattlFrog   User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 73
  • Joined: 09-April 12

Re: How do I use ViewModel in this situation

Posted 29 July 2013 - 04:37 PM

A couple questions:

What specific 'MVC Standards' are you referring to?
In the controller, am I correct in assuming this is the post controller, receiving values from the view to be saved to the database?
Is there a reason you are using the viewbag instead of strongly typing?
Is the gist of your question, how to get the select list working?
Was This Post Helpful? 0
  • +
  • -

#3 Psyguy   User is offline

  • D.I.C Regular
  • member icon

Reputation: 84
  • View blog
  • Posts: 365
  • Joined: 12-January 11

Re: How do I use ViewModel in this situation

Posted 30 July 2013 - 07:42 AM

As I said, this is my first application, so bear with me as I try to understand what you are asking:

1. I am not entirely sure what you mean by "MVC Standards". I am using the Microsoft MVC 4 solution in Visual Studio 2012 until I get a firm grasp on exactly how it is "supposed to be done".
2. Yes and no. This particular controller has methods which feed the view data from the model/database as well as post information from the view to the model/database.
3. I am using the ViewBag because I couldn't figure out another way to do it which would make it work. I am storing the data in one database and populating the comboboxes with items from a different database (i.e. a different context). I want to strongly type it in a ViewModel, but I can't figure out how I am supposed to write it properly.
4. I have the select list working, using the ViewBag, but I would rather get it into a strongly typed ViewModel.

Thanks for the clarification request. The confusion is likely a result of my unfamiliarity with how MVC works in an ideal situation. The "Hello World" applications don't help me much since I have progressed past the point of simple display and I haven't been able to find a tutorial which uses one context for storage and one for drop down list population. I'm not even sure if there is an "IDEAL" way of doing it.

Anyway, thanks for the response.
Was This Post Helpful? 0
  • +
  • -

#4 BattlFrog   User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 73
  • Joined: 09-April 12

Re: How do I use ViewModel in this situation

Posted 30 July 2013 - 08:44 AM

Ok. One thing to keep in mind is the basic of MVC. The purpose is to have a spot for everything, and ensure everything is in its spot. I think of MVC as a 'filing system for a code project'. They way I think of the seperate parts are, the Controller grabs data from a database, the model is a bucket, made specifically to hold that data, the controller puts the data into the bucket (model) and then sends the bucket to the View. The user looks in the bucket, adds/deletes/creates/modifies the data, then sends the bucket back to the controller. the controller takes the bucket and puts the data back in the database. A Perfect Circle =). Ok now on to your questions.

You should have separate action methods for getting and posting your views. They can have the same name, just make sure the post method is decorated with the [HttpPost] attribute. Here is an example of a strongly typed dropdown. There are several parts. I take the 'seperation' thing a little further, and have all my database (LINQ) statements in a separate folder called Repository. In this scenario, I supply a list of locations. The user selects a list, and the selected location is saved to a different database.

Step One, Models:

The initial entity is a reflection of the database table:

Location(LocationId, LocationName, SiteCode). This is passed in as part of the edmx file, the entity model.

Now I know I am going to have an 'Add Person' page that will save data to a couple different entities such as the Person and SelectedLocation, so I make a view model for it:

ViewModel:

    public class PersonViewModel
    {
        public int PersonId { get; set; }

        [Display(Name = "First Name *")]
        [StringLength(20)]
        [Required(ErrorMessage = "Required.")]
        public string FirstName { get; set; }

        [Display(Name = "Last Name *")]
        [StringLength(30)]
        [Required(ErrorMessage = "Required.")]
        public string LastName { get; set; }

        [StringLength(14)]
        public string Phone { get; set; }

        [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = false)]
        [Display(Name = "Date of Birth")]
        public DateTime? DOB { get; set; }

        //Start Location List proerties

        [Display(Name = "Location of Trespass *")]
        public List<SelectListItem> LocationList { get; set; }  // This is the 'bucket' that will hold the dropdown list

        public SelectedLocation SelectedLocation { get; set; }  // This is the 'bucket' that will hold the single, selected location.
    }




Now that the bucket is made, I need to fill it. First I am going to create a LINQ query to get the list of locations, then I will call it from the controller.

Repository:

        public List<SelectListItem> GetLocationList()
        {
                var query =
                        db.v_LocationsAlphabetical.OrderByDescending(x => x.Category).ThenBy(x => x.LocationName).ToList()
                        .Select(x => new SelectListItem
                        {
                            Value = x.SiteCode,
                            Text = x.LocationName
                        });

                return (query).ToList();
        }



Controller: // The first method gets the need stuff for the 'AddPerson' view.

        public ActionResult AddPerson()
        {
            var model = new PersonViewModel();  // Create an instance of the ViewModel

            model.LocationList = repo.GetLocationList();  // Call the LINQ query and drop the list of locations in the model.

            };

            return View(model);  //  Now send the model to the view
        }




Next the data gets to the view. In the view we will display the list, and saved the selected item to a different property, SelectedItem.

View:
@model TrespassTracker.Models.PersonViewModel

@{
    ViewBag.Title = "Add a New Person";
}

<div class="page-content">
    <div class="page">

                    <h2>Create a New Person Record</h2>

                @using (Html.BeginForm())
                {

                        <div class="editor-field">
                            @Html.EditorFor(model => model.FirstName)
                        </div>

                        <div class="editor-label">
                            @Html.LabelFor(model => model.LastName) @Html.ValidationMessageFor(model => model.LastName)
                        </div>
                        <div class="editor-field">
                            @Html.EditorFor(model => model.LastName)
                        </div>

                        <div class="editor-label">
                            @Html.LabelFor(model => model.DOB)
                        </div>
                        <div class="editor-field">
                            @Html.EditorFor(model => model.DOB, "DateEdit")
                        </div>

                        <div class="editor-label">
                            @Html.LabelFor(model => model.School)
                        </div>
                        <div class="editor-field">
                            @Html.DropDownListFor(model => model.SelectedLocation, new SelectList(Model.LocationList, "Value", "Text"), "--Select Location--")
                        </div>

              </div>
                    
                    <div class="controls">
                        <input type="submit" class="skbutton" value="Next Page" />
                    </div>
                    
                }




And lastly the model (bucket) goes back to the controller for saving to the database. Notice the action method has the same name 'AddPerson', but is decorated with the post attribute, so MVC can differentiate it.:

        [HttpPost]
        public ActionResult AddPerson(PersonViewModel vm)
        {


            if (ModelState.IsValid)
            {
               // I have data in the viewmodel, for 2 different entities, so I manually split it up:
               var person = new Person
               {
                   FirstName = vm.FirstName,
                   LastName = vm.LastName
               };

               var location = new SelectedLocation
               {
                   SelectedLocation = vm.SelectedLocation
               };


                db.Person.AddObject(person);
                db.SelectedLocation.AddObject(location);
                db.SaveChanges();

                var Id = model.PersonId;

                return RedirectToAction("AddOrder", "Orders", new { @id = Id });


            }
            else
            {
                return View("error");
            }
        }




And that should do it. I hope I answered your question.
Was This Post Helpful? 1
  • +
  • -

#5 Psyguy   User is offline

  • D.I.C Regular
  • member icon

Reputation: 84
  • View blog
  • Posts: 365
  • Joined: 12-January 11

Re: How do I use ViewModel in this situation

Posted 01 August 2013 - 07:04 AM

Wow. That is a great answer! Thank you so much.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1