Skip to content

Commit b087c8c

Browse files
committed
Merged docs.
2 parents 232ce99 + 337666d commit b087c8c

File tree

165 files changed

+1798
-666
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

165 files changed

+1798
-666
lines changed

doc/WebSite/Audit-Logging.html

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,6 @@ <h3 id="DocConfig">Configuration</h3>
7373
<strong>IsEnabledForAnonymousUsers</strong>: If this is set to true,
7474
audit logs are saved also for users those are not logged in to the system.
7575
Default: <strong>false</strong>.</li>
76-
<li>
77-
<strong>MvcControllers</strong>: Used to configure auditing for ASP.NET MVC Controllers.<ul>
78-
<li>
79-
<strong>IsEnabled</strong>: Used to enable/disable auditing for MVC controllers.
80-
Default: <strong>true</strong>.</li>
81-
<li>
82-
<strong>IsEnabledForChildActions</strong>: Used to enable/disable auditing for child MVC actions.
83-
Default: <strong>false</strong>.</li>
84-
</ul>
85-
</li>
8676
<li>
8777
<strong>Selectors</strong>: Used to select other classes to save audit logs.</li>
8878
</ul>
@@ -101,6 +91,9 @@ <h3 id="DocConfig">Configuration</h3>
10191
can remove the selector above by name if you don't like to save audit logs for
10292
application services. That's why it has a unique name (Use simple LINQ to find
10393
the selector in Selectors and remove it if you want).</p>
94+
<p>Note: In addition to standard audit configuration, MVC and
95+
ASP.NET Core modules define configuration to enable/disable audit
96+
logging for actions.</p>
10497

10598
<h3 id="DocEnableDisableByAttrs">Enable/Disable by attributes</h3>
10699
<p>While you can select auditing classes by configuration, you can use <strong>

doc/WebSite/Dynamic-Web-API.html

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,6 @@ <h4>Overriding ForAll</h4>
8282
<p>In this code, we created dynamic web api controllers for all application
8383
services in an assembly. Then overrided configuration for a single application
8484
service (ITaskAppService) to ignore CreateTask method. </p>
85-
<h5>DisableDynamicWebApiAttribute</h5>
86-
<p>You can also use DisableDynamicWebApiAttribute for any <strong>
87-
interface</strong> or
88-
<strong>method</strong> definition to ignore this service or method while creating
89-
dynamic web api.</p>
9085
<h5>ForMethods</h5>
9186
<p>We can use <strong>ForMethods</strong> method to better adjust
9287
each method while using ForAll method. Example:</p>
@@ -158,6 +153,16 @@ <h5>Naming Convention</h5>
158153
HTTP verb.</li>
159154
</ul>
160155
<p>We can override it for a specific method as described before.</p>
156+
<h4>API Explorer</h4>
157+
<p>All dynamic web api controllers are visible to API explorer by
158+
default (They are available in <a href="Swagger-UI-Integration.html">
159+
Swagger</a> for example). You can control this behaviour with fluent DynamicApiControllerBuilder
160+
API or using RemoteService attribute defined below.</p>
161+
<h4>RemoteService Attribute</h4>
162+
<p>You can also use <strong>RemoteService</strong> attribute for any <strong>
163+
interface</strong> or
164+
<strong>method</strong> definition to enable/disable (<strong>IsEnabled</strong>)
165+
dynamic API or API explorer setting (<strong>IsMetadataEnabled</strong>).</p>
161166
<h3 id="DocDynamicProxy">
162167
Dynamic Javascript Proxies</h3>
163168
<p>

doc/WebSite/Entities.html

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,29 @@ <h3 id="DocEntityClasses">Entity Classes</h3>
5454
<p>Entity class overrides <strong>equality</strong> operator (==) to easily
5555
check if two entities are equal (their Id is equal). It also defines the <strong>
5656
IsTransient()</strong> method to check if it has an Id or not.</p>
57+
<h3>AggregateRoot Class</h3>
58+
<p>"<em>Aggregate is a pattern in Domain-Driven Design. A DDD
59+
aggregate is a cluster of domain objects that can be treated as a
60+
single unit. An example may be an order and its line-items, these
61+
will be separate objects, but it's useful to treat the order
62+
(together with its line items) as a single aggregate.</em>" (Martin
63+
Fowler - see
64+
<a href="http://martinfowler.com/bliki/DDD_Aggregate.html" target="_blank">
65+
full description</a>)</p>
66+
<p>While ABP does not enforce you to use aggregates, you may want to
67+
create aggregates and aggregate roots in your application. ABP
68+
defines <strong>AggregateRoot</strong> class that extends Entity to
69+
create aggregate root entities for an aggregate.</p>
70+
<h4>Domain Events</h4>
71+
<p>AggregateRoot defines <a href="EventBus-Domain-Events.html">
72+
<strong>DomainEvents</strong></a> collection to generate domain
73+
events by the aggregate root class. These events are automatically
74+
triggered just before the current <a href="Unit-Of-Work.html">unit
75+
of work</a> is completed. Actually, any entity can generate domain
76+
events by implementing <strong>IGeneratesDomainEvents</strong>
77+
interface, but it's common (best practice) to generate domain events
78+
in aggregate roots. That's why it's default for AggregateRoot but
79+
not for Entity class.</p>
5780
<h3 id="DocConventionalInterfaces">Conventional Interfaces</h3>
5881
<p>In many application, similar entity properties (and database table fields)
5982
are used like CreationTime indicates that when this entity is created. ASP.NET

