Readdy Write  
0,00 €
Your View Money
Views: Count
Self 20% 0
Your Content 60% 0

Users by Links 0
u1*(Content+Views) 10% 0
Follow-Follower 0
s2*(Income) 5% 0

Count
Followers 0
Login Register as User

Gelöst: API Controller wird bei React nicht erreicht OK 304

28.12.2022 (👁8970)

Gelöst: API Controller wird bei React nicht erreicht



Problem: bei einer neu erstellen React Anwendung mit ASP.Net Controller unter Visual Studio 2022 und .Net6 wird der Daten Controller nie erreicht.

Die Anwendung meldet OK 305 zurück

Lösung: man muss unter der React -Datei setupProxy.js die Erweiterung für den Controller eintragen

Solution is:
setupProxy.js

 

const { createProxyMiddleware } = require('http-proxy-middleware');

const { env } = require('process');

 

const target = env.ASPNETCORE_HTTPS_PORT ? `https://localhost:${env.ASPNETCORE_HTTPS_PORT}` :

  env.ASPNETCORE_URLS ? env.ASPNETCORE_URLS.split(';')[0] : 'http://localhost:46007';

 

const context =  [

    "/api",

    "/weatherforecast",       

  "/_configuration",

  "/.well-known",

  "/Identity",

  "/connect",

  "/ApplyDatabaseMigrations",

  "/_framework"

];

 

module.exports = function(app) {

  const appProxy = createProxyMiddleware(context, {

    target: target,

    secure: false,

    headers: {

      Connection: 'Keep-Alive'

    }

  });

 

  app.use(appProxy);

};

 

 

With added “/api” it works

Ein Bild, das Text, Screenshot, drinnen, Computer enthält.

Automatisch generierte Beschreibung

 

Asp.net6:  Program.cs

Ein Bild, das Text enthält.

Automatisch generierte Beschreibung

using Microsoft.AspNetCore.Authentication;

using Microsoft.AspNetCore.Identity;

using Microsoft.AspNetCore.Identity.UI;

using Microsoft.EntityFrameworkCore;

using Rue25.Data;

using Rue25.Models;

 

var builder = WebApplication.CreateBuilder(args);

 

// Add services to the container.

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");

builder.Services.AddDbContext<ApplicationDbContext>(options =>

    options.UseSqlServer(connectionString));

builder.Services.AddDatabaseDeveloperPageExceptionFilter();

 

builder.Services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)

    .AddEntityFrameworkStores<ApplicationDbContext>();

 

builder.Services.AddIdentityServer()

    .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();

 

//*AntiforgeryToken

 

// Angular's default header name for sending the XSRF token.

 

builder.Services.AddAntiforgery(options =>

{

    options.HeaderName = "X-XSRF-TOKEN";

    //options.Cookie.Name = "X-XSRF-TOKEN";  //"X-CSRF-TOKEN-OurAppName";

    // Set Cookie properties using CookieBuilder properties†.

    //options.FormFieldName = "AntiforgeryFieldname";

    //options.HeaderName = "X-CSRF-TOKEN-HEADERNAME";

    //options.SuppressXFrameOptionsHeader = false;

});

 

builder.Services.AddAuthentication()

    .AddIdentityServerJwt();

 

builder.Services.AddControllersWithViews();

builder.Services.AddRazorPages();

 

var app = builder.Build();

 

// Configure the HTTP request pipeline.

if (app.Environment.IsDevelopment())

{

    app.UseMigrationsEndPoint();

}

else

{

    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.

    app.UseHsts();

}

 

app.UseHttpsRedirection();

app.UseStaticFiles();

app.UseRouting();

 

app.UseAuthentication();

app.UseIdentityServer();

app.UseAuthorization();

 

 

app.UseEndpoints(endpoints =>

{

    endpoints.MapControllerRoute(

    name: "api",

    pattern: "/{controller}/{action=Index}/{id?}");

    endpoints.MapRazorPages();

});

 

 

app.MapFallbackToFile("index.html"); ;

 

 

app.Run();

 

 

 

//--< AntiForgery >--

 

//app.us

////*add in Configure(.. , IAntiforgery antiforgery)

//    app.Use(next => context =>

//    {

//        string path = context.Request.Path.Value;

//        string[] urlAreas = { "/api", "/swagger", "articles" };

//        if (

//            string.Equals(path, "/", StringComparison.OrdinalIgnoreCase) ||

//            string.Equals(path, "/index.html", StringComparison.OrdinalIgnoreCase) ||

//            urlAreas.Any(urlAreas => path.StartsWith(urlAreas))

//            )

//        {

//            // The request token can be sent as a JavaScript-readable cookie,

//            // and Angular uses it by default.

//            var tokens = antiforgery.GetAndStoreTokens(context);

//            context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken,

