Introduction
WebFrame - Doc 0.0.1

Release History
- 0.0.1 Initial Release
- 0.0.2
created by Michael Lopez published by EasyCode-IT AG (www.easycode-it.com)
License
This project is liscensed to EasyCode-IT AG, all rights reserved.
Contact
Technical Informations
To learn more about EasyWeb, or to recieve detailed infos, contact
EasyCode-IT AG Erlenstrasse 27 CH-2555 Brügg Switzerland
info@easycode-it.com www.easycode-it.com
Sales
If you are interested in using WebFrame for your company, please contact
EasyStudios Erlenstrasse 27 CH-2555 Brügg Switzerland
info@easystudios.ch www.easystudios.ch
General Info
WebFrame is the Module-Based Framework published and created by EasyCode-IT AG) With it’s dynamic structure and solid basis it provides a simple framework for all of our Modules.
Modules
Currently the following modules have been built:
- EasyWeb
- EasyShop
- EasyNews
- EasyService
Releases
Getting Started
Architecture
Modules
Tools
Jobscheduler
The jobscheduler integrated in WebFrame is responsible to run different jobs from all modules. The jobs get writen into the database and will be sent to be executed by an external windows service.
Application Architecture
ECIT.WebFrame.Web
ECIT.WebFrame.Lib
ECIT.WebFrame.Infrastructure
ECIT.WebFrame.Core
Modules
BaseModule
Every Module inherits from BaseModule. So the properties of BaseModule are described below:
public abstract class BaseModule
{
/// <summary>
/// Gets the title of the module a.e: "EasyWeb"
/// </summary>
/// <value>
/// The title.
/// </value>
public abstract string Title { get; }
/// <summary>
/// Gets the name of the module a.e: "ECIT.WebFrame.Modules.EasyWeb"
/// </summary>
/// <value>
/// The name.
/// </value>
public abstract string Name { get; }
/// <summary>
/// Gets the required role for accessing this module.
/// </summary>
/// <value>
/// The required role.
/// </value>
public abstract Role RequiredRole { get; }
/// <summary>
/// Gets the version of the module
/// </summary>
/// <value>
/// The version.
/// </value>
public abstract Version Version { get; }
/// <summary>
/// Gets the module navigation
/// </summary>
/// <value>
/// The admin navigation.
/// </value>
public abstract ModuleNavigation Navigation { get; }
/// <summary>
/// Gets the robots information.
/// </summary>
/// <value>
/// The robots information.
/// </value>
public virtual RobotsInformation RobotsInformation
{
get { return null; }
}
/// <summary>
/// Gets the wildcard routes.
/// </summary>
/// <value>
/// The wildcard routes.
/// </value>
public virtual List<MvcRoute> WildcardRoutes
{
get { return null; }
}
/// <summary>
/// Gets the FTP interface for the Module
/// </summary>
/// <value>
/// The FTP interface.
/// </value>
public virtual IFtp FtpInterface
{
get { return null; }
}
/// <summary>
/// Initializes this instance.
/// </summary>
public abstract void Init();
/// <summary>
/// Users the cleanup.
/// </summary>
/// <param name="user">The user.</param>
public abstract void UserCleanup(User user);
/// <summary>
/// Gets or sets the application identifier.
/// </summary>
/// <value>
/// The application identifier.
/// </value>
public int ApplicationId { get; set; }
}
Init()
Init is used to execute code before the modules get loaded. As example for creating user roles:
public override void Init()
{
RoleManager.InitRole(EasyWebDefaultRoles.EASYWEB_USER, "EasyWeb User Role");
}
FtpInterface
FtpInterface provides a simple way to add FTP Support for the Module. What you are going to do with the FTP Protocoll and the transfered data is completly by the logic of the module :=)
For an easy implementation just override the abstract property with the following code:
public override IFtp FtpInterface
{
get { return new FtpInterface(); }
}
Create a class that interhits from the IFtp Interface as showed bellow and fill out the methods:
…. -> Further information coming soon!
public class FtpInterface : IFtp
{
/// <summary>
/// Deletes the specified pathname.
/// </summary>
/// <param name="pathname">The pathname.</param>
/// <returns></returns>
/// <exception cref="System.NotImplementedException"></exception>
public string Delete(string pathname)
{
throw new NotImplementedException();
}
/// <summary>
/// Renames the specified rename from.
/// </summary>
/// <param name="renameFrom">The rename from.</param>
/// <param name="renameTo">The rename to.</param>
/// <returns></returns>
/// <exception cref="System.NotImplementedException"></exception>
public string Rename(string renameFrom, string renameTo)
{
throw new NotImplementedException();
}
/// <summary>
/// Creates the dir.
/// </summary>
/// <param name="pathname">The pathname.</param>
/// <returns></returns>
/// <exception cref="System.NotImplementedException"></exception>
public string CreateDir(string pathname)
{
throw new NotImplementedException();
}
/// <summary>
/// Removes the dir.
/// </summary>
/// <param name="pathname">The pathname.</param>
/// <returns></returns>
/// <exception cref="System.NotImplementedException"></exception>
public string RemoveDir(string pathname)
{
throw new NotImplementedException();
}
/// <summary>
/// Changes the working directory.
/// </summary>
/// <param name="pathname">The pathname.</param>
/// <returns></returns>
/// <exception cref="System.NotImplementedException"></exception>
public string ChangeWorkingDirectory(string pathname)
{
throw new NotImplementedException();
}
/// <summary>
/// Lists the operation.
/// </summary>
/// <param name="dataStream">The data stream.</param>
/// <param name="pathname">The pathname.</param>
/// <returns></returns>
/// <exception cref="System.NotImplementedException"></exception>
public string ListOperation(NetworkStream dataStream, string pathname)
{
throw new NotImplementedException();
}
/// <summary>
/// Retrieves the operation.
/// </summary>
/// <param name="dataStream">The data stream.</param>
/// <param name="pathname">The pathname.</param>
/// <returns></returns>
/// <exception cref="System.NotImplementedException"></exception>
public string RetrieveOperation(NetworkStream dataStream, string pathname)
{
throw new NotImplementedException();
}
/// <summary>
/// Stores the operation.
/// </summary>
/// <param name="dataStream">The data stream.</param>
/// <param name="pathname">The pathname.</param>
/// <returns></returns>
/// <exception cref="System.NotImplementedException"></exception>
public string StoreOperation(NetworkStream dataStream, string pathname)
{
throw new NotImplementedException();
}
/// <summary>
/// Appends the operation.
/// </summary>
/// <param name="dataStream">The data stream.</param>
/// <param name="pathname">The pathname.</param>
/// <returns></returns>
/// <exception cref="System.NotImplementedException"></exception>
public string AppendOperation(NetworkStream dataStream, string pathname)
{
throw new NotImplementedException();
}
}
…. -> Further information coming soon!
Wildcardroutes
Wildcardroutes provides a simple way to add wildcardroutes to the routing of your Module
The Wildcardroutes is built as a abstract property in the BaseModule so it can be overriden in the individual Module.
public override List<MvcRoute> WildcardRoutes
{
get
{
var retVal = new List<MvcRoute>
{
new MvcRoute
{
Name = "EasyWeb_404",
Url = "{lang}/error/404",
Defaults = new {controller = "Web", action = "Error404", lang = ""},
Namespaces = new[] {"ECIT.WebFrame.Modules.EasyWeb.Controllers.Frontend"},
Constraints = new {customConstraint = new TenantHasModuleConstraint(this.Title)}
}
};
return retVal;
}
}
Navigation
Navigation provides a simple way to create a navigation for your Module
The Navigation is built as a abstract property in the BaseModule so it can be overriden in the individual Module.
Use the following code in your Module implementation, to allow the lowest user level:
public override ModuleNavigation Navigation
{
get
{
var retVal = new ModuleNavigation()
{
Icon = "fa-globe",
Name = "EasyWeb",
NavigationPoints = new List<ModuleNavigationPoint>
{
new ModuleNavigationPoint
{
Name = "Dashboard",
Url = "/Admin/" + this.Title + "/Dashboard",
RequiredRole = null,
Icon = "fa-dashboard"
}
}
};
}
}
RequiredRole
RequiredRole provides a simple way to permissioning your Module
The RequiredRole is built as a abstract property in the BaseModule so it can be overriden in the individual Module.
Use the following code in your Module implementation, to allow the lowest user level:
public override Role RequiredRole
{
get
{
return RoleManager.GetRole(EasyWebDefaultRoles.EASYWEB_USER);
}
}
RobotsInformation
RobotsInformation provides a simple way to provide Instance wide Robots.txt Information.
The RobotsInforamtion is built as a abstract property in the BaseModule so it can be overriden in the individual Module
public class RobotsInformation
{
public List<string> DisallowUrls { get; set; }
public string SitemapUrl { get; set; }
}
Use the following code in your Module implemetation, to add your nessecary infos into robots.txt:
public override RobotsInformation RobotsInformation
{
get
{
var disallowUrls = GeneralSettingsManager.CreateInstance(this.ApplicationId).GetGeneralSettings().IsUnderConstructionMode ? new List<string>{"/"} : PageContentManager.CreateInstance(this.ApplicationId).GetPageContentsRaw().Where(m => m.AllowPageIndexing == false).ToList().Select(pageContent => PageContentManager.CreateInstance(this.ApplicationId).GetPageContentUrl(pageContent)).ToList();
return new RobotsInformation
{
DisallowUrls = disallowUrls,
SitemapUrl = GeneralSettingsManager.CreateInstance(this.ApplicationId).GetGeneralSettings().WebsiteUrl + "/sitemap.xml"
};
}
}
Step for new Modul
- Create Modul and Lib project
- Create Folder structur and areas like webmodul
- Add reference to Webframe.Infrastructur
- install nuget packages in lib: entity framework
- in frontend install: mvc5, RazorGenerator.MsBuild
- create the modul configuration-> see other modul – Notice: That you installe the razorgenerator addin for visual studio before.
Important:
The lib is only for EF shizzl every other thing goes into the web project
Create a View
Install the ‘RazorGenerator.Mvc’ package, which registers a special view engine Go to an MVC Razor view’s property and set the Custom tool to RazorGenerator Optionally specify a value for Custom Tool Namespace to specify a namespace for the generated file. The project namespace is used by default. Optionally specify one of the generators in the first line of your Razor file. A generator declaration line looks like this: @* Generator: MvcHelper *@ . If you don’t specify this, a generator is picked based on convention (e.g. files under Views are treated as MvcViews) You’ll see a generated .cs file under the .cshtml file, which will be used at runtime instead of the .cshtml file You can also go to the nuget Package Manager Console and run ‘Enable-RazorGenerator’ to enable the Custom Tool on all the views. And to cause all the views to be regenerated, go to the nuget Package Manager Console and run ‘Redo-RazorGenerator’. This is useful when you update the generator package and it needs to generate different code.
Prefix every table
In every modul the tablenames must be prefixed!
protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Types().Configure(entity => entity.ToTable("EasyWeb_" + entity.ClrType.Name)); }
First Migrations
If you make the first migration you had to comment out, all tables from basecontext, such as user, application, servers
Publish Webframe
Just click Publish and copy the files.
But dont forget to copy the EntityFramework.SqlServer.dll by hand to the bin folder. If you want that it works ;)
Modules
Frontend
Know How
SQL Scripts
Short SQL Cursor Script to read or update Data from a set of values using cursor.
DECLARE @URL as NVARCHAR(150);
DECLARE @LangCode as NVARCHAR(30);
DECLARE @Collection as NVARCHAR (50);
DECLARE @ParentID as INT;
DECLARE @PageContentID as INT;
DECLARE @PageContentTitle as NVARCHAR (50);
DECLARE @ApplicationID as INT;
DECLARE @LanguageID as INT;
DECLARE @PageID as INT;
DECLARE @EasyWebCursor as CURSOR;
SET @EasyWebCursor = CURSOR FOR
SELECT ID, Title, Application_ID, Language_ID, Page_ID FROM EasyWeb_PageContent
WHERE Content LIKE '%wf-slider%'
OPEN @EasyWebCursor;
FETCH NEXT FROM @EasyWebCursor INTO @PageContentID, @PageContentTitle, @ApplicationID, @LanguageID, @PageID;
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @URL = WebsiteUrl FROM EasyWeb_GeneralSettings WHERE Application_ID = @ApplicationID;
IF (@URL is null or @URL = '')
BEGIN
DECLARE @ApplicationName as NVARCHAR(50);
SELECT @ApplicationName = Name FROM Applications WHERE ID = @ApplicationID;
print @ApplicationName + ' has no Website Url';
FETCH NEXT FROM @EasyWebCursor INTO @PageContentID, @PageContentTitle, @ApplicationID, @LanguageID, @PageID;
END
ELSE
BEGIN
SELECT @LangCode = Code FROM EasyWeb_Language WHERE ID = @LanguageID;
SELECT @ParentID = ParentPage_ID FROM EasyWeb_Page WHERE ID = @PageID;
IF (@ParentID = null Or @ParentID = 0)
BEGIN
PRINT @URL + '/' + @LangCode + '/' + @PageContentTitle;
END
ELSE
BEGIN
SELECT @Collection = Title FROM EasyWeb_PageContent WHERE Page_ID = @ParentID AND Language_ID = @LanguageID;
PRINT @URL + '/' + @LangCode + '/' + @Collection + '/' + @PageContentTitle;
END
FETCH NEXT FROM @EasyWebCursor INTO @PageContentID, @PageContentTitle, @ApplicationID, @LanguageID, @PageID;
END
END
CLOSE @EasyWebCursor;
DEALLOCATE @EasyWebCursor;