doc/WebSite/Entity-Framework-Core.html

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,27 @@ <h5>Custom Repository Example</h5>
207207
</strong>it in the <strong>EntityFrameworkCore </strong>project for layered
208208
applications. Thus, you can inject the interface from any project without
209209
referencing to EF Core.</p>
210+
<h5>Replacing Default Repositories</h5>
211+
<p>Even you have created a TaskRepository as shown above, any class can
212+
still <a href="Dependency-Injection.html">inject</a> IRepository&lt;Task, long&gt;
213+
and use it. That's not a problem in most cases. But, what if you <strong>
214+
overrided</strong> a base method in your custom repository? Say that you
215+
have overrided Delete method in your custom repository to add a custom
216+
behaviour on delete. If a class injects IRepository&lt;Task, long&gt; and use the
217+
default repository to Delete a task, your custom behaviour will not work. To
218+
overcome this issue, you can replace your custom repository implementation
219+
with the default one like shown below:</p>
220+
<pre lang="cs">Configuration.ReplaceService&lt;<strong>IRepository&lt;Task, Guid&gt;</strong>&gt;(() =&gt;
221+
{
222+
IocManager.IocContainer.Register(
223+
Component.For&lt;<strong>IRepository&lt;Task, Guid&gt;, ITaskRepository, TaskRepository</strong>&gt;()
224+
.ImplementedBy&lt;<strong>TaskRepository</strong>&gt;()
225+
.<strong>LifestyleTransient</strong>()
226+
);
227+
});</pre>
228+
<p>We registered TaskRepository for IRepository&lt;Task, Guid&gt;,
229+
ITaskRepository and TaskRepository. So, any one of these can be injected to
230+
use the TaskRepository.</p>
210231
<h4>Repository Best Practices</h4>
211232
<ul>
212233
<li><strong>Use default repositories</strong> wherever it's

doc/WebSite/EventBus-Domain-Events.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,10 @@ <h3 id="DocTriggerEvents">Triggering Events</h3>
112112
EventBus.Trigger(this, new TaskCompletedEventData { TaskId = 42 }); //Set 'event source' as 'this'
113113
EventBus.Trigger(typeof(TaskCompletedEventData), this, new TaskCompletedEventData { TaskId = 42 }); //Call non-generic version (first argument is the type of the event class)</pre>
114114

115+
<p>Another way of triggering events can be using DomainEvents collection of
116+
AggregateRoot class (see related section in the <a href="Entities.html">Entity
117+
documentation</a>).</p>
118+
115119
<h3 id="DocHandleEvents">Handling Events</h3>
116120

117121
<p>To handle an event, you should implement <strong>IEventHandler&lt;T&gt;</strong>