//                new CookieOptions()

//               {

//                    HttpOnly = false,

//                    Secure = false,

//                    IsEssential = true,

//                    SameSite = SameSiteMode.Strict

//                });

//        }

 

//       return next(context);

//    });

////--</ AntiForgery >--

 

React Articles.js

Ein Bild, das Text enthält.

Automatisch generierte Beschreibung

 

import React, { Component } from 'react';

 

export class Articles extends Component {

    //--------< component: Articles >--------

 

    //====< compontent >====

    static displayName = Articles.name;

 

    constructor(props) {

        //-< react: parameter >

        super(props);

        //-</ react: parameter >

 

        //--< react: variables >--

        this.state = {

            articles: [],

            loading: true

        };

        //--</ react: variables >-

    }

 

    //--< component.events >--

    componentDidMount() {

        this.populateData();

    }

    //--</ component.events >--

 

    //====</ compontent >====

 

 

    //========< Fill HTML >======

 

    static renderTable(articles) {

        return (

            <table className='table table-striped' aria-labelledby="tabelLabel">

                <thead>

                    <tr>

                        <th>title</th>

 

                    </tr>

                </thead>

                <tbody>

                    {articles.map(article =>

                        <tr key={article.IDArticle}>

                            <td>{article.title}</td>

                        </tr>

                    )}

                </tbody>

            </table>

        );

    }

    //========</ Fill HTML >======

    //====< react: render >====

    //*set root hmtl, load data, fill data

    render() {

        //----< prepare document >---

        let contents = this.state.loading

            ? <p><em>Loading...</em></p>

            : Articles.renderTable(this.state.articles);

        //----</ prepare document >---

 

 

        //----< fill html >----

        return (

            <div>

                <h1 id="tableLabel" >Articles</h1>

                <p>This component demonstrates fetching data from the server.</p>

                {contents}

            </div>

        );

        //----</ fill html >----

 

    }

    //====</ react: render >====

    //====< functions >====

    //*load data from web api

    async populateData() {

        //--------< populateData() >--------

        const response = await fetch('api/articles/list');   //*get web_data from web api as json-string

        const data = await response.json();             //*convert json to data

        this.setState({ articles: data, loading: false }); //*refresh state of arcticles

        //--------</ populateData() >--------

    }

    //====</ functions >====

 

    //--------</ component: Articles >--------

}

 

 

 

ArticlesController.cs

Ein Bild, das Text enthält.

Automatisch generierte Beschreibung

Using Microsoft.AspNetCore.Mvc;

using Microsoft.EntityFrameworkCore;

using Rue25.Models;

using Rue25.Data;

 

namespace Controllers

{

    //------------< Namespace >------------

    [Produces ("application/json")]

    [Route("api/articles")]

    [ApiController]

    public class ArticlesController : ControllerBase

    {

        //--------< Controller: ArticlesController >--------

        #region init

        private readonly ApplicationDbContext _dbContext;

 

        public ArticlesController(ApplicationDbContext dbcontext)

        {

            _dbContext = dbcontext; //*get database context

        }

        #endregion /init

 

        // GET: api/Articles

        [HttpGet("list")]

        public async Task<ActionResult<IEnumerable<ArticleModel>>> List()

        {

            //-------------< Liste >-------------

            var data = _dbContext.tbl_Articles.Take(100);

            return await data.ToListAsync();

            //-------------</ Liste >-------------

        }

    }

}

 

appRoutes.js

import ApiAuthorzationRoutes from './components/api-authorization/ApiAuthorizationRoutes';

import { Counter } from "./components/Counter";

import { FetchData } from "./components/FetchData";

import { Home } from "./components/Home";

import { Articles } from "./components/Articles";

 

const AppRoutes = [

 

    {

        index: true,

        element: <Home />

    }, {

        path: '/counter',

        element: <Counter />

    },

    {

        path: '/fetch-data',

        requireAuth: true,

        element: <FetchData />

    },

    {

        path: '/articles',

        element: <Articles/>

    },

 

 

    ...ApiAuthorzationRoutes

];

 

export default AppRoutes;

 

 

 

App.js

import React, { Component } from 'react';

import { Route, Routes } from 'react-router-dom';

import AppRoutes from './AppRoutes';

import AuthorizeRoute from './components/api-authorization/AuthorizeRoute';

import { Layout } from './components/Layout';

import './custom.css';

 

export default class App extends Component {

  static displayName = App.name;

 

 

 

  render() {

    return (

      <Layout>

        <Routes>

          {AppRoutes.map((route, index) => {

            const { element, requireAuth, ...rest } = route;

            return <Route key={index} {...rest} element={requireAuth ? <AuthorizeRoute {...rest} element={element} /> : element} />;

          })}

        </Routes>

      </Layout>

    );

  }

}