Create a Create view for a Menu With a Dropdownlis

2019-09-08 04:49发布

问题:

i'm a student and needs to make a application for school. This is a reservation application for a restaurant. I want to create a Create view for the menu where you can give the menu a name and you choose which dishes this menu needs to have. These dishes are stored in another model. I'm using this question: Create a Dropdown List for MVC3 using Entity Framework (.edmx Model) & Razor Views && Insert A Database Record to Multiple Tables but not get it to work. This is my model:

public class MenuAddController
{
    private BonTempsDbContext db = new BonTempsDbContext();
    public Menu Menu { get; set; }
    public Dictionary<int, string> Voorgerechten { get; set; }
    public Dictionary<int, string> Hoofdgerechten { get; set; }
    public Dictionary<int, string> Nagerechten { get; set; }

    public MenuAddController() { }
    public MenuAddController(int id)
    {
        Menu = db.Menu
            .Where(e => e.id == id).SingleOrDefault();

        // instantiate your dictionaries

        foreach (var Voorgerecht in db.Voorgerecht)
        {
            Voorgerechten.Add(Voorgerecht.id, Voorgerecht.description);
        }
        foreach (var Hoofdgerecht in db.Hoofdgerecht)
        {
            Hoofdgerechten.Add(Hoofdgerecht.id, Hoofdgerecht.description);
        }
        foreach (var Nagerecht in db.Nagerecht)
        {
            Nagerechten.Add(Nagerecht.id, Nagerecht.description);
        }

    }
}

And this is my Controller.

public class MenusController : Controller
{
    // GET: Menus
    public ActionResult Index()
    {
        return View();
    }

    [HttpGet]
    public ActionResult Add()
    {
        return View(new MenuAddController());
    }

    [HttpPost]
    public ActionResult Add(MenuAddController vm)
    {
        if (ModelState.IsValid)
        {
            Menu.Add(vm.Menu); <--- this is the error line
            return View("Index"); // or wherever you go after successful add
        }

        return View(vm);
    }
}

It gives an error on

Menu.Add(vm.Menu);

Error 1 'BonTempsMVC.Menu' does not contain a definition for 'Add'

Anyone can help me with this?

回答1:

Your error is because there is no Menu property on MenusController i.e. you haven't declared anything called Menu. It looks like you're trying to use the Menu object on the MenuAddController, but it obviously doesn't exist in MenusController since it's an entirely different class.

By the names of your classes, you might not fully be grasping the MVC pattern. Your MenuAddController looks like it's attempting to be a view model and possibly a repository as well--I can't say for certain what your intention is. The good news is the MenusController is just about there. The only thing it's missing is a way to persist/save the menu (the thing being added) to a database.

Let's start with MenusController, since you seem to be closest to completion there. As mentioned the data access is all that's missing. I'd consider adding a BonTempsDbContext property to the controller class, or at the very least instantiating one inside the Add (POST) action e.g.

public class MenusController
{
    private BonTempsDbContext db = new BonTempsDbContext();
    // actions and stuff
}

or in the action itself e.g.

[HttpPost]
public ActionResult Add(SomeViewModel vm)
{
    var db = new BonTempsDbContext();
    // check model state, etc
        // db.Menus.Add(vm.Menu)
}

The only other oddity I see is the GET Add action. Your variable name suggests you're passing it a controller, which makes no sense in the context of MVC. The convention I see most often is to pass an empty view model object (described a little below) to setup the form to be posted to the POST version of the action.

This is not complete (sort of pseudo code) since you mentioned it's homework!

Now onto the other bits. MenuAddController doesn't make any sense (to me) as an object or name, so let's consider a new object called MenuAddViewModel that represents the state of a Menu object to be added i.e. the object ASP.NET MVC will bind for you when the user submits the form (which you haven't shown.) Maybe there's a Menu property on said view model object and that's what you're planning on saving to the database e.g.

public class MenuAddViewModel
{
    public Menu Menu { get; set; }
    // ...
}

It might be that simple if your form is generated in a way that MVC can automagically bind the Menu property. This way, you can reuse (almost always a good thing) the MenuAddViewModel object in both your Add actions. You pass it to GET view and it helps populate an empty form, then the user submits (POST's) to the "post" view and POOF, the data context can save it to the database or wherever it goes.

The new view model object I'm describing wouldn't need a data context object, since it only needs to know about the state of a Menu object. If you need to combine menu items, you could add properties to said view model object and go from there.