doc/WebSite/Module-System.html

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,33 @@ <h4>ASP.NET MVC, Web API</h4>
115115
//...
116116
base.Application_Start(sender, e);
117117
}
118+
}</pre>
119+
<h5 lang="cs"><span lang="tr">Controllers in PlugIns</span></h5>
120+
<p lang="cs"><span lang="tr">If your modules include MVC or Web API
121+
Controllers, ASP.NET can not investigate your controllers. To
122+
overcome this issue, you can change global.asax file like below:</span></p>
123+
<pre lang="cs">using System.Web;
124+
using Abp.PlugIns;
125+
using Abp.Web;
126+
using MyDemoApp.Web;
127+
128+
<strong>[assembly: PreApplicationStartMethod(typeof(PreStarter), &quot;Start&quot;)]
129+
</strong>
130+
namespace MyDemoApp.Web
131+
{
132+
public class MvcApplication : AbpWebApplication&lt;MyStartupModule&gt;
133+
{
134+
}
135+
136+
public static class PreStarter
137+
{
138+
public static void Start()
139+
{
140+
//...
141+
MvcApplication.AbpBootstrapper.PlugInSources.AddFolder(@&quot;C:\MyPlugIns\&quot;);
142+
<strong>MvcApplication.AbpBootstrapper.PlugInSources.AddToBuildManager();</strong>
143+
}
144+
}
118145
}</pre>
119146
<h3>Additional Assemblies</h3>
120147
<p>Default implementations for IAssemblyFinder and ITypeFinder (which is used by ABP to investigate specific classes

doc/WebSite/OWIN.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@
3232

3333
</div>
3434

35+
<p>If you are only using OWIN (say, in a self hosted Web API project),
36+
you can use override of UseAbp which takes a startup module to
37+
initialize ABP framework. Notice that; this should be done only if ABP
38+
is not initialized in another way.</p>
39+
3540
</body>
3641

3742
</html>

doc/WebSite/Setting-Management.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,10 @@ <h4 id="DocSettingScopes">Setting scope</h4>
136136
</ul>
137137
<p>Default value can be <strong>null </strong>or <strong>empty </strong>string.
138138
It's adviced to provide default values for settings where it's possible.</p>
139+
<h4>Overriding Setting Definitions</h4>
140+
<p>context.Manager can be used to get a setting definition to change
141+
it's values. In this way, you can manipulate setting definitions of
142+
<a href="Module-System.html">depended modules</a>.</p>
139143

140144
<h3 id="DocGettingValues">Getting setting values</h3>
141145
<p>After defining a setting, we can get it's current value both in server and

doc/WebSite/Swagger-UI-Integration.html

Lines changed: 95 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,71 @@
1111

1212
<div class="document-contents">
1313

14-
<h3>Introduction</h3>
14+
<h2>Introduction</h2>
1515
<p>From it's web site: "....with a Swagger-enabled API, you get <strong>
1616
interactive documentation</strong>, client SDK generation and discoverability."</p>
17+
<h2>ASP.NET Core</h2>
18+
<h3>Installation</h3>
19+
<p>It's easy to integrate Swagger into your ASP.NET Boilerplate based ASP.NET Core application.</p>
20+
<h4>Install Nuget Package</h4>
21+
<p>Install <strong>
22+
<a href="https://www.nuget.org/packages/Swashbuckle/6.0.0-beta902">Swashbuckle</a></strong>
23+
nuget package to your <strong>Web</strong> project.</p>
24+
<h4>Configure</h4>
25+
<p>Add configuration code for Swagger into <strong>ConfigureServices</strong> method of your <strong>Startup.cs</strong></p>
26+
<pre lang="cs">
27+
public IServiceProvider ConfigureServices(IServiceCollection services)
28+
{
29+
//your other code...
30+
31+
<strong>services.AddSwaggerGen();</strong>
32+
33+
//your other code...
34+
}
35+
</pre>
36+
37+
<p>Then, add below code into <strong>Configure </strong>method of <strong>Startup.cs</strong> to use Swagger</p>
38+
<pre lang="cs">
39+
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
40+
{
41+
//your other code...
42+
43+
<strong>app.UseSwagger();
44+
app.UseSwaggerUi(); //URL: /swagger/ui
45+
</strong>}
46+
</pre>
47+
<p>And finally, in order to send CSRF token when testing dynamic web api services from swagger ui, you need to add swagger ui's <a href="https://github.com/swagger-api/swagger-ui/blob/master/dist/index.htmlhttps://github.com/swagger-api/swagger-ui/blob/master/dist/index.html">index.html</a> file to your web project. It should be placed exactly under "<strong>wwwroot\swagger\ui</strong>" folder.
48+
Then you need to change <strong>onComplete </strong>method of swagger ui definition like this in
49+
<strong>index.html</strong>.</p>
50+
<pre lang="js">
51+
onComplete: function(swaggerApi, swaggerUi){
52+
if(typeof initOAuth == "function") {
53+
initOAuth({
54+
clientId: "your-client-id",
55+
clientSecret: "your-client-secret-if-required",
56+
realm: "your-realms",
57+
appName: "your-app-name",
58+
scopeSeparator: " ",
59+
additionalQueryStringParams: {}
60+
});
61+
}
62+
63+
if(window.SwaggerTranslator) {
64+
window.SwaggerTranslator.translate();
65+
}
66+
67+
<strong> var csrfToken = abp.security.antiForgery.getToken();
68+
var csrfCookieAuth = new SwaggerClient.ApiKeyAuthorization(abp.security.antiForgery.tokenHeaderName, csrfToken, "header");
69+
swaggerUi.api.clientAuthorizations.add(abp.security.antiForgery.tokenHeaderName, csrfCookieAuth);
70+
</strong>
71+
}</pre>
72+
<p>See Swashbuckle <a href="https://github.com/domaindrivendev/Ahoy">documentation</a> for more configuration options.</p>
73+
<h4>Test</h4>
74+
<p>That's all. You can browse swagger ui under "<strong>/swagger/ui/index</strong>".</p>
75+
76+
77+
78+
<h2>ASP.NET 5.x</h2>
1779
<h3>Installation</h3>
1880
<p>It's easy to integrate <a href="http://swagger.io/">Swagger</a> into your
1981
ASP.NET Boilerplate based application.</p>
@@ -42,11 +104,41 @@ <h4>Configure</h4>
42104
c.SingleApiVersion(&quot;v1&quot;, &quot;SwaggerIntegrationDemo.WebApi&quot;);
43105
c.ResolveConflictingActions(apiDescriptions =&gt; apiDescriptions.First());
44106
})
45-
.EnableSwaggerUi();
107+
.EnableSwaggerUi(c =>
108+
{
109+
c.InjectJavaScript(Assembly.GetAssembly(typeof(AbpProjectNameWebApiModule)), "AbpCompanyName.AbpProjectName.Api.Scripts.Swagger-Custom.js");
110+
});
46111
}</strong>
47112
}
48113
</pre>
49-
<p>See it's own
114+
<p>Notice that, we inject a javascript file named "<strong>Swagger-Custom.js</strong>" while configuring swagger ui. This script file is used to add CSRF token to requests while testing api services on swagger ui. You also need to add this file to your WebApi project and use it's Logical Name in InjectJavaScript method while injecting it. It's content is:</p>
115+
<pre lang="js">
116+
var getCookieValue = function(key) {
117+
var equalities = document.cookie.split('; ');
118+
for (var i = 0; i < equalities.length; i++) {
119+
if (!equalities[i]) {
120+
continue;
121+
}
122+
123+
var splitted = equalities[i].split('=');
124+
if (splitted.length !== 2) {
125+
continue;
126+
}
127+
128+
if (decodeURIComponent(splitted[0]) === key) {
129+
return decodeURIComponent(splitted[1] || '');
130+
}
131+
}
132+
133+
return null;
134+
};
135+
136+
var csrfCookie = getCookieValue("XSRF-TOKEN");
137+
var csrfCookieAuth = new SwaggerClient.ApiKeyAuthorization("X-XSRF-TOKEN", csrfCookie, "header");
138+
swaggerUi.api.clientAuthorizations.add("X-XSRF-TOKEN", csrfCookieAuth);
139+
</pre>
140+
<p></p>
141+
<p>See Swashbuckle
50142
<a href="https://github.com/domaindrivendev/Swashbuckle" target="_blank">
51143
documentation</a> for more configuration options.</p>
52144
<h4>Test</h4>

