私はMVC WebアプリのAPIをセットアップしようとしていますが、これには多くのルートがありますが、それぞれに同じ部分があります。基本的に各エリアのCRUD。また、バージョン対応に設定しています。私は2つのコントローラーをそれぞれセットアップし、簡単なアクションで開始してすぐに競合を受け取ります。私が得るエラーは
私はこれらのURLの後にいます
MVCを使用すると、
だから私はcontacts_delete
およびlocations_delete
のようなURLを生成する
等々
(これは、コメントおよびRoute names must be unique. You cannot have two different routes named delete. Use deleteLocation and deleteContact instead.
)
https://foo.bar/aim/v1/contacts_delete/11111
しかし、それは私にはあまり意味がありません。 MVCがそれを実行できる場合、これを実現する方法があると私は信じる必要があります。
私が得るエラーは:
同じ名前「delete」の属性ルートには同じテンプレートが必要です。
アクション: 'rest.fais.foo.edu.Controllers.aimContactsController.delete(rest.fais.foo.edu)'-テンプレート: 'aim/v1/contacts/delete/{id}'
アクション: 'rest.fais.foo.edu.Controllers.aimLocationsController.delete(rest.fais.foo.edu)'-テンプレート: 'aim/v1/locations/delete/{id}'
私が設定したコントローラ用
[EnableCors("SubDomains")]
[ResponseCache(NoStore = true, Duration = 0)]
[Produces("application/json")]
[Route("aim/v1/contacts/[action]")]
[ProducesResponseType(typeof(errorJson), 500)]
public class aimContactsController : Controller
{
private readonly IHostingEnvironment _appEnvironment;
private readonly AimDbContext _aim_context;
private readonly UserManager<ApplicationUser> _userManager;
public aimContactsController(IHostingEnvironment appEnvironment,
AimDbContext aim_context,
UserManager<ApplicationUser> userManager)
{
_appEnvironment = appEnvironment;
_userManager = userManager;
_aim_context = aim_context;
}
[HttpPost("{id}", Name = "delete")]
public IActionResult delete(string id)
{
return Json(new
{
results = "deleted"
});
}
}
[EnableCors("SubDomains")]
[ResponseCache(NoStore = true, Duration = 0)]
[Produces("application/json")]
[Route("aim/v1/locations/[action]")]
[ProducesResponseType(typeof(errorJson), 500)]
public class aimLocationsController : Controller
{
private readonly IHostingEnvironment _appEnvironment;
private readonly AimDbContext _aim_context;
private readonly UserManager<ApplicationUser> _userManager;
public aimLocationsController(IHostingEnvironment appEnvironment,
AimDbContext aim_context,
UserManager<ApplicationUser> userManager)
{
_appEnvironment = appEnvironment;
_userManager = userManager;
_aim_context = aim_context;
}
[HttpPost("{id}", Name = "delete")]
public IActionResult delete(string id)
{
return Json(new
{
results = "deleted"
});
}
}
Startup.csの場合、
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
//RolesData.SeedRoles(app.ApplicationServices).Wait();
app.UseApplicationInsightsRequestTelemetry();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
app.UseBrowserLink();
}
else
{
//app.UseExceptionHandler("/Home/Error");
}
app.UseIdentity();
app.UseDefaultFiles();
app.UseStaticFiles();
//app.UseResponseCompression();
// Add external authentication middleware below. To configure them please see http://go.Microsoft.com/fwlink/?LinkID=532715
app.UseSession();
// custom Authentication Middleware
app.UseWhen(x => (x.Request.Path.StartsWithSegments("/aim_write", StringComparison.OrdinalIgnoreCase) || x.Request.Path.StartsWithSegments("/rms", StringComparison.OrdinalIgnoreCase)),
builder =>
{
builder.UseMiddleware<AuthenticationMiddleware>();
});
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger();
// Enable middleware to serve swagger-ui (HTML, JS, CSS etc.), specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c =>
{
c.RoutePrefix = "docs";
//c.SwaggerEndpoint("/docs/v1/wsu_restful.json", "v1.0.0");swagger
c.SwaggerEndpoint("/swagger/v1/swagger.json", "v1.0.0");
});
app.UseMvc(routes =>
{
routes.MapRoute(
name: "javascript",
template: "javascript/{action}.js",
defaults: new { controller = "mainline" });
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
routes.MapRoute(
name: "AIMApi",
template: "aim/v1/{action}/{id?}",
defaults: new { controller = "aim" });
routes.MapRoute(
name: "AIMContactsApi",
template: "aim/v1/contacts/{action}/{id?}",
defaults: new { controller = "aimContactsController" }
);
routes.MapRoute(
name: "AIMLocationsApi",
template: "aim/v1/locations/{action}/{id?}",
defaults: new { controller = "aimLocationsController" }
);
routes.MapRoute(
name: "RMSApi",
template: "{controller=rms}/v1/{action}/{id?}");
});
}
}
私がこれを回避する方法の答えをググるように思えないこと。差し迫った問題を修正したいのですが、どんな提案も歓迎します。
両方のルートに同じ名前が付けられています。これはASP.NET Core MVCでは機能しません。
メソッドの命名についてではなく、ルートの命名について話しています。 HttpPost
属性内で同じ識別子Name = "delete"
を使用して両方のルートを呼び出しました。 MVCのルート名は、ルートテンプレートを一意に識別します。
私が見ることができるものから、あなたは本当にあなたのルートを特定する必要はありませんが、異なるURIを区別するためだけに必要です。このため、アクションメソッドのName
属性のHttpPost
プロパティを自由に削除できます。 ASP.NET Coreルーターがアクションメソッドと一致するには、これで十分です。
代わりに、属性ルーティングのみを使用して元に戻す場合は、コントローラーを次のように変更することをお勧めします。
// other code omitted for clarity
[Route("aim/v1/contacts/")]
public class aimContactsController : Controller
{
[HttpPost("delete/{id}")]
public IActionResult delete(string id)
{
// omitted ...
}
}
別の可能な解決策は次のとおりです。
// other solution
[Route("aim/v1/contacts/[Action]")]
public class aimContactsController : Controller
{
[HttpPost("{id}")]
public IActionResult delete(string id)
{
// omitted ...
}
}
アクション名を動的に使用した例:
[Route("api/{lang}/[controller]/[Action]")]
[ApiController]
public class SpatiaController : ControllerBase
{
private readonly ISpatialService _service;
private readonly ILogger<SpatialController> _logger;
public SpatialUnitsIGMEController(ILogger<SpatialController> logger, ISpatialService service)
{
_service = service;
_logger = logger;
}
[HttpGet]
public async Task<ActionResult<IQueryable<ItemDto>>> Get50k(string lang)
{
var result = await _service.GetAll50k(lang);
return Ok(result);
}
[HttpGet("{name}")]
public async Task<ActionResult<ItemDto>> Get50k(string lang, string name)
{
var result = await _service.Get50k(lang, name);
return Ok(result);
}
}
これらのエンドポイントを呼び出すには、次の呼び出しが使用されます。
https://example.domain.com/api/en/spatial/get50k ->すべてのデータを英語で取得します
https://example.domain.com/api/en/spatial/get50k/madrid -> madridのデータを英語で取得します
https://example.domain.com/api/es/spatial/get50k/madrid ->スペイン語でマドリードのデータを取得
(ルートのアクションと言語を使用)