【问题标题】:ASP.NET Core MVC requests return 404ASP.NET Core MVC 请求返回 404
【发布时间】:2020-09-15 22:57:02
【问题描述】:

我创建了一个快速项目来证明一个观点,现在我想我很烂。出于某种原因,我在这个非常简单的站点设置中的端点上提取了 404 错误。我觉得我错过了一些小事,但我似乎无法找到它。

任何帮助都会很棒,我真的无法理解路线是如何创建的和/或我尝试使用的路线是如何无效的?

我只使用过 .NET 框架,而 .NET Core 处理的事情似乎略有不同。

最初,我只是将它作为一个针对 asp-controller / asp-action 的表单,方法为 POST。然而这没有用,我收到了一个 404 页面。

然后我尝试使用 jQuery Ajax 请求,结果相同。

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();
        });
    }
}

家庭控制器:

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>
}

【问题讨论】:

标签: c# routes asp.net-core-mvc


【解决方案1】:

.Net Core3.0之后,ASP.NET Core默认会从动作名称中去除后缀Async,你可以参考link。所以你可以将你的ajax url改为@Url.Action("Download", "Home"),然后你发布对象采取行动,所以你需要删除[FromBody]。这是一个演示:

控制器:

[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>
}

结果:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-16
    • 2021-09-12
    • 2012-08-10
    • 2021-02-01
    • 2014-11-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多