首页 > 编程语言 >Use MVC, Razor Pages, Blazor, API Controllers, And Minimal APIs In A Single ASP.NET Core Application

Use MVC, Razor Pages, Blazor, API Controllers, And Minimal APIs In A Single ASP.NET Core Application

时间:2023-03-09 10:12:50浏览次数:64  
标签:Razor Use ASP Index app Pages add page

博客原文地址:http://www.binaryintellect.net/articles/55355722-96b6-4bbc-a110-999e5e61235e.aspx

A few years ago I wrote an article explaining how ASP.NET Core 2.0 MVC, Razor Pages, and Web API can coexist in a single web application. ASP.NET Core has added some new members to the family since then. And it's time to rebuild a similar web application that uses ASP.NET Core 6.0 MVC, Razor Pages, Blazor Server, API controllers, and minimal APIs together in a single project. Usually developers create a new ASP.NET Core project based on a particular project template such as MVC or Blazor. But you are not restricted to a single development option. ASP.NET Core offers multiple development options and you can utilize them in a single project depending on your requirement.

In this walkthrough I will start with an empty project and one-by-one add MVC, Razor Pages, Blazor Server, API controller, and minimal API to it. This will help you understand what configuration is necessary and how various files are organized in such situations.

Let's get started by creating a new ASP.NET Core named AspNetCoreAllInOne based on Empty project template.

The newly created project in the Solution Explorer is shown below.

 

Add ASP.NET Core MVC

First we will add MVC to the project. So, open Program.cs file and add this code:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews();

var app = builder.Build();

app.UseStaticFiles();
app.UseRouting();
app.MapDefaultControllerRoute();

app.Run();

Notice the code marked in bold letters. We call AddControllersWithViews() to register MVC services with the DI container. The UseStaticFiles() call adds the support foe static files (images, JS files etc.) to the app. The UseRouting() and MapDefaultControllerRoute() methods handle the MVC routing used by the app. In this example we are going to use the default /controller/action/id pattern for the routes and hence we didn't specify any other route pattern.

Now add four folders namely Models, Views, Controllers, and wwwroot to the project.

Then add a new class called AppModel to the Models folder using the Add New Item dialog.

 

Write the following code in the AppModel.cs file:

namespace AspNetCoreAllInOne.Models
{
    public class AppModel
    {
        public string Message { get; set; }
    }
}

The AppModel class has just one property called Message.

Next, add a new controller class named HomeController to the Controllers folder.

 

Write the following code in the HomeController class.

using Microsoft.AspNetCore.Mvc;
using AspNetCoreAllInOne.Models;


namespace AspNetCoreAllInOne.Controllers
{
    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            AppModel data = new AppModel()
            { 
                Message = "Hello World!" 
            };
            return View(data);
        }
    }
}

The HomeController class contains Index() action. The Index() action creates an AppModel object, sets its Message property to Hello World! and passes that model object to the Index view.

Create Views > Home folder and add a new Razor view file named Index.cshtml in it. 

 

Write the following code in the Index.cshtml file

@model AspNetCoreAllInOne.AppModel

<h1>@Model.Message</h1>

Here we simply output the Message property in the browser.

Add a new HTML page named Default.html in the wwwroot folder. We will use this page later in this example. Just keep it empty for the time being.

At this stage your project will look like this:

 

If you run the application you will get this output:

 

Add ASP.NET Core Razor Pages

Now that MVC has been added to the project, let's go ahead and add Razor Pages.

Open Program.cs file again and add this code:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();

var app = builder.Build();

app.UseStaticFiles();
app.UseRouting();
app.MapDefaultControllerRoute();
app.MapRazorPages();

app.Run();

Notice that we added two more calls - AddRazorPages() and MapRazorPages() - for supporting Razor Pages.

Then add Pages folder under the project root. And add a new Razor Page named Index.cshtml to it.

 

Open the Index.cshtml.cs page model class and add the following code:

public class IndexModel : PageModel
{
    public AppModel Data = new AppModel();

    public void OnGet()
    {
        Data.Message = "Hello Galaxy!";
    }
}

We create an object of AppModel and set its Message property to Hello Galaxy! in the OnGet() page handler.

Then open the Index.cshtml page and output the Message property as shown below:

@page
@model AspNetCoreAllInOne.Pages.IndexModel

<h1>@Model.Data.Message</h1>

If you run the application you will see this output: 

 

Note that after adding Razor Pages, the web application's default page got changed from /Home/Index (MVC default) to /Index (Razor Pages default). Of course, you can manually navigate to the desired URL and invoke MVC or Razor Pages as required.

Add Blazor Server

Adding Blazor Server is slightly more complicated than adding MVC and Razor Pages. Let's go ahead and do that.

