0

I'm just getting started with MVC. I'm building a project in asp.net mcv 5 using entity framework. I have researched many threads but I didn't find anything that would help solve my problem. I have two models:
Resource:

public class Resource
    {
        [Key]
        public int Id { get; set; }

        [Required]
        public string Name { get; set; }

        public string Comments { get; set; }

        [Required]
        public ResourceType Type { get; set; }

        public bool IsActive { get; set; }
    }

ResourceType:

public class ResourceType
    {
        [Key]
        public int Id { get; set; }

        [Required]
        public string Name { get; set; }
    }

And the problem is: In View > Resource > Create I want to add DropDownList for object ResourceType Type with values from class ResourceType string Name
Create.cshtml:

@model NetAudit.Models.Resource

@{
    ViewBag.Title = "Create Resource";
}

<h2>Create</h2>


@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>Resource</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Comments, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Comments, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Comments, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Type, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                HERE
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.IsActive, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                <div class="checkbox">
                    @Html.EditorFor(model => model.IsActive)
                    @Html.ValidationMessageFor(model => model.IsActive, "", new { @class = "text-danger" })
                </div>
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Dodaj" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to list", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

RecourceType controller:

using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web.Mvc;
using NetAudit.Models;

namespace NetAudit.Controllers
{
    public class ResourceTypesController : BaseController
    {
        private readonly ApplicationDbContext _db = new ApplicationDbContext();

        [Authorize]
        public ActionResult Index()
        {
            return View(_db.ResourceTypes.ToList());
        }
        [Authorize]
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            var resourceType = _db.ResourceTypes.Find(id);

            if (resourceType == null)
            {
                return HttpNotFound();
            }

            return View(resourceType);
        }
        [Authorize]
        public ActionResult Create()
        {
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]

        public ActionResult Create(ResourceType resourceType)
        {
            if (ModelState.IsValid)
            {
                _db.ResourceTypes.Add(resourceType);
                _db.SaveChanges();

                return RedirectToAction("Index");
            }

            return View(resourceType);
        }
        [Authorize]
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            var resourceType = _db.ResourceTypes.Find(id);

            if (resourceType == null)
            {
                return HttpNotFound();
            }

            return View(resourceType);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]

        public ActionResult Edit(ResourceType resourceType)
        {
            if (ModelState.IsValid)
            {
                _db.Entry(resourceType).State = EntityState.Modified;
                _db.SaveChanges();

                return RedirectToAction("Index");
            }

            return View(resourceType);
        }
        [Authorize]
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            var resourceType = _db.ResourceTypes.Find(id);

            if (resourceType == null)
            {
                return HttpNotFound();
            }

            return View(resourceType);
        }

        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]

        public ActionResult DeleteConfirmed(int id)
        {
            var resourceType = _db.ResourceTypes.Find(id);

            if (resourceType == null)
            {
                return HttpNotFound();
            }

            _db.ResourceTypes.Remove(resourceType);
            _db.SaveChanges();

            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                _db.Dispose();
            }

            base.Dispose(disposing);
        }
    }
}

Resource controller:

using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web.Mvc;
using NetAudit.Models;

namespace NetAudit.Controllers
{
    public class ResourceTypesController : BaseController
    {
        private readonly ApplicationDbContext _db = new ApplicationDbContext();

        [Authorize]
        public ActionResult Index()
        {
            return View(_db.ResourceTypes.ToList());
        }
        [Authorize]
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            var resourceType = _db.ResourceTypes.Find(id);

            if (resourceType == null)
            {
                return HttpNotFound();
            }

            return View(resourceType);
        }
        [Authorize]
        public ActionResult Create()
        {
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]

        public ActionResult Create(ResourceType resourceType)
        {
            if (ModelState.IsValid)
            {
                _db.ResourceTypes.Add(resourceType);
                _db.SaveChanges();

                return RedirectToAction("Index");
            }

            return View(resourceType);
        }
        [Authorize]
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            var resourceType = _db.ResourceTypes.Find(id);

            if (resourceType == null)
            {
                return HttpNotFound();
            }

            return View(resourceType);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]

        public ActionResult Edit(ResourceType resourceType)
        {
            if (ModelState.IsValid)
            {
                _db.Entry(resourceType).State = EntityState.Modified;
                _db.SaveChanges();

                return RedirectToAction("Index");
            }

            return View(resourceType);
        }
        [Authorize]
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            var resourceType = _db.ResourceTypes.Find(id);

            if (resourceType == null)
            {
                return HttpNotFound();
            }

            return View(resourceType);
        }

        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]

        public ActionResult DeleteConfirmed(int id)
        {
            var resourceType = _db.ResourceTypes.Find(id);

            if (resourceType == null)
            {
                return HttpNotFound();
            }

            _db.ResourceTypes.Remove(resourceType);
            _db.SaveChanges();

            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                _db.Dispose();
            }

            base.Dispose(disposing);
        }
    }
}

I spent a lot of time looking for a solution to this problem. I would appreciate your feedback on this.

1

2 Answers 2

1

I think the best way to get what you want is to create a ViewModel, this allows you create a view with various classes.

Under your solution create a new folder named ViewModels. Create a new class and name it CreateResourceViewModel.

    public class CreateResourceViewModel
{

   public Resource Resource {get;set;}
   public SelectList ResourceType {get;set;} //this will create the list of resourcetypes
   public int IdResourceType {get;set;} //this will be used to select the id of resourceType you are selecting.

public CreateResourceViewModel (Resource resource,List<ResourceType>resourceType) //create a constructor 
{
 this.Resource = resource;
//here you will set the list as a new selectList, stating where the list will come from. the Id de valuevaluefield, and the name is the valuetextfield
this.ResourceType= new SelectList(resourceType,"Id","Name");
}

public CreateResourceViewModel(){} //you need this second constructor

 }

Now you need a Create ActionResult that accepts a ViewModel in your resource Controller

  // GET: Locals/Create
    public ActionResult Create()
    {
        Resource resource = new Resource();
        List<ResourceType> resourceType;

        using (yourcontext db = new yourcontext())
        {
            resourceType = db.ResourceType.ToList(); //fill your list with the resourceTypes that are in your database

        }

        CreateResourceViewModel vm = new CreateResourceViewModel(resource,resourceType); //create a new viewmodel and give it the parameters necesary that we created


        return View(vm);
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(CreateResourceViewModel vm)
    {
        using (yourcontext db = new yourcontext())
        {
            if (ModelState.IsValid)
            {
                try {
                    vm.Resource.Type = db.ResourceTpe.Find(vm.IdResourceType); //using the ID selected in the view find it in the database

                    db.Resources.Add(vm.Resource);
                    db.SaveChanges();
                    return RedirectToAction("Index");

                }
                catch (Exception e)
                {
                    e.Message();
                }
            }

            return View(vm);
        }
    }

Now onto the view for the ViewModel

    @model  yourSolution.ViewModels.CreateResourceViewModel

    @{
        ViewBag.Title = "Create";

    }


    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()

        <div class="form-horizontal">
            <h4>Resource</h4>
            <hr />
            @Html.ValidationSummary(true, "", new { @class = "text-danger" })
            <div class="form-group">
                @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
                </div>
            </div>

            <div class="form-group">
                @Html.LabelFor(model => model.Comments, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(model => model.Comments, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => model.Comments, "", new { @class = "text-danger" })
                </div>
            </div>

         <div class="form-group">
                @Html.LabelFor(model => model.ResourceType, htmlAttributes: new { @class = "control-label col-md-2" })

//this is what you need to create a dropdownlist with all the resourceTypes

                <div class="col-md-10">
                    @Html.DropDownListFor(model => model.IdResourceType, Model.ResourceType,"--Select--" )
                </div>
            </div>



            <div class="form-group">
                @Html.LabelFor(model => model.IsActive, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    <div class="checkbox">
                        @Html.EditorFor(model => model.IsActive)
                        @Html.ValidationMessageFor(model => model.IsActive, "", new { @class = "text-danger" })
                    </div>
                </div>
            </div>

            <div class="form-group">
                <div class="col-md-offset-2 col-md-10">
                    <input type="submit" value="Dodaj" class="btn btn-default" />
                </div>
            </div>
        </div>
    }

    <div>
        @Html.ActionLink("Back to list", "Index")
    </div>

    @section Scripts {
        @Scripts.Render("~/bundles/jqueryval")
    }

Hope this helps!!

Sign up to request clarification or add additional context in comments.

Comments

1

First of you have a mistake to put Resource Controller here (both of Resource and ResourceType are ResourceType). fix it first.

Put in the Here section this code to render a select element from ViewBag.Types:

@Html.DropDownListFor(m => m.Type.Id, (SelectList)ViewBag.Types, new
                           {
                               @class = "form-control"
                           });

Before it you must fill ViewBag.Types in the action, Change the first Create action of ResourceController to this:

        [Authorize]
        public ActionResult Create()
        {
            ViewBag.Types = new SelectList(_db.ResourceTypes.ToList(), "Id", "Name", "0");
            return View();
        }

It will be worked.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.