分离ASP.NET Core MVC和API控制器的正确方法是什么

时间:2016-09-17 07:38:17

标签: asp.net-web-api asp.net-core asp.net-core-mvc

我有一个包含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?}");
            });

0 个答案:

没有答案