我有一个包含MVC和API控制器的ASP.NET核心项目。每种控制器类型都有自己的文件夹。
对于网络和API(取决于使用情况)我都有AlertsController
这应该不是问题,但我发现了一个奇怪的问题。在部分页面中,asp-controller标签混合了控制器,在同一页面上给出了不同的结果。
页面很小,所以我会发布整个内容:
@model IEnumerable<AlertDTO>
<h4>Alerts</h4>
<div class="container-fluid">
<div class="row row-padding">
<span class="col-lg-1 col-md-1 col-sm-1 col-xs-2"></span>
<span class="col-lg-1 col-md-1 col-sm-1 col-xs-2"></span>
<span class="col-lg-1 col-md-1 col-sm-2 hidden-xs"><strong>ID</strong></span>
<span class="col-lg-1 col-md-1 col-sm-2 hidden-xs"><strong>AccID</strong></span>
<span class="col-lg-1 col-md-1 col-sm-2 col-xs-3"><strong>Rate</strong></span>
<span class="col-lg-1 col-md-1 col-sm-2 col-xs-2"><strong>Above</strong></span>
<span class="col-lg-1 col-md-1 col-sm-2 col-xs-2"><strong>Active</strong></span>
<span class="col-lg-5 col-md-5 hidden-sm hidden-xs"><strong>Owner</strong></span>
</div>
@foreach (var item in Model)
{
<div class="row row-padding">
<span class="col-lg-1 col-md-1 col-sm-1 col-xs-2">
<a asp-controller="Alerts"
asp-action="Edit"
asp-route-id="@item.AlertID"
class="btn btn-warning btn-sm">
<i class="fa fa-pencil-square-o"></i>
</a>
</span>
<span class="col-lg-1 col-md-1 col-sm-1 col-xs-2">
<a asp-controller="Alerts"
asp-action="Delete"
asp-route-id="@item.AlertID"
asp-route-accountID="@item.AccountID"
class="btn btn-danger btn-sm">
<i class="fa fa-trash-o"></i>
</a>
</span>
<span class="col-lg-1 col-md-1 col-sm-2 hidden-xs">@item.AlertID</span>
<span class="col-lg-1 col-md-1 col-sm-2 hidden-xs">@item.AccountID</span>
<span class="col-lg-1 col-md-1 col-sm-2 col-xs-3">@item.Rate</span>
<span class="col-lg-1 col-md-1 col-sm-2 col-xs-2">@item.TriggerAbove</span>
<span class="col-lg-1 col-md-1 col-sm-2 col-xs-2">@item.IsActive</span>
<span class="col-lg-5 col-md-5 hidden-sm hidden-xs">@item.UserTag</span>
</div>
}
<div class="row row-padding">
<span class="col-lg-12">
<a asp-controller="Alerts"
asp-action="Create"
asp-route-accountID="@ViewData["AccountID"]"
class="btn btn-success btn-sm">
<i class="fa fa-plus"></i>
</a>
</span>
</div>
</div>
asp-controller="Alerts"
循环中的foreach
(编辑和删除)最终指向api/Alerts
,而循环外的那个(创建)将指向正确的 /警报
这怎么可能?
丹尼斯
MVC控制器:
using HGW.Interfaces;
using HGWDomain.DTOs;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System;
namespace HGW.Controllers.Web
{
[Authorize]
[Route("[controller]")]
public class AlertsController : Controller
{
private IAlertsRepository repo;
public AlertsController(IAlertsRepository AlertsRepository)
{
repo = AlertsRepository;
}
[HttpGet("")]
public IActionResult Index()
{
try
{
var results = repo.GetAlerts();
return View(results);
}
catch (Exception ex)
{
return View("Error", ex.Message);
}
}
[HttpGet("[action]/{id:int}")]
public IActionResult Account(int accountID)
{
try
{
var dtos = repo.GetAlertsByAccount(accountID);
return View(dtos);
}
catch (Exception ex)
{
return View("Error", ex.Message);
}
}
[HttpGet("[action]/{accountID:int}")]
public IActionResult Create(int accountID)
{
if (accountID > 0)
{
var dto = new AlertDTO();
dto.AccountID = accountID;
dto.LastUpdated = DateTime.UtcNow;
if (User.Identity.IsAuthenticated)
{
string user = User.Identity.Name;
int index = user.IndexOf("#");
string email = user.Substring(index + 1);
dto.UserTag = email;
}
return View(dto);
}
string message = "AccountID is missing. Cannot create Alert";
return View("Error", message);
}
[HttpPost("[action]/{accountID:int}")]
public IActionResult Create(int accountID, AlertDTO dto)
{
if (ModelState.IsValid)
{
try
{
var result = repo.CreateAlert(dto);
if (result != null)
{
return RedirectToAction("Details", "Accounts", new { id = result.AccountID });
}
else
{
ViewBag.Message = "Alert failed to register";
return View(result);
}
}
catch (Exception ex)
{
ViewBag.Message = "Oops";
return View("Error", new { Message = ex });
}
}
else
{
return View(dto);
}
}
[HttpGet("[action]/{id:int}")]
public IActionResult Edit(int id)
{
try
{
var dto = repo.GetAlert(id);
if (dto == null)
{
return RedirectToAction("Index");
}
return View(dto);
}
catch (Exception ex)
{
return View("Error", ex.Message);
}
}
[HttpPost("[action]/{id:int}")]
public IActionResult Edit(int id, AlertDTO dto)
{
if (ModelState.IsValid)
{
dto.LastUpdated = DateTime.UtcNow;
try
{
var result = repo.UpdateAlert(dto);
if (result != null)
{
return RedirectToAction("Details", "Accounts", new { id = result.AccountID });
}
else
{
ViewBag.Message = "Alert was not saved";
return View(result);
}
}
catch (Exception ex)
{
ViewBag.Message = "Oops";
return View("Error", new { Message = ex });
}
}
else
{
return View(dto);
}
}
[HttpGet("[action]/{id:int}")]
public IActionResult Delete(int id, int accountID)
{
try
{
int result = repo.DeleteAlert(id);
if (result > 0)
{
return RedirectToAction("Details", "Accounts", new { id = accountID });
}
return View();
}
catch (Exception ex)
{
return View("Error", ex.Message);
}
}
}
}
API控制器:
using HGW.Interfaces;
using HGWDomain.DTOs;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Net;
namespace HGW.Controllers.Api
{
//[Authorize]
[Route("api/[controller]")]
public class AlertsController : Controller
{
private IAlertsRepository repo;
public AlertsController(IAlertsRepository AlertsRepository)
{
repo = AlertsRepository;
}
[HttpGet("{id:int}")]
[Produces(typeof(IEnumerable<AlertDTO>))]
public IEnumerable<AlertDTO> Get(int id)
{
try
{
var result = repo.GetAlertsByAccount(id);
Response.StatusCode = (int)HttpStatusCode.OK;
return result;
}
catch (Exception ex)
{
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return null;
}
}
[HttpPost("[action]/{id:int}")]
public AlertDTO Edit(int id, [FromBody] AlertDTO dto)
{
AlertDTO result = null;
if (ModelState.IsValid)
{
try
{
result = repo.UpdateAlert(dto);
if (result != null)
{
Response.StatusCode = (int)HttpStatusCode.OK;
return result;
}
}
catch (Exception ex)
{
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return result;
}
}
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return result;
}
[HttpGet("[action]/{id:int}")]
public IActionResult Delete(int id)
{
if (id > 0)
{
try
{
var result = repo.DeleteAlert(id);
if (result > 0)
{
Response.StatusCode = (int)HttpStatusCode.OK;
}
else
{
Response.StatusCode = (int)HttpStatusCode.BadRequest;
}
return Json(result);
}
catch (Exception ex)
{
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return Json(new { Message = ex.Message });
}
}
return BadRequest();
}
}
}
Startup.cs的默认路由:
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});