Skip to content

Latest commit

 

History

History
222 lines (177 loc) · 7.58 KB

netcore.md

File metadata and controls

222 lines (177 loc) · 7.58 KB

Integrating ExtJS and .NET Core web application

  • Download and install Sencha Cmd and Sencha ExtJS SDK
  • Create a basic .NET Core MVC or WebApi project using Visual Studio or Visual Studio code
  • Ensure that the project has a wwwroot folder, and also that Razor Pages or Razor Views (or both) are enabled. For example, I use Razor Pages, and in my Program.cs file I see the following lines:
builder.Services.AddRazorPages();           // enables Razor MVVM
builder.Services.AddControllersWithViews(); // if you prefer classic MVC
...
app.UseDefaultFiles();                      // enables access to the index.html
app.UseStaticFiles();                       // enables access to staic content within the wwwroot folder
app.MapRazorPages();                        // enables requests to dynamic Razor pages
app.MapControllers();	                    // enables requests to MVC and WebApi controllers
  • Open terminal or command prompt, and navigate to the wwwroot folder. Execute the following commands to create a simple single-page ExtJS application:
cd wwwroot
sencha -sdk C:\sencha\sdk\ext-7.0.0 generate app MyDemo ./demo
# the -sdk options tells the generator to use a local cloned version of Sencha ExtJS SDK
# MyApp is a name of your application
# ./demo - relative path the ExtJS application should be created in
  • At this point, your project directory tree should look like
AspNetCoreApp
  |-wwwroot
    |-demo
      |-app.js
      |-app.json         <-- Application configuration manifest
      |-bootstrap.css
      |-bootstrap.js
      |-classic.json
      |-modern.json
      |-index.html       <-- Single page web application (SPA) entry point
      |-...
      |-app
        |-model
        |-store
        |-view
        |-Application.js
      |-build
      |-classic
      |-ext
      |-modern
      |-resources
  |-Pages
    |-Test.cshtml        <-- We will use that instead of index.html
  |-Controllers          <-- Optional
  |-Views                <-- Optional
  • Navigate to the wwwroot/demo folder and execute the following command:
sencha app build development
  • Next, you have to modify the Test.cshtml page. Simply copy here basic markup from the index.html file which has been generated by Sencha Cmd:
<!DOCTYPE HTML>
<html manifest="">
<head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=10, user-scalable=yes">

    <title>MyDemo</title>

    <script type="text/javascript">
        var Ext = Ext || {}; // Ext namespace won't be defined yet...

        // This function is called by the Microloader after it has performed basic
        // device detection. The results are provided in the "tags" object. You can
        // use these tags here or even add custom tags. These can be used by platform
        // filters in your manifest or by platformConfig expressions in your app.
        //
        Ext.beforeLoad = function (tags) {
            var s = location.search,  // the query string (ex "?foo=1&bar")
                profile;

            // For testing look for "?classic" or "?modern" in the URL to override
            // device detection default.
            //
            if (s.match(/\bclassic\b/)) {
                profile = 'classic';
            }
            else if (s.match(/\bmodern\b/)) {
                profile = 'modern';
            }
            else {
                profile = tags.desktop ? 'classic' : 'modern';
                //profile = tags.phone ? 'modern' : 'classic';
            }

            Ext.manifest = profile; // this name must match a build profile name
        };
    </script>

    <script id="microloader" data-app="f54f4456-d9ff-4321-b6b0-7f8cdee59cda" type="text/javascript" src="bootstrap.js"></script>

</head>
<body></body>
</html>
  • Let's take a look at the script[id=microloader] tag. It executes so called ExtJS microloader from the bootstrap.js file. But if you run your application and open your browser at http://localhost:1234/Test, you'll see nothing. That's because root directores do not match. The loader expects the base URL to be '/', but ours is '/Test'.

    Learning ExtJS you should actively use browser debugging tools that allow you to locate such a problems with relative addresses in ExtJS.

  • Let's slightly modify the ExtJS microloader url:

<script id="microloader" data-app="f54f4456-d9ff-4321-b6b0-7f8cdee59cda" type="text/javascript" src="~/demo/bootstrap.js"></script>
  • Once again, the app isn't working as the microloader wants you page to have root / URL and not /Test

  • How to solve such a problem? There are two approaches:

Method 1

In your Test.cshtml markup, insert the base element and change the application base URL:

<head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=10, user-scalable=yes">

    <title>MyDemo</title>
    <base href="~/demo/" />  <!-- HERE -->
    ...
    <script id="microloader" data-app="f54f4456-d9ff-4321-b6b0-7f8cdee59cda" type="text/javascript" src="bootstrap.js"></script>

Method 2

  • Open the app.json manifest
  • Find the indexHtmlPath param and change value from index.html to ../index.html. If your Sencha app resides deeper, just add one more navigational path, for example - ../../index.html
  • Execute the following batch which performs full rebuild of Sencha ExtJS app manifests (classic.json and modern.json) because of changed value of the indexHtmlPath property:
cd wwwroot/demo
sencha app build development
  • Modify your launcher script as follows (Test.cshtml). Later you can replace hardcoded base URLs with methods of the @Url helper:
    <!--base href="~/demo/" / -->
    <script type="text/javascript">
        var Ext = Ext || {};

        Ext.beforeLoad = function (tags) {
            var s = location.search, profile;

            if (s.match(/\bclassic\b/)) {
                profile = 'demo/classic';         // HERE
            }
            else if (s.match(/\bmodern\b/)) {
                profile = 'demo/modern';          // HERE
            }
            else {
                profile = tags.desktop ? 
                    'demo/classic' :              // HERE
                    'demo/modern';                // HERE
            }

            Ext.manifest = profile;
        };
    </script>

    <script id="microloader" 
            data-app="f54f4456-d9ff-4321-b6b0-7f8cdee59cda" 
            type="text/javascript" 
            src="~/demo/bootstrap.js"             // AND HERE
    ></script>
  • Run debugger and navigate the browser to /Test

Method 3

Redirect requests from ./wwwroot to the root directory of your ExtJS application:

Program.cs

var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
    Args = args,
    WebRootPath = "demo"
});

...

app.UseDefaultFiles();                        // makes `index.html` default
app.UseStaticFiles();                         // allows static files

// !!! If you use ExtJS workspaces, you'll also need to redirect requests to `ext` and `build` directories
app.UseStaticFiles(new StaticFileOptions
{
    RequestPath = "/ext",
    FileProvider = new PhysicalFileProvider(Path.Combine(builder.Environment.ContentRootPath, "ext"))
});
app.UseStaticFiles(new StaticFileOptions
{
    RequestPath = "/build",
    FileProvider = new PhysicalFileProvider(Path.Combine(builder.Environment.ContentRootPath, "build"))
});