0

I created a quick project to prove a point and now well I guess I suck. For some reason I'm pulling 404 errors on an endpoint in this very simple site setup. I feel like I'm missing something minor but I can't seem to put my finger on it.

Any assistance would be great, I really just can't seem to wrap my head around how the routes are being created and / or how the route that I'm attempting to use is invalid?

I've only ever used the .NET framework, and .NET Core seems to be handling things slightly different.

Originally, I had just made it a form targeting the asp-controller / asp-action with method=POST. However that didn't work and I received a 404 page.

Then I tried using jQuery Ajax request, same result.

Startup.cs

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }

        app.UseStatusCodePagesWithReExecute("/Home/Error/{0}");

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapDefaultControllerRoute();
        });
    }
}

Home controller:

public class HomeController : Controller
{
    private readonly ILogger<HomeController> _logger;

    public HomeController(ILogger<HomeController> logger)
    {
        _logger = logger;
    }

    public IActionResult Index()
    {
        return View();
    }

    public IActionResult Privacy()
    {
        return View();
    }

    [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
    public IActionResult Error()
    {
        var model = new ErrorViewModel {RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier};

        if (Response.StatusCode.Equals(HttpStatusCode.NotFound))
            return View("~/Views/Shared/404.cshtml", model);

        return View(model);
    }

    [HttpPost]
    public async Task<IActionResult> DownloadAsync([FromBody] DownloadModel model)
    {
        try
        {
            var youtube = new YoutubeClient();
            var manifest = await youtube.Videos.Streams.GetManifestAsync(model.VideoId);

            var info = manifest.GetMuxed().WithHighestVideoQuality();

            if (info != null)
            {
                var file = $"{model.VideoId}.{info.Container}";
                await youtube.Videos.Streams.DownloadAsync(info, file);
                var bytes = await System.IO.File.ReadAllBytesAsync(file);
                return File(bytes, "application/force-download", file);
            }
        }
        catch (Exception e)
        {
            // TODO: Document Exception
            this._logger.LogError(e, $"Download exception occurred.");
        }

        return BadRequest();
    }
}

Index.cshtml

@model DownloadModel
@{
    ViewData["Title"] = "Home Page";
}

<div class="text-center">
    <h1 class="display-4">Yipper (Youtube Ripper)</h1>
    <input type="text" asp-for="Url" class="url-input" id="url-textbox"/>
    <button id="url-submit-btn" class="url-btn" type="submit">RIP</button>
</div>

@section Scripts
{
    <script>
        function download(e) {
            e.preventDefault();
            const request = {
                "Url": $("#url-textbox").val() 
            }
            console.log(request);
            $.ajax('@Url.Action("DownloadAsync", "Home")',
                {
                    method: "POST",
                    data: request
                }).done(function(result) {
                    console.log(result);
                }).fail(function(error) {
                    console.log(error);
                });
        }

        $(function() {
            $("#url-submit-btn").click(download);
        });
    </script>
}
2

1 Answer 1

3

ASP.NET Core will trim the suffix Async from action names by default after .Net Core3.0,you can refer to the link.So you can change your ajax url to @Url.Action("Download", "Home"),and then you post object to action,so you need to remove [FromBody].Here is a demo worked:

Controller:

[HttpPost]
        public async Task<IActionResult> DownloadAsync(DownloadModel model)
        {
            return Ok();
        }

Index.cshtml:

<div class="text-center">
    <h1 class="display-4">Yipper (Youtube Ripper)</h1>
    <input type="text" asp-for="Url" class="url-input" id="url-textbox" />
    <button id="url-submit-btn" class="url-btn" type="submit">RIP</button>
</div>

@section Scripts
{
    <script>
        function download(e) {
            e.preventDefault();
            const request = {
                "Url": $("#url-textbox").val()
            }
            console.log(request);
            $.ajax('@Url.Action("Download", "Home")',
                {
                    method: "POST",
                    data: request
                }).done(function(result) {
                    console.log(result);
                }).fail(function(error) {
                    console.log(error);
                });
        }

        $(function() {
            $("#url-submit-btn").click(download);
        });
    </script>
}

result: enter image description here

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

1 Comment

man i got this answer after wasting two days and my sleep..I can't thank you enough. GBU now i can sleep

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.