0

I have recently started to use Areas in my .net core web app to organise hundreds of files in the project. It all worked well, until now.

I have a controller in its own area, with these decorators

namespace MyApp.Controllers
{
    [Area("Doc")]
    [Route("doc")]
    public class DailyOperatingCtrlController : Controller
    { 
    ... 
    }
}

Then each action method is decorated like so:

    [Authorize]
    [Route("[action]/{page:int?}")]
    public async Task<IActionResult> DOC()
    { 
    ... 
    }

I used this post as an example: How to use an Area in ASP.NET Core

My Startup.cs routes look like this:

app.UseMvc(routes =>
{
    routes.MapRoute("areaRoute", "{area:exists}/{controller=Admin}/{action=Index}/{id?}");

    routes.MapRoute(
    name: "default",
    template: "{controller=Home}/{action=Index}/{id?}");
});

In the same controller I have several methods that all have [HttpPost] decorator and work as expected.

Here is the specific issue I am having:

I have this method, loads a page with a form:

    [Authorize]
    [Route("[action]/{page:int?}")]

    public async Task<IActionResult> DocService()
    {
        var model = new ForecastViewModel
        {
            { ... }
        };

        return View(model);
    }

Then this method is for POST:

[Authorize]
[HttpPost]
[ValidateAntiForgeryToken]
[Route("[action]/{page:int?}")]
public async Task<IActionResult> DocService(int ForecastRtnId, string checkgroup, [Bind("{...}")] ForecastRtn forecastRtn)
    {
    /* Save data to a table and redirect back to the GET method */
        { ... }
    }

Now so far so good, this works fine. The problem I have is with a child window I open from within the above page. So within the DocService.cshtml file I have a short js script that opens up a popup:

        function PopupService() {

        url = "@Url.Action("DocServiceComment", "DailyOperatingCtrl", new { Area = "Doc", Id = "ID" })".replace("ID",parseInt(@lab_id));
        title = "Some Title";
        w = 600;
        h = 400;

        { ... }

    }

I am using Url.Action, I am also passing Area name and Id parameter. The popup is a single input box form that saves an user comment to separate audit table. Nothing fancy.

[Authorize]
[Route("[action]/{page:int?}")]
public async Task<IActionResult> DocServiceComment(int? Id)
    {
        if (Id == null)
        {
            return NotFound();
        }

        var forecast = await _context.Forecast.SingleOrDefaultAsync(m => m.ForecastId == Id);

        if (forecast == null)
        {
            return NotFound();
        }

        return View(forecast);
    }

So far so good, the popup loads correctly and has the correct comment in the input box (if there was one left already)

What I have noticed - and I believe this is where the issue is - that the URL of the popup looks like this:

http://localhost:5000/doc/DocServiceComment?Id=2

Instead of this:

http://localhost:5000/doc/DocServiceComment/2

But I might be wrong here and confusing matters. When I try to submit this popup I get 404 error.

My post method for DocServiceComment:

[Authorize]
[HttpPost]
[ValidateAntiForgeryToken]
[Route("[action]/{page:int?}")]
public async Task<IActionResult> DocServiceComment(int id, [Bind("{ ...}")] Forecast forecast)
    {
        /* Save stuff and redirect back to get */
    }

Which obviously does not get called at all.

Inside my DocServiceComment.cshtml I've tried this:

<form asp-area="Doc" asp-controller="DailyOperatingCtrl" asp-action="DocServiceComment"> 
/* Form stuff goes here */
</form>

I've tried to find any info on this but to no avail, which makes me think I am making a rookie error somewhere?

Also another hint, if we take this URL

http://localhost:5000/doc/DocServiceComment?Id=2

and remove the ?Id=2 it also gives 404 error.

This is the only page that behaves like that, and I need help figuring out what is going on.

PawelKosi
  • 151
  • 1
  • 3
  • 13

0 Answers0