Open the Program.cs file and add the following code:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();

var app = builder.Build();

app.UseStaticFiles();
app.UseRouting();

app.MapDefaultControllerRoute();
app.MapRazorPages();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");

app.Run();

Notice the code marked in bold letters. We first call AddServerSideBlazor() to register Blazor Server services. We then setup the Blazor  and fallback page using MapBlazorHub() and MapFallbackToPage() methods.

Next, add Blazor's root component - App.razor in the project's root folder.

 

Write the following code into App.razor.

@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web

<Router AppAssembly="@typeof(App).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" />
    </Found>
    <NotFound>
        <PageTitle>Not found</PageTitle>
        <LayoutView>
            <p>Sorry, there's 
nothing at this address.</p>
            <a href="/Default.html">Go to Default page</a>
        </LayoutView>
    </NotFound>
</Router>

Here we basically setup Blazor's router. Notice the anchor tag marked in bold letters. If the router can't find a URL it will show an error message and will allow the user to go to the Default.html page (we added Default.html page while configuring MVC earlier in this example).

The App.razor component is loaded from the _Host.cshtml file. So, add a new Razor View file named _Host.cshtml in the Pages folder.

Add the following code in the _Host.cshtml file.

@page

@using Microsoft.AspNetCore.Components.Web
@using AspNetCoreAllInOne
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, 
initial-scale=1.0" />
    <base href="~/" />
    <component type="typeof(HeadOutlet)" 
render-mode="ServerPrerendered" />
</head>
<body>
    <component type="typeof(App)" render-mode="ServerPrerendered" />
    <script src="_framework/blazor.server.js"></script>
</body>
</html>

Notice the code marked in bold letters. We render the App.razor component using the <component> syntax. We also add a <script> reference to blazor.server.js just before the </body> tag.

Next, we will add two simple Razor Components. First, create a new folder called Shared under the project root. And add a new razor component named WelcomeMessage.razor in it.

Write the following code inside WelcomeMessage component:

@code{

    [Parameter]
    public string Message { get; set; }

}

<h1>@Message</h1>

As you can see, there is a Message parameter property that will be used by a parent component to specify a message. The specified message is simply outputted on the page.

The WelcomeMessage.razor component is used by Index.razor component. So, add Index.razor component in the Pages folder. You already added the Pages folder while creating the Index Razor Page earlier in this example.

Write the following code in the Index.razor file.

@page "/"
@page "/IndexBlazor"
@using AspNetCoreAllInOne.Shared

<WelcomeMessage Message="Hello Universe!" /> 

We used the WelcomeMessage component and specify the Message to be Hello Universe!. Notice that we have also used @page directive to specify a route /IndexBlazor. This way the Index component can be accessed at /IndexBlazor. We already have Index.cshtml file in the Pages folder. Therefore, we can't assign /Index route to the newly added razor component.

These two components are shown in the Solution Explorer below:

 

Run the application and navigate to /IndexBlazor. You should get the following output.

 

At this stage the Razor Pages default page is displayed in the browser. What if we want to male our Blazor app as the default. Let's do that.

Rename Index.cshtml to IndexRazorPages.cshtml. And modify the _Host.cshtml as shown below:

@page "/"

@using Microsoft.AspNetCore.Components.Web
@using AspNetCoreAllInOne
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, 
initial-scale=1.0" />
    <base href="~/" />
    <component type="typeof(HeadOutlet)" 
render-mode="ServerPrerendered" />
</head>
<body>
    <component type="typeof(App)" render-mode="ServerPrerendered" />
    <script src="_framework/blazor.server.js"></script>
</body>
</html>

Note that the @page directive now specifies the route to be /

If you run the app after making this change it will directly show the output from Index.razor component.

 

Of course, you can also access the component using /IndexBlazor

Add API controller

Now let's add an API controller to the project. Open Program.cs again and add the following lines of code:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddControllers();
var app = builder.Build();
app.UseStaticFiles();
app.UseRouting();
app.MapDefaultControllerRoute();
app.MapRazorPages();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
app.MapControllers();
app.Run();

Notice the lines marked in bold letters. They are calls to AddControllers() and MapControllers() and will take care of Web API related functionality.

Now add an API controller named ValuesController in the Controllers folder.

 

Write the following code in ValuesController.cs

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    [HttpGet]
    public IActionResult Get()
    {
        string[] data = new string[] {
            "Hello World!",
            "Hello Galaxy!",
            "Hello Universe!"
        };
        return Ok(data);
    }
}

As an example we added just one action to the ValuesController. The Get() action is marked with [HttpGet] attribute and simply returns an array of three string values - Hello World!, Hello Galaxy!, and Hello Universe!

