locked
Submit button action in controller RRS feed

  • Question

  • User-501297529 posted

    I'm trying to find out the best way to create a submit and add button action in a controller.

    I have a HttpGet for Create (Submit) but not sure how to do a HttpPost or if Get or Post is even needed:

     [HttpGet]
            public IActionResult Create()
            {
                var drafList = _drService.GetDraft().ToList();
    
                var IndexViewModel = new IndexViewModel();
                IndexViewModel.Draft = draftList;
                IndexViewModel.Published = _drService.GetPublished();
                IndexViewModel.Current = _drService.GetCurrent();
    
                return View(IndexViewModel);
            }

    For the View, 

     <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">
                            <div class="col-md-3">
                                <label for="asof">As of:</label>
                            </div>
                            <div class="col-md-9">
                                <input name="AsOf" type="date" title="AsOf" class="form-control" />
                            </div>
                        </div>
                        <div class="clearfix col-md-12"></div>
                        <div class="clearfix col-md-12"></div>
                        <div class="form-group">
                            <div class="col-md-2">
                                <label for="title">Title:</label>
                            </div>
                            <div class="col-md-9 col-md-offset-1">
                                <input type="text" class="form-control" id="title" />
                            </div>
                            <div class="col-md-6">
                                <input type="submit" value="Add" class="btn btn-primary" />
                            </div>
                        </div>
    
                    </form>
                </div>
            </div>

    Monday, July 22, 2019 1:46 PM

Answers

  • User1120430333 posted

    The 'adm' is the AuthorDomainModel object in the Models folder that is DI into the AuthorController, which follows these principles.

     https://www.c-sharpcorner.com/UploadFile/56fb14/understanding-separation-of-concern-and-Asp-Net-mvc/

    https://docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/overview/understanding-models-views-and-controllers-cs

    <copied>

    An MVC model contains all of your application logic that is not contained in a view or a controller. The model should contain all of your application business logic, validation logic, and database access logic. For example, if you are using the Microsoft Entity Framework to access your database, then you would create your Entity Framework classes (your .edmx file) in the Models folder.

    A view should contain only logic related to generating the user interface. A controller should only contain the bare minimum of logic required to return the right view or redirect the user to another action (flow control). Everything else should be contained in the model.

    In general, you should strive for fat models and skinny controllers. Your controller methods should contain only a few lines of code. If a controller action gets too fat, then you should consider moving the logic out to a new class in the Models folder.

    <end>

    namespace PublishingCompany.Models
    {
        public interface IAuthorDM
        {
            AuthorVM GetAll();
            AuthorVM.Author Find(int id);
            AuthorVM.Author Add();
            void Add(AuthorVM.Author author);
            AuthorVM.Author Update(int id);
            void Update(AuthorVM.Author author);
            void Delete(int id);
        }
    }
    
    ======================================================================================
    using System.Linq;
    using ServiceLayer;
    using Entities;
    
    namespace PublishingCompany.Models
    {
        public class AuthorDM :IAuthorDM
        {
            private IAuthorSvc svc;
            public AuthorDM(IAuthorSvc authorSvc)
            {
                svc = authorSvc;
            }
    
            public AuthorVM GetAll()
            {
                var vm = new AuthorVM();
    
                var dtos = svc.GetAll().ToList();
    
                vm.Authors.AddRange(dtos.Select(dto => new AuthorVM.Author()
                {
                    AuthorID = dto.AuthorId,
                    FirstName = dto.FirstName,
                    LastName = dto.LastName
                }).ToList());
    
                return vm;
            }
    
            public AuthorVM.Author Find(int id)
            {
                var dto = svc.Find(id);
    
                var author = new AuthorVM.Author
                {
                    AuthorID = dto.AuthorId,
                    FirstName = dto.FirstName,
                    LastName = dto.LastName
                };
    
                return author;
            }
    
            public AuthorVM.Author Add()
            {
                return new AuthorVM.Author();
            }
    
            public void Add(AuthorVM.Author author)
            {
                var dto = new DtoAuthor
                {
                    FirstName = author.FirstName,
                    LastName = author.LastName
                };
    
                svc.Add(dto);
            }
    
            public AuthorVM.Author Update(int id)
            {
                var dto = Find(id);
    
                var author = new AuthorVM.Author
                {
                    AuthorID = dto.AuthorID,
                    FirstName = dto.FirstName,
                    LastName = dto.LastName
                };
    
                return author;
            }
    
            public void Update(AuthorVM.Author author)
            {
                var dto = new DtoAuthor
                {
                    AuthorId = author.AuthorID,
                    FirstName = author.FirstName,
                    LastName = author.LastName
                };
    
                svc.Update(dto);
            }
    
            public void Delete(int id)
            {
                var dto = new DtoId
                {
                    Id = id
                };
    
                svc.Delete(dto);
            }
           
        }
    }
    
    using Microsoft.AspNetCore.Mvc;
    using PublishingCompany.Models;
    
    namespace PublishingCompany.Controllers
    {
        public class AuthorController : Controller
        {
            private IAuthorDM adm;
            public AuthorController(IAuthorDM authorDM)
            {
                adm = authorDM;
            }
    
            public IActionResult Index()
            {
                return View(adm.GetAll());
            }
    
            public IActionResult Detail(int id = 0)
            {
                return id == 0 ? null : View(adm.Find(id));
            }
    
            public IActionResult Create()
            {
                return View(adm.Add());
            }
    
            [HttpPost]
            public ActionResult Create(AuthorVM.Author author, string submit)
            {
                if (submit == "Cancel") return RedirectToAction("Index");
    
                if (!ModelState.IsValid) return View(author);
    
                adm.Add(author);
                return RedirectToAction("Index");
            }
            
            public ActionResult Edit(int id = 0)
            {
                return id == 0 ? null : View(adm.Update(id));
            }
            
            [HttpPost]
            public ActionResult Edit(AuthorVM.Author author, string submit)
            {
                if (submit == "Cancel") return RedirectToAction("Index");
                            
                if (!ModelState.IsValid) return View(author);
                           
                adm.Update(author);
                return RedirectToAction("Index");
            }
    
            public IActionResult Delete(int id = 0)
            {
                if (id > 0) adm.Delete(id);
    
                return RedirectToAction("Index");
            }
    
            public ActionResult Cancel()
            {
                return RedirectToAction("Index", "Home");
            }
        }
    }

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, July 22, 2019 9:19 PM

