ASP.Core表单忽略了asp-controller



我正在做一个ASP。. NET Core应用程序。它的一部分是一个图片库,允许用户上传图像。在本地主机上,这按预期工作,但当我部署(AWS Lambda与API网关)的上传按钮缺少asp-controller属性。

我有一个GalleryController.cs有两个方法:

public async Task<IActionResult> Index()
{
// Pulls images from aws S3, adds them to a list and passes them to then returns View();
}
[HttpPost("Upload")]
public async Task<IActionResult> Upload(List<IFormFile> files)
{
// For each iformFile in Files, create a thumbnail in memory then upload both the original and thumbnail to aws s3 bucket
return RedirectToAction("Index");
}

我的startup.cs中的路由配置已从样板中保留默认值:

app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});

Views的文件夹结构如下:

├── Views
│   ├── Gallery
│   │   ├── _GalleryPartial.cshtml
│   │   ├── Index.cshtml
│   │   └── _UploadPartial.cshtml
│   ├── Home
│   │   └── Index.cshtml

_UploadPartial。CSHTML看起来像这样:

<div class="container">
<div class="col-md-12">
<form method="post" enctype="multipart/form-data" asp-controller="Gallery" asp-action="Upload">
<div class="form-group">
<div class="col-md-12">
<div class="col-md-6">
<input class="form-control-file" type="file" name="files" multiple />
</div>
<div class="col-md-6">
<input class="form-control-file" type="submit" value="Upload" />
</div>
</div>
</div>
</form>
</div>
</div>
<hr>

正如你所看到的,我有asp-controller="Gallery"asp-action="Upload",但是当我检查表单部署到lambda后,它似乎忽略了控制器标签。

看起来我没有足够的点来嵌入图像,所以创建了一个链接

edit根据要求,以下是Gallery/index.cshtml

的内容
@model Dictionary<string, string>

@{
ViewData["Title"] = "News page";
}
<center>
@await Html.PartialAsync("_uploadPartial")

@await Html.PartialAsync("_galleryPartial")
</center>

startup.cs的内容:

using Amazon.S3;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Redacted.Helpers;
namespace Redacted;
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().AddRazorRuntimeCompilation();
services.AddAWSService<IAmazonS3>();
services.AddTransient<ImageHelper>();

services.AddRazorPages();
services.AddMvcCore();
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
// Signin:
options.ResponseType = Environment.GetEnvironmentVariable("ResponseType");
options.MetadataAddress = Environment.GetEnvironmentVariable("MetadataAddress");
options.ClientId = Environment.GetEnvironmentVariable("ClientId");
options.ClientSecret = Environment.GetEnvironmentVariable("ClientSecret");
// Signout
options.Events = new OpenIdConnectEvents()
{
OnRedirectToIdentityProviderForSignOut = OnRedirectToIdentityProviderForSignOut
};
});
services.AddAuthorization(options =>
{
options.AddPolicy("Admins", policy => policy.RequireAssertion(context => context.User.HasClaim(c => c.Type == "cognito:groups" && c.Value == "admins")));
options.AddPolicy("Users", policy => policy.RequireAssertion(context => context.User.HasClaim(c => c.Type == "cognito:groups" && c.Value == "users" || c.Value == "admins")));
});
}

// 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("/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.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});

}
private Task OnRedirectToIdentityProviderForSignOut(RedirectContext context)
{

context.ProtocolMessage.Scope = "openid";
context.ProtocolMessage.ResponseType = "code";
var cognitoDomain = Environment.GetEnvironmentVariable("CognitoDomain");
var clientId = Environment.GetEnvironmentVariable("ClientId");
var logoutUrl = Environment.GetEnvironmentVariable("LogoutUri");
context.ProtocolMessage.IssuerAddress = $"{cognitoDomain}/logout?client_id={clientId}&logout_uri={logoutUrl}&redirect_uri={logoutUrl}";
// delete cookies
context.Properties.Items.Remove(CookieAuthenticationDefaults.AuthenticationScheme);
// close openid session
context.Properties.Items.Remove(OpenIdConnectDefaults.AuthenticationScheme);
return Task.CompletedTask;
}
}

经过一段时间的调试后,我发现问题出在基础设施本身。当我使用API网关将流量路由到我的lambda时,我缺少POST的路由。只需在aws控制台中api gateway/routes下的/{proxy+}中添加一个POST路由方法,或者使用类似于以下的地形资源块:

resource "aws_apigatewayv2_route" "get_route" {
api_id    = aws_apigatewayv2_api.lambda.id
route_key = "GET /{proxy+}"
target    = "integrations/${aws_apigatewayv2_integration.proxy_integration.id}"
}

最新更新