Home > Mobile >  Creating a method to submit a form without duplicating code in multiple controllers
Creating a method to submit a form without duplicating code in multiple controllers

Time:11-22

Folks, I'm looking for a solution to avoid duplication when I make the same method Post for a several controllers

Can you tell me a solution how to make a method with sending a form that I can use in any controller and return a model with an error?

I have several Controllers in which I will have a form sending (in the real project it is a service with email sending). On showed it in the screenshots and code.

public class HomeController : BaseController
    {
        public IActionResult Index()
        {
            return View();
        }

    }
public class AdditionalController : BaseController
    {
        public IActionResult Index()
        {
            return View();
        }

    }
public class BaseController : Controller
{
    [HttpPost]
    public IActionResult ScheduleDemo(UserModel model)
    {
        if (ModelState.IsValid)
        {
            return Content("The Best");
        }

        return PartialView(@"~/Views/Shared/Partial/ScheduleDemo.cshtml", model);
    }
}
ASPX 
HomeController Index.cshtml

<h1>Home</h1>
@await Html.PartialAsync("Partial/ScheduleDemo")

ASPX 
AdditionalController Index.cshtml

<h1>Additional</h1>
@await Html.PartialAsync("Partial/ScheduleDemo")

I did not create a view for the BaseController in ScheduleDemo, but use a partial view

ASPX 
ScheduleDemo.cshtml
@model UserModel

<form asp-controller="Base" asp-action="ScheduleDemo" method="post" asp-antiforgery="true">
    <p>
        <label asp-for="@Model.UserName">UserName</label><br />
        <input type="text" asp-for="@Model.UserName" />
        <span asp-validation-for="UserName"   style="color: red;"></span>
    </p>
    <p>
        <label asp-for="@Model.Age">Age</label><br />
        <input asp-for="@Model.Age" />
        <span asp-validation-for="Age"  style="color: red;"></span>
    </p>
    <p>
        <label asp-for="@Model.City">City</label><br />
        <input type="text" asp-for="@Model.City" />
        
    </p>
    <input type="submit" value="Send" />
</form>

additional url base url

In order to avoid code duplication, I tried to make BaseController and define this form sending in it, but when I make a post I go to another route localhost://Base/... and I need to stay at the same url, for example localhost://Aditional/... The biggest problem is not in that url, when I send a form successfully, everything is OK, the problem is when ModelState.IsValid == false... then model returns to me, but the page says that View by this url does not exist or in my case redirect to PartialView and it is logical, because I send form from parent controller...

CodePudding user response:

There are a few ways to avoid code duplication when making the same method POST for several controllers. One way would be to create a base controller that all your other controllers inherit from. In the base controller, you can define the POST method and have it return a model with an error. Your other controllers can then override this method if they need to.

Another way to avoid code duplication is to use a service layer. In the service layer, you can define the POST method and have it return a model with an error. Your controllers can then call the service layer method to avoid duplicating code.

For example, let's say you have a controller that needs to make a POST request to a URL. You can define a method in the base controller like this:

public class BaseController : Controller {
  [HttpPost]
  public IActionResult PostToUrl(string url, UserModel model) {
    if (ModelState.IsValid) {
      return Content("The Best");
    }

    return PartialView(@"~/Views/Shared/Partial/PostToUrl.cshtml", model);
  }
}

Your other controllers can then inherit from the BaseController and call the PostToUrl method.

If you need to make the same POST request from multiple controllers, you can also create a service layer. In the service layer, you can define the POST method and have it return a model with an error. Your controllers can then call the service layer method to avoid duplicating code.

For example, let's say you have a controller that needs to make a POST request to a URL. You can define a method in the service layer like this:

public class MyService {
  public IActionResult PostToUrl(string url, UserModel model) {
    if (ModelState.IsValid) {
      return Content("The Best");
    }

    return PartialView(@"~/Views/Shared/Partial/PostToUrl.cshtml", model);
  }
}

Your controllers can then call the MyService.PostToUrl method to avoid duplicating code.

  • Related