【问题标题】:MVC Controller unable to find Api Controller (same project)MVC 控制器无法找到 Api 控制器(同一项目)
【发布时间】:2019-03-21 16:58:21
【问题描述】:

(对不起,如果我的英语有点糟糕)

我正在尝试从 mvc 控制器调用 api 方法,但 mvc 似乎无法找到该方法。我将 mvc 控制器中的路由设置为

[Route("[controller]")]

在 api 控制器中作为

[Route("api/[controller]")]

在 startup.cs 文件中我添加了这个命令来启用默认路由

app.UseMvcWithDefaultRoute();

Mvc 控制器代码:

[HttpGet]
    public async Task<ActionResult> GetAll()
    {
        IEnumerable<Utente> utenti = null;

        using (var client = new HttpClient())
        {
            client.BaseAddress = new Uri("http://localhost:57279/");
            var Res = await client.GetAsync("api/utente/GetAll");

            if (Res.IsSuccessStatusCode)
            {
                var readTask = Res.Content.ReadAsAsync<IList<Utente>>();
                utenti = readTask.Result;
            }
            else
            {
                utenti = Enumerable.Empty<Utente>();

                ModelState.AddModelError(string.Empty, "Server error. Please contact administrator.");
            }
        }
        return View(utenti);
    }

API 代码:

[HttpGet]
    public IHttpActionResult GetAll()
    {
        IList<Utente> utenti = null;

        using (_utenteContext)
        {
            utenti = _utenteContext.Utenti.Select(u => new Utente()
                        {
                            id = u.id,
                            user = u.user,
                            password = u.password
                        }).ToList<Utente>();
        }

        if (utenti.Count == 0)
        {
            return NotFound();
        }

        return Ok(utenti);
    }

问题可能是我在同一个项目中关注 mvc 和 api 控制器的旧示例,但我希望你们能帮助我。

在:

var Res = await client.GetAsync("api/utente/GetAll");

无论我对代码进行什么更改,我总是得到 {StatusCode: 404, ReasonPhrase: 'Not Found',...}。

编辑:

整个 Api 控制器(我也在尝试使用 POST 方法,但它也不起作用)

using AdrianWebApi.Models;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;

namespace AdrianWebApi.Controllers.api
{
[Route("api/[controller]")]
public class UtenteController : ApiController
{
    private readonly UtenteContext _utenteContext;

    public UtenteController(UtenteContext context)
    {
        _utenteContext = context;
    }

    [HttpGet]
    public IHttpActionResult GetAll()
    {
        IList<Utente> utenti = null;

        using (_utenteContext)
        {
            utenti = _utenteContext.Utenti.Select(u => new Utente()
                        {
                            id = u.id,
                            user = u.user,
                            password = u.password
                        }).ToList<Utente>();
        }

        if (utenti.Count == 0)
        {
            return NotFound();
        }

        return Ok(utenti);
    }

    [HttpPost]
    public IHttpActionResult PostNewUtente(Utente utente)
    {
        if (!ModelState.IsValid)
            return BadRequest("Not a valid model");

        using (_utenteContext)
        {
            _utenteContext.Utenti.Add(new Utente()
            {
                id = utente.id,
                user = utente.user,
                password = utente.password
            });

            _utenteContext.SaveChanges();
        }

        return Ok();
    }
}
}

编辑 2 有用的启动类:

using AdrianWebApi.Models;
using AdrianWebApi.Models.DataManager;
using AdrianWebApi.Models.Repository;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace AdrianWebApi
{
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.AddDbContext<UtenteContext>(options =>{options.UseMySQL("server=localhost;database=dbutenti;User ID=root;password=root;");});
        services.AddScoped<IDataRepository<Utente>, DataManager>();
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        app.UseMvcWithDefaultRoute();
    }
}
}

EDIT 3 如果有人感兴趣,可以发布 MVC 方法,至少对我来说:

[Route("Add")]
    [System.Web.Http.HttpPost]
    public ActionResult Add([FromForm]Utente utente)
    {
        if (utente.password == null)
        {
            return View();
        }
        else
        {

            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri("http://localhost:57279/api/");

                //HTTP POST
                var postTask = client.PostAsJsonAsync<Utente>("utente", utente);
                postTask.Wait();

                var result = postTask.Result;
                if (result.IsSuccessStatusCode)
                {
                    return RedirectToAction("GetAll");
                }
            }
            ModelState.AddModelError(string.Empty, "Server Error. Please contact administrator.");
            return View(utente);
        }
    }

【问题讨论】:

  • 你能在 API 中显示更多的控制器吗?另外,这是 MVC5 而不是 ASP.NET MVC Core?
  • 这是MVC5,我正在编辑发布整个api控制器。
  • 你会不会错过app.UseWebApi()
  • 当我尝试在 startup.cs 中添加它时,它告诉我 IApplicationBuilder' 不包含“UseWebApi”的定义,并且没有可访问的扩展方法“UseWebApi”接受“IApplicationBuilder”类型的第一个参数可以找到。我必须安装 Owin Nuget 吗?
  • 这个 api 是否可以在浏览器中工作?跨控制器调用可能需要一些配置

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


【解决方案1】:

尝试注释掉你的控制器并用下面的代码替换它,然后转到api/utente/ 看看你是否得到了结果。如果你这样做了,那么用你的代码替换你需要的。

using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;

namespace AdrianWebApi.Controllers.api
{
    [Route("api/[controller]")]
    [ApiController]
    public class ValuesController : ControllerBase
    {
        // GET api/values
        [HttpGet]
        public ActionResult<IEnumerable<string>> Get()
        {
            return new string[] { "Test 1", " Test 2" };
        }
    }
}

【讨论】:

  • 谢谢你,现在 mvc 控制器正在从 api 获取数据 :)
  • 如果有人需要它,我还设法修复了 post 方法,添加了一个 if 在调用 mvc 方法之前检查密码是否为空,如下所示: if (utente.password == null) { return View (); } else { // 添加的所有代码
猜你喜欢
  • 2015-08-24
  • 2015-01-12
  • 2015-12-28
  • 1970-01-01
  • 2019-01-06
  • 1970-01-01
  • 2017-01-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多