【问题标题】:Start a C# web API inside an application在应用程序中启动 C# Web API
【发布时间】:2022-01-28 21:24:05
【问题描述】:

编辑:

我发现了这个问题:Simple routing with web server in netcore console app 所以我试着用它做点什么。

我使用以下代码创建了一个控制台应用程序(与答案中的基本相同,但有细微的变化):

public class Program
{
    public static void Main(string[] args)
    {
        StartServer(args);
    }

    public static void StartServer(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}

public class Startup
{
    // This method gets called by the runtime. Use this method to add services to the container.
    // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
    }

    // 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.UseRouting();
        app.UseEndpoints(configure => configure.MapControllers());
    }
}

public class MyEndpoint : ControllerBase
{
    [Route("")]
    public string Get()
    {
        return "it works";
    }
}

这很好用。如果我从另一个项目(另一个控制台应用程序)调用 StartServer 方法,它仍然有效。

但后来我用新的 .NET 6 样式替换了代码:

public class Program
{
    public static void Main(string[] args)
    {
        StartServer(args);
    }

    public static void StartServer(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);

        builder.Services.AddControllers();
        builder.Services.AddEndpointsApiExplorer();

        var app = builder.Build();

        app.UseRouting();
        app.MapControllers();
        app.Run();

    }
}

public class MyEndpoint : ControllerBase
{
    [Route("")]
    public string Get()
    {
        return "it works";
    }
}

如果我从它自己的项目启动服务器,这可以工作,但如果它是从其他控制台应用程序启动的,则不再有效(404 错误)。

我错过了什么?

========== 原帖==========

我目前正在学习 C# 中的 Web 开发,特别是尝试制作一个可以从 .NET 6 中的另一个程序集访问和启动的 C# REST API。

如果您需要更多上下文:这一切背后的想法是向现有的大型程序添加 Web API。 API 将有一个类保存从应用程序接收的数据,并作为请求响应发送到 API 客户端。

这是我尝试过的:

首先,我使用 Visual Studio 2022 模板创建了一个 Web API 项目,将其输出类型设置为“类库”而不是“控制台应用程序”,然后将其所有 Program.cs 内容放入一个单独的类(“Starter .cs”)和静态方法(“开始”)。然后,我创建了一个单独的控制台应用程序,引用了 API 项目,并调用了 Starter.Start 方法。

服务器实际启动:它在控制台输出中可见,我可以使用浏览器访问它。

问题是我只有一个空白页面,当我尝试访问作为控制台应用程序启动的 API 时可以正常工作的 URL 时,根本不会调用控制器。

我有什么遗漏吗?当应用程序以这种方式启动时未读取的配置文件(appsettings.json?)? 或者这是一种愚蠢的方式来实现我想要实现的目标?如果是这样,请不要犹豫,告诉我一个更好的解决方案,正如我所说,我只是在学习网络,所以我还没有真正理解/了解所有的良好实践和架构的注意事项。

这是我修改的代码,几乎没有。

Program.cs 中的代码(现已删除):

namespace WebApplication1
{
    public class Starter
    {
        public static void Start(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);

            builder.Services.AddControllers();

            builder.Services.AddEndpointsApiExplorer();
            builder.Services.AddSwaggerGen();

            var app = builder.Build();

            if (app.Environment.IsDevelopment())
            {
                app.UseSwagger();
                app.UseSwaggerUI();
            }

            app.UseHttpsRedirection();

            app.UseAuthorization();

            app.MapControllers();

            app.Run();
        }
    }
}

以及我如何在控制台应用程序中调用它:

WebApplication1.Starter.Start(args);

之后有一个Console.ReadLine(); 以防止应用关闭。

其余部分与 .NET 6 中的 Visual Studio 2022 Web API 项目模板中的代码基本相同。

【问题讨论】:

  • 不清楚问题是什么。为什么不直接使用webapiweb 模板创建一个新项目,而不是从可能相关或不相关的问题中复制代码?问题中的代码没有帮助 - 它与具有不同方法名称的模板代码相同
  • 唯一的问题似乎是 make a C# REST API that can be accessed and started from another program 本身并不清楚(in .NET 6 部分并不重要)。你是什​​么意思从另一个程序开始?从另一个程序启动一个程序的唯一方法是调用指向该可执行文件的Process.Start(),并传递必要的参数。还是您想将控制台应用程序用作类库?
  • 如果您想从另一个应用程序调用设置代码,请重构您的代码并将您想要调用的内容提取到公共类和方法中。完成此操作后,您将能够添加对另一个项目的引用并使用这些类
  • @Panagiotis Kanavos 是的,抱歉,我的意思是“从另一个程序集开始”,而不是“程序”。我会在问题中更改它。
  • @Panagiotis Kanavos 我认为“NET 6”部分实际上是相关的,因为似乎启动 Web API 的方式与在 NET 5 中完成的方式不同。如果您查看“编辑”部分,您将看到 2 个代码块。第一个是启动服务器的“NET 5 方式”。当我这样做时,如果我从另一个程序集启动它(调用 StartServer),我可以访问我的端点(例如从浏览器)。但是,如果我使用第二个块的代码,情况并非如此,否则如果我从它自己的程序集(通过 Main)执行它,它就可以正常工作

标签: c# .net-core asp.net-web-api console-application .net-6.0


【解决方案1】:

ms 推荐此语法用于 net 6 minimum apis https://docs.microsoft.com/en-us/aspnet/core/fundamentals/minimal-apis?view=aspnetcore-6.0

app.MapGet("/MyEndpoint", () =>
{
   return "it works";
});

例如,我在我的 apis 中使用它,当我从 Visual Studio 测试它们时,因为我不喜欢空屏幕。

一开始我改变了launchSettings.json

....
"launchUrl": "welcome",
"applicationUrl": "http://localhost:5000",
....

这是我的欢迎代码


app.MapGet("/welcome", () =>
{
  var con = "<html><body><h1>Hello!</h1><p> <h3>  API Is Ready To Work!!! </h3> </p></body></html>";
  
  return Results.Content(con, "text/html");
});

app.Run();

【讨论】:

  • 谢谢,成功了。
  • "ms 推荐这种语法" - 1) 不,它没有,2) 它不仅仅是语法。
  • @Arruba 不客气
  • @Serge 和?我已阅读此文档,但仍然看不到“推荐”的位置。再说一次 - 它不仅仅是一种语法,它是与传统控制器共存的全新管道,具有一些优点(主要是性能和简单性)和缺点(它在开箱即用的功能方面远没有那么强大,并且由于它不应该赶上的最小 api 的目标)。
猜你喜欢
  • 2019-05-14
  • 2015-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-26
相关资源
最近更新 更多