Run the application and navigate to /api/Values to invoke the Get() action. Here is the output:

 

As expected the browser receives an array with three string elements.

Add minimal API

Adding minimal APIs is quite straightforward. Open Program.cs file and add the following MapGet() call just before app.Run() :

app.MapGet("/minimalapi/values", () =>
{
    string[] data = new string[] {
                "Hello World!",
                "Hello Galaxy!",
                "Hello Universe!"
            };
    return Results.Ok(data);
});

As you can seem the MapGet() call specifies the endpoint URL to be /minimalapi/values and the handler function simply returns an array of string values.

Run the app again and navigate to /minimalapi/values. Here is the output:

 

As you can see, the output is identical to the API controller but we invoked the minimal API using a different endpoint (/minimalapi/values).

Using the Default.html page

We have added Default.html page in the wwwroot folder. Let's use it to include URLs to all the endpoints we created so far.

Open Default.html and add the following code:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <h1>This is default page!</h1>

    <h3><a href="/Home/Index">
Go to ASP.NET Core MVC</a></h3>

    <h3><a href="/IndexRazorPages">
Go to ASP.NET Core Razor Pages</a></h3>

    <h3><a href="/IndexBlazor">
Go to ASP.NET Core Blazor</a></h3>

    <h3><a href="/Api/Values">
Go to ASP.NET Core API Controller</a></h3>

    <h3><a href="/MinimalApi/Values">
Go to ASP.NET Core Minimal API</a></h3>

</body>
</html>

This is a simple page containing hyperlinks and looks like this in the browser:

 

Now open Index.razor component and remove this like:

@page "/"

The Index.razor won't be the default component anymore and you will get this error after running the app.

 

Click on the Go to Default page link and you will go to the Default.html page.

Click on each of the link and see if you get the correct output.

That's it for now! Keep coding!!

标签:Razor,Use,ASP,Index,app,Pages,add,page
From: https://www.cnblogs.com/comsher/p/17197333.html

相关文章

  • ansible user模块批量修改用户密码
    目录ansibleuser模块批量修改用户密码更改多个用户更改单个用户ansibleuser模块批量修改用户密码更改多个用户//修改主机,账号,密码----hosts:zksitgather_facts......
  • Host Referer User-Agent Content-Type
    Host作用:请求报头域主要用于指定被请求资源的internet主机和端口号 它通常从HTTPURL中提取出来的我们在浏览器中输入:http://fljf.com:8080......
  • ASP.NET Core中如何限制响应发送速率(不是调用频率)
    前言ASP.NETCore中有很多RateLimit组件,.NET7甚至推出了官方版本。不过这些组件的主要目标是限制客户端访问服务的频率,在HTTP服务器崩溃前主动拒绝部分请求。如果请求没......
  • asp .net 学习网站
    学习netcore思路:1.首先,了解.NETCore的基本概念,学习.NETCore的文档,以及它和.NETFramework的区别;2.学习.NETCore的构建工具,如MSBuild,NuGet,NPM,Bower等;3.学习.NETCore的......
  • python连接oracle 19c报错误ORA-01017: invalid username/password
    环境:db:19cpython:3.6最近有使用到cx_oracle(5.3)模块,这里记录下出现的问题由于我的项目一直在是windows上测试,最近把项目更新到linux下后,再去跑代码,发现代码报出ORA-2......
  • AspNet Core MVC项目接入AdminLTE
    AdminLTE是一款基于jQuery和Bootstrap的流行的后台管理界面框架,通过使用AdminLET框架提供的现成的组件可以大幅的提高后台管理界面的开发速度和规范性。参考 http......
  • Clickhouse实现累计求和cumulative sum
    源表数据如下:timeprovinceorder_cnt20200601shandong10020200601jiangsu20020200601zhejiang30020200602shandong20020200602jiangsu30020200602zhejiang40020200603shandon......
  • Use CMake notes
    WhayneedtheCMake?如果只是构建一个只有一个main.cpp的小型项目,那么确实不需要CMake,直接GCC、G++编译,或者写个build.sh脚本即可,不需要把简单的问题搞复杂化。$g++......
  • 京东云RASP云原生安全免疫创新实践
    作者:京东云刘一鑫1背景随着网络攻击事件整体呈上升趋势,应用作为网络入口承载着大量业务和流量,因此成为了安全的重灾区。黑客往往借助自动化的工具以及安全漏洞,对Web进......
  • useState+setInterval 导致获取useState都是原始的解决方法
    1import{useRef,useEffer}from"react";2exportfunctionuseInterval(callback,delay){3constsavedCallback=useRef();45useEffect(()=>......