doc/WebSite/Validating-Data-Transfer-Objects.html

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,19 +96,24 @@ <h3 id="DocCustomValidation">Custom Validation</h3>
9696
[Required]
9797
public string Description { get; set; }
9898

99-
<strong> public void AddValidationErrors(List&lt;ValidationResult&gt; results)
99+
<strong> public void AddValidationErrors(CustomValidatationContext context)
100100
{
101101
if (SendEmailToAssignedPerson &amp;&amp; (!AssignedPersonId.HasValue || AssignedPersonId.Value &lt;= 0))
102102
{
103-
results.Add(new ValidationResult(&quot;AssignedPersonId must be set if SendEmailToAssignedPerson is true!&quot;));
103+
context.Results.Add(new ValidationResult(&quot;AssignedPersonId must be set if SendEmailToAssignedPerson is true!&quot;));
104104
}
105105
}</strong>
106106
}</pre>
107107
<p>ICustomValidate interface declares <strong>AddValidationErrors</strong>
108-
method to be implemented. Here, we have a <strong>SendEmailToAssignedPerson</strong> property. If it's
109-
true, <strong>AssignedPersonId</strong> should be supplied, else it can be null.
110-
We must add <strong>ValidationResult</strong> objects to <strong>results</strong> list if there are
111-
validation errors.</p>
108+
method to be implemented.
109+
We must add <strong>ValidationResult</strong> objects to <strong>context.Results</strong> list if there are
110+
validation errors. You can also use context.IocResolver to
111+
<a href="Dependency-Injection.html">resolve dependencies</a> if
112+
needed in validation progress.&nbsp;</p>
113+
<p>In addition to ICustomValidate, ABP also supports .NET's standard
114+
IValidatableObject interface. You can also implement it to perform
115+
additional custom validations. If you implement both interfaces,
116+
both of them will be called.</p>
112117
<h3>Disabling Validation</h3>
113118
<p>For automatically validated classes (see Introduction section),
114119
you can use these attributes to control validation:</p>

0 commit comments

Comments
 (0)