All replies

  • User475983607 posted

    The two code snippets seem to be unrelated.  We cannot see the models or the CreateDor action.  There not enough context to understand what programming problem you trying to solve.  Are you trying to save user input?

    The only input shown that submits to the CreateDor action is the AsOf input.  Is that what you expect?

    <div class="col-md-9">
    	<input name="AsOf" type="date" title="AsOf" class="form-control" />
    </div>

    Title is missing a name attribute.

    <div class="col-md-9 col-md-offset-1">
    	<input type="text" class="form-control" id="title" />
    </div>

    The browser will not submit the title input.

    Maybe you are trying to show a list of items.  Followed by editing one of the items.  If so, please go through a few tutorials first as the tutorials cover basic MVC patterns step-by-step.

    https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/?view=aspnetcore-2.0

    https://dotnet.microsoft.com/learn/web

    Monday, July 22, 2019 2:11 PM
  • User-501297529 posted

    mgebhard

    The two code snippets seem to be unrelated.  We cannot see the models or the CreateDor action.  There not enough context to understand what programming problem you trying to solve.  Are you trying to save user input?

    The only input shown that submits to the CreateDor action is the AsOf input.  Is that what you expect?

    <div class="col-md-9">
    	<input name="AsOf" type="date" title="AsOf" class="form-control" />
    </div>

    Title is missing a name attribute.

    <div class="col-md-9 col-md-offset-1">
    	<input type="text" class="form-control" id="title" />
    </div>

    The browser will not submit the title input.

    Maybe you are trying to show a list of items.  Followed by editing one of the items.  If so, please go through a few tutorials first as the tutorials cover basic MVC patterns step-by-step.

    https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/?view=aspnetcore-2.0

    https://dotnet.microsoft.com/learn/web

    It is supposed to be 'Create' not 'CreateDor'. Fixed in the OP.

    As for the attributes, I'm not concerned about that unless it involves the issue with the controller. My concern is what the action should be in the controller as stated in the OP.

    Monday, July 22, 2019 2:26 PM
  • User475983607 posted

    bootzilla

    My concern is what the action should be in the controller as stated in the OP.

    The controller action and HTML form action must match.

    [HttpPost]
    public IActionResult Create(MyModel model)
    {
    
    }
    <form asp-action="Create" method="post">

    The tutorials in my initial post cover this concept plus we've discussed this concept few times in similar threads. 

    The tutorial step; https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/controller-methods-views?view=aspnetcore-2.2

    Monday, July 22, 2019 2:44 PM
  • User1120430333 posted

    Are you talking about something like the below?

    @model AuthorVM.Author
    
    <!DOCTYPE html>
    
    <html>
    <head>
        <title>Create</title>
    </head>
    <style type="text/css">
        .editor-field > label {
            float: left;
            width: 150px;
        }
    
        .txtbox {
            font-family: Arial, Helvetica, sans-serif;
            font-size: 12px;
            background: white;
            color: black;
            cursor: text;
            border-bottom: 1px solid #104A7B;
            border-right: 1px solid #104A7B;
            border-left: 1px solid #104A7B;
            border-top: 1px solid #104A7B;
            padding-top: 10px;
        }
    </style>
    
    <body>
        <h1>Author</h1>
    
        @using (Html.BeginForm())
         {
            @Html.ValidationSummary(false, "", new { @class = "text-danger" })
    
            <fieldset>
    
                <legend>Create</legend>
    
                <div class="editor-field">
                    @Html.Label("First Name:")
                    @Html.TextBoxFor(model => model.FirstName, new { @Cssclass = "txtbox" })
                    @Html.ValidationMessageFor(model => model.FirstName, "", new { @class = "text-danger" })
                </div>
                <br />
                <div class="editor-field">
                    @Html.Label("Last Name:")
                    @Html.TextBoxFor(model => model.LastName, new { @Cssclass = "txtbox" })
                    @Html.ValidationMessageFor(model => model.LastName, "", new { @class = "text-danger" })
                </div>
                <br />
                
                <p>
                    <input type="submit" name="submit" value="Save" />
                    <input type="submit" name="submit" value="Cancel" />
                </p>
    
            </fieldset>
         }
    
    </body>
    </html>
    
    
    public IActionResult Create()
            {
                return View(adm.Add());
            }
    
            [HttpPost]
            public ActionResult Create(AuthorVM.Author author, string submit)
            {
                if (submit == "Cancel") return RedirectToAction("Index");
    
                if (!ModelState.IsValid) return View(author);
    
                adm.Add(author);
                return RedirectToAction("Index");
            }
      public AuthorVM.Author Add()
            {
                return new AuthorVM.Author();
            }
    
            public void Add(AuthorVM.Author author)
            {
                var dto = new DtoAuthor
                {
                    FirstName = author.FirstName,
                    LastName = author.LastName
                };
    
                svc.Add(dto);
            }

    Monday, July 22, 2019 5:45 PM
  • User-501297529 posted

    DA924

    Are you talking about something like the below?

    @model AuthorVM.Author
    
    <!DOCTYPE html>
    
    <html>
    <head>
        <title>Create</title>
    </head>
    <style type="text/css">
        .editor-field > label {
            float: left;
            width: 150px;
        }
    
        .txtbox {
            font-family: Arial, Helvetica, sans-serif;
            font-size: 12px;
            background: white;
            color: black;
            cursor: text;
            border-bottom: 1px solid #104A7B;
            border-right: 1px solid #104A7B;
            border-left: 1px solid #104A7B;
            border-top: 1px solid #104A7B;
            padding-top: 10px;
        }
    </style>
    
    <body>
        <h1>Author</h1>
    
        @using (Html.BeginForm())
         {
            @Html.ValidationSummary(false, "", new { @class = "text-danger" })
    
            <fieldset>
    
                <legend>Create</legend>
    
                <div class="editor-field">
                    @Html.Label("First Name:")
                    @Html.TextBoxFor(model => model.FirstName, new { @Cssclass = "txtbox" })
                    @Html.ValidationMessageFor(model => model.FirstName, "", new { @class = "text-danger" })
                </div>
                <br />
                <div class="editor-field">
                    @Html.Label("Last Name:")
                    @Html.TextBoxFor(model => model.LastName, new { @Cssclass = "txtbox" })
                    @Html.ValidationMessageFor(model => model.LastName, "", new { @class = "text-danger" })
                </div>
                <br />
                
                <p>
                    <input type="submit" name="submit" value="Save" />
                    <input type="submit" name="submit" value="Cancel" />
                </p>
    
            </fieldset>
         }
    
    </body>
    </html>
    
    public IActionResult Create()
            {
                return View(adm.Add());
            }
    
            [HttpPost]
            public ActionResult Create(AuthorVM.Author author, string submit)
            {
                if (submit == "Cancel") return RedirectToAction("Index");
    
                if (!ModelState.IsValid) return View(author);
    
                adm.Add(author);
                return RedirectToAction("Index");
            }
      public AuthorVM.Author Add()
            {
                return new AuthorVM.Author();
            }
    
            public void Add(AuthorVM.Author author)
            {
                var dto = new DtoAuthor
                {
                    FirstName = author.FirstName,
                    LastName = author.LastName
                };
    
                svc.Add(dto);
            }

    What is adm? Is that the object?

    public IActionResult Create()
            {
                return View(adm.Add());
            }
    
            [HttpPost]
            public ActionResult Create(AuthorVM.Author author, string submit)
            {
                if (submit == "Cancel") return RedirectToAction("Index");
    
                if (!ModelState.IsValid) return View(author);
    
                adm.Add(author);
                return RedirectToAction("Index");
            }

    Monday, July 22, 2019 6:58 PM
  • User1120430333 posted

    The 'adm' is the AuthorDomainModel object in the Models folder that is DI into the AuthorController, which follows these principles.

     https://www.c-sharpcorner.com/UploadFile/56fb14/understanding-separation-of-concern-and-Asp-Net-mvc/

    https://docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/overview/understanding-models-views-and-controllers-cs

    <copied>

    An MVC model contains all of your application logic that is not contained in a view or a controller. The model should contain all of your application business logic, validation logic, and database access logic. For example, if you are using the Microsoft Entity Framework to access your database, then you would create your Entity Framework classes (your .edmx file) in the Models folder.

    A view should contain only logic related to generating the user interface. A controller should only contain the bare minimum of logic required to return the right view or redirect the user to another action (flow control). Everything else should be contained in the model.

    In general, you should strive for fat models and skinny controllers. Your controller methods should contain only a few lines of code. If a controller action gets too fat, then you should consider moving the logic out to a new class in the Models folder.

    <end>

    namespace PublishingCompany.Models
    {
        public interface IAuthorDM
        {
            AuthorVM GetAll();
            AuthorVM.Author Find(int id);
            AuthorVM.Author Add();
            void Add(AuthorVM.Author author);
            AuthorVM.Author Update(int id);
            void Update(AuthorVM.Author author);
            void Delete(int id);
        }
    }
    
    ======================================================================================
    using System.Linq;
    using ServiceLayer;
    using Entities;
    
    namespace PublishingCompany.Models
    {
        public class AuthorDM :IAuthorDM
        {
            private IAuthorSvc svc;
            public AuthorDM(IAuthorSvc authorSvc)
            {
                svc = authorSvc;
            }
    
            public AuthorVM GetAll()
            {
                var vm = new AuthorVM();
    
                var dtos = svc.GetAll().ToList();
    
                vm.Authors.AddRange(dtos.Select(dto => new AuthorVM.Author()
                {
                    AuthorID = dto.AuthorId,
                    FirstName = dto.FirstName,
                    LastName = dto.LastName
                }).ToList());
    
                return vm;
            }
    
            public AuthorVM.Author Find(int id)
            {
                var dto = svc.Find(id);
    
                var author = new AuthorVM.Author
                {
                    AuthorID = dto.AuthorId,
                    FirstName = dto.FirstName,
                    LastName = dto.LastName
                };
    
                return author;
            }
    
            public AuthorVM.Author Add()
            {
                return new AuthorVM.Author();
            }
    
            public void Add(AuthorVM.Author author)
            {
                var dto = new DtoAuthor
                {
                    FirstName = author.FirstName,
                    LastName = author.LastName
                };
    
                svc.Add(dto);
            }
    
            public AuthorVM.Author Update(int id)
            {
                var dto = Find(id);
    
                var author = new AuthorVM.Author
                {
                    AuthorID = dto.AuthorID,
                    FirstName = dto.FirstName,
                    LastName = dto.LastName
                };
    
                return author;
            }
    
            public void Update(AuthorVM.Author author)
            {
                var dto = new DtoAuthor
                {
                    AuthorId = author.AuthorID,
                    FirstName = author.FirstName,
                    LastName = author.LastName
                };
    
                svc.Update(dto);
            }
    
            public void Delete(int id)
            {
                var dto = new DtoId
                {
                    Id = id
                };
    
                svc.Delete(dto);
            }
           
        }
    }
    
    using Microsoft.AspNetCore.Mvc;
    using PublishingCompany.Models;
    
    namespace PublishingCompany.Controllers
    {
        public class AuthorController : Controller
        {
            private IAuthorDM adm;
            public AuthorController(IAuthorDM authorDM)
            {
                adm = authorDM;
            }
    
            public IActionResult Index()
            {
                return View(adm.GetAll());
            }
    
            public IActionResult Detail(int id = 0)
            {
                return id == 0 ? null : View(adm.Find(id));
            }
    
            public IActionResult Create()
            {
                return View(adm.Add());
            }
    
            [HttpPost]
            public ActionResult Create(AuthorVM.Author author, string submit)
            {
                if (submit == "Cancel") return RedirectToAction("Index");
    
                if (!ModelState.IsValid) return View(author);
    
                adm.Add(author);
                return RedirectToAction("Index");
            }
            
            public ActionResult Edit(int id = 0)
            {
                return id == 0 ? null : View(adm.Update(id));
            }
            
            [HttpPost]
            public ActionResult Edit(AuthorVM.Author author, string submit)
            {
                if (submit == "Cancel") return RedirectToAction("Index");
                            
                if (!ModelState.IsValid) return View(author);
                           
                adm.Update(author);
                return RedirectToAction("Index");
            }
    
            public IActionResult Delete(int id = 0)
            {
                if (id > 0) adm.Delete(id);
    
                return RedirectToAction("Index");
            }
    
            public ActionResult Cancel()
            {
                return RedirectToAction("Index", "Home");
            }
        }
    }

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, July 22, 2019 9:19 PM
  • User711641945 posted

    Hi bootzilla,

    1.[HttpGet] is used to retrieve and show the data.And [HttpPost] is used to submit data to the controller.

    2.You need a [HttpGet] action to get into a view and then submit data to the [HttpPost] action.

    3.As Magebhard said,when you did `create` operation, you need a [HttpPost]  in the  action and could use asp-for tag to pass the model to the Action.

    The controller action and HTML form action must match.

    [HttpPost]
    public IActionResult Create(MyModel model)
    {
    
    }
    <form asp-action="Create" method="post">

    Best Regards,

    Rena

    Tuesday, July 23, 2019 9:41 AM