Skip to content

Commit

Permalink
Showing 31 changed files with 282 additions and 92 deletions.
2 changes: 1 addition & 1 deletion docs/Database-CodeGeneration-Config-Xml.md
Original file line number Diff line number Diff line change
@@ -45,7 +45,7 @@ Property | Description
-|-
`CdcSchema` | The schema name for the generated `CDC`-related database artefacts. Defaults to `Cdc` (literal).
`CdcAuditTableName` | The table name for the `Cdc`-Tracking. Defaults to `CdcTracking` (literal).
**`EventSubjectRoot`** | The root for the event name by prepending to all event subject names. Used to enable the sending of messages to the likes of EventHub, Service Broker, SignalR, etc. This can be overidden within the `Entity`(s).
**`EventSubjectRoot`** | The root for the event name by prepending to all event subject names. Used to enable the sending of messages to the likes of EventHub, Service Broker, SignalR, etc. This can be overridden within the `Entity`(s).
**`EventActionFormat`** | The formatting for the Action when an Event is published. Valid options are: `None`, `UpperCase`, `PastTense`, `PastTenseUpperCase`. Defaults to `None` (no formatting required).
`JsonSerializer` | The JSON Serializer to use for JSON property attribution. Valid options are: `None`, `Newtonsoft`. Defaults to `Newtonsoft`. This can be overridden within the `Entity`(s).
`PluralizeCollectionProperties` | Indicates whether the .NET collection properties should be pluralized.
2 changes: 1 addition & 1 deletion docs/Database-CodeGeneration-Config.md
Original file line number Diff line number Diff line change
@@ -45,7 +45,7 @@ Property | Description
-|-
`cdcSchema` | The schema name for the generated `CDC`-related database artefacts. Defaults to `Cdc` (literal).
`cdcAuditTableName` | The table name for the `Cdc`-Tracking. Defaults to `CdcTracking` (literal).
**`eventSubjectRoot`** | The root for the event name by prepending to all event subject names. Used to enable the sending of messages to the likes of EventHub, Service Broker, SignalR, etc. This can be overidden within the `Entity`(s).
**`eventSubjectRoot`** | The root for the event name by prepending to all event subject names. Used to enable the sending of messages to the likes of EventHub, Service Broker, SignalR, etc. This can be overridden within the `Entity`(s).
**`eventActionFormat`** | The formatting for the Action when an Event is published. Valid options are: `None`, `UpperCase`, `PastTense`, `PastTenseUpperCase`. Defaults to `None` (no formatting required).
`jsonSerializer` | The JSON Serializer to use for JSON property attribution. Valid options are: `None`, `Newtonsoft`. Defaults to `Newtonsoft`. This can be overridden within the `Entity`(s).
`pluralizeCollectionProperties` | Indicates whether the .NET collection properties should be pluralized.
7 changes: 4 additions & 3 deletions docs/Entity-CodeGeneration-Config-Xml.md
Original file line number Diff line number Diff line change
@@ -59,8 +59,9 @@ Provides the _Web API (Controller)_ configuration.

Property | Description
-|-
`WebApiAuthorize` | The authorize attribute value to be used for the corresponding entity Web API controller; generally `Authorize` (or `true`), otherwise `AllowAnonymous` (or `false`). Defaults to `AllowAnonymous`. This can be overidden within the `Entity`(s) and/or their corresponding `Operation`(s).
`WebApiAuthorize` | The authorize attribute value to be used for the corresponding entity Web API controller; generally `Authorize` (or `true`), otherwise `AllowAnonymous` (or `false`). Defaults to `AllowAnonymous`. This can be overridden within the `Entity`(s) and/or their corresponding `Operation`(s).
`AppBasedAgentArgs` | Indicates whether to create and use a domain-specific `WebApi.WebApiAgentArgs` to simplify dependency injection usage.
`WebApiAutoLocation` | Indicates whether the HTTP Response Location Header route (`Operation.WebApiLocation`) is automatically inferred. This will automatically set the `Operation.WebApiLocation` for an `Operation` named `Create` where there is a corresponding named `Get`. This can be overridden within the `Entity`(s).

<br/>

@@ -78,8 +79,8 @@ Provides the _Data Services-layer_ configuration.

Property | Description
-|-
**`EventPublish`** | Indicates whether to add logic to publish an event on the successful completion of the `DataSvc` layer invocation for a `Create`, `Update` or `Delete` operation. Defaults to `true`. Used to enable the sending of messages to the likes of EventHub, Service Broker, SignalR, etc. This can be overidden within the `Entity`(s).
**`EventSubjectRoot`** | The root for the event name by prepending to all event subject names. Used to enable the sending of messages to the likes of EventHub, Service Broker, SignalR, etc. This can be overidden within the `Entity`(s).
**`EventPublish`** | Indicates whether to add logic to publish an event on the successful completion of the `DataSvc` layer invocation for a `Create`, `Update` or `Delete` operation. Defaults to `true`. Used to enable the sending of messages to the likes of EventHub, Service Broker, SignalR, etc. This can be overridden within the `Entity`(s).
**`EventSubjectRoot`** | The root for the event name by prepending to all event subject names. Used to enable the sending of messages to the likes of EventHub, Service Broker, SignalR, etc. This can be overridden within the `Entity`(s).
**`EventActionFormat`** | The formatting for the Action when an Event is published. Valid options are: `None`, `UpperCase`, `PastTense`, `PastTenseUpperCase`. Defaults to `None` (no formatting required)`.
**`EventTransaction`** | Indicates whether a `System.TransactionScope` should be created and orchestrated at the `DataSvc`-layer whereever generating event publishing logic. Usage will force a rollback of any underlying data transaction (where the provider supports TransactionScope) on failure, such as an `EventPublish` error. This is by no means implying a Distributed Transaction (DTC) should be invoked; this is only intended for a single data source that supports a TransactionScope to guarantee reliable event publishing. Defaults to `false`. This essentially defaults the `Entity.EventTransaction` where not otherwise specified.

7 changes: 4 additions & 3 deletions docs/Entity-CodeGeneration-Config.md
Original file line number Diff line number Diff line change
@@ -72,8 +72,9 @@ Provides the _Web API (Controller)_ configuration.

Property | Description
-|-
`webApiAuthorize` | The authorize attribute value to be used for the corresponding entity Web API controller; generally either `Authorize` or `AllowAnonymous`. This can be overidden within the `Entity`(s) and/or their corresponding `Operation`(s).
`webApiAuthorize` | The authorize attribute value to be used for the corresponding entity Web API controller; generally either `Authorize` or `AllowAnonymous`. This can be overridden within the `Entity`(s) and/or their corresponding `Operation`(s).
`appBasedAgentArgs` | Indicates whether to create and use a domain-specific `WebApi.WebApiAgentArgs` to simplify dependency injection usage.
`webApiAutoLocation` | Indicates whether the HTTP Response Location Header route (`Operation.WebApiLocation`) is automatically inferred. This will automatically set the `Operation.WebApiLocation` for an `Operation` named `Create` where there is a corresponding named `Get`. This can be overridden within the `Entity`(s).

<br/>

@@ -91,8 +92,8 @@ Provides the _Data Services-layer_ configuration.

Property | Description
-|-
**`eventPublish`** | Indicates whether to add logic to publish an event on the successful completion of the `DataSvc` layer invocation for a `Create`, `Update` or `Delete` operation. Defaults to `true`. Used to enable the sending of messages to the likes of EventHub, Service Broker, SignalR, etc. This can be overidden within the `Entity`(s).
**`eventSubjectRoot`** | The root for the event name by prepending to all event subject names. Used to enable the sending of messages to the likes of EventHub, Service Broker, SignalR, etc. This can be overidden within the `Entity`(s).
**`eventPublish`** | Indicates whether to add logic to publish an event on the successful completion of the `DataSvc` layer invocation for a `Create`, `Update` or `Delete` operation. Defaults to `true`. Used to enable the sending of messages to the likes of EventHub, Service Broker, SignalR, etc. This can be overridden within the `Entity`(s).
**`eventSubjectRoot`** | The root for the event name by prepending to all event subject names. Used to enable the sending of messages to the likes of EventHub, Service Broker, SignalR, etc. This can be overridden within the `Entity`(s).
**`eventActionFormat`** | The formatting for the Action when an Event is published. Valid options are: `None`, `UpperCase`, `PastTense`, `PastTenseUpperCase`. Defaults to `None` (no formatting required)`.
**`eventTransaction`** | Indicates whether a `System.TransactionScope` should be created and orchestrated at the `DataSvc`-layer whereever generating event publishing logic. Usage will force a rollback of any underlying data transaction (where the provider supports TransactionScope) on failure, such as an `EventPublish` error. This is by no means implying a Distributed Transaction (DTC) should be invoked; this is only intended for a single data source that supports a TransactionScope to guarantee reliable event publishing. Defaults to `false`. This essentially defaults the `Entity.EventTransaction` where not otherwise specified.

1 change: 1 addition & 0 deletions docs/Entity-Entity-Config-Xml.md
Original file line number Diff line number Diff line change
@@ -119,6 +119,7 @@ Property | Description
`WebApiAuthorize` | The authorize attribute value to be used for the corresponding entity Web API controller; generally `Authorize` (or `true`), otherwise `AllowAnonymous` (or `false`). Defaults to the `CodeGeneration.WebApiAuthorize` configuration property (inherits) where not specified; can be overridden at the `Operation` level also.
`WebApiCtor` | The access modifier for the generated Web API `Controller` constructor. Valid options are: `Public`, `Private`, `Protected`. Defaults to `Public`.
**`WebApiCtorParams`** | The comma seperated list of additional (non-inferred) Dependency Injection (DI) parameters for the generated `WebApi` constructor. Each constructor parameter should be formatted as `Type` + `^` + `Name`; e.g. `IConfiguration^Config`. Where the `Name` portion is not specified it will be inferred. Where the `Type` matches an already inferred value it will be ignored.
`WebApiAutoLocation` | Indicates whether the HTTP Response Location Header route (`Operation.WebApiLocation`) is automatically inferred. This will automatically set the `Operation.WebApiLocation` for an `Operation` named `Create` where there is a corresponding named `Get`. This is defaulted from the `CodeGen.WebApiAutoLocation`.

<br/>

1 change: 1 addition & 0 deletions docs/Entity-Entity-Config.md
Original file line number Diff line number Diff line change
@@ -137,6 +137,7 @@ Property | Description
**`webApiAuthorize`** | The authorize attribute value to be used for the corresponding entity Web API controller; generally either `Authorize` or `AllowAnonymous`. Defaults to the `CodeGeneration.WebApiAuthorize` configuration property (inherits) where not specified; can be overridden at the `Operation` level also.
`webApiCtor` | The access modifier for the generated Web API `Controller` constructor. Valid options are: `Public`, `Private`, `Protected`. Defaults to `Public`.
**`webApiCtorParams`** | The list of additional (non-inferred) Dependency Injection (DI) parameters for the generated `WebApi` constructor. Each constructor parameter should be formatted as `Type` + `^` + `Name`; e.g. `IConfiguration^Config`. Where the `Name` portion is not specified it will be inferred. Where the `Type` matches an already inferred value it will be ignored.
`webApiAutoLocation` | Indicates whether the HTTP Response Location Header route (`Operation.WebApiLocation`) is automatically inferred. This will automatically set the `Operation.WebApiLocation` for an `Operation` named `Create` where there is a corresponding named `Get`. This is defaulted from the `CodeGen.WebApiAutoLocation`.

<br/>

1 change: 1 addition & 0 deletions docs/Entity-Operation-Config-Xml.md
Original file line number Diff line number Diff line change
@@ -69,6 +69,7 @@ Property | Description
**`WebApiMethod`** | The HTTP Method for the operation. Valid options are: `HttpGet`, `HttpPost`, `HttpPut`, `HttpDelete`. The value defaults as follows: `HttpGet` for `Operation.Type` value `Get` or `GetColl`, `HttpPost` for `Operation.Type` value `Create` or `Custom`, `HttpPut` for `Operation.Type` value `Update`, and `HttpDelete` for `Operation.Type` value `Delete`. An `Operation.Type` value `Patch` can not be specified and will always default to `HttpPatch`.
`WebApiStatus` | The primary HTTP Status Code that will be returned for the operation where there is a non-`null` return value. Valid options are: `OK`, `Accepted`, `Created`, `NoContent`, `NotFound`. The value defaults as follows: `OK` for `Operation.Type` value `Get`, `GetColl`, `Update`, `Delete` or `Custom`, `Created` for `Operation.Type` value `Create`.
`WebApiAlternateStatus` | The primary HTTP Status Code that will be returned for the operation where there is a `null` return value. Valid options are: `OK`, `Accepted`, `Created`, `NoContent`, `NotFound`, `ThrowException`. The value defaults as follows: `NotFound` for `Operation.Type` value `Get`, `NoContent` for `Operation.Type` value `GetColl`, `Create`, `Update` or `Patch`; otherwise, `ThrowException` which will result in an `InvalidOperationException`.
`WebApiLocation` | The HTTP Response Location Header route. This uses similar formatting to the `WebApiRoute`. The response value is accessed using `r.` notation to access underlying properties; for example `{r.Id}` or `person/{r.Id}`. The `Entity.WebApiRoutePrefix` will be prepended automatically; however, to disable set the first character to `!`, e.g. `!person/{r.Id}`. The URI can be inferred from another `Operation` by using a lookup `^`; for example `^Get` indicates to infer from the named `Get` operation (where only `^` is specified this is shorthand for `^Get` as this is the most common value). The Location URI will ensure the first character is a `/` so it acts a 'relative URL absolute path'.
`PatchGetOperation` | The corresponding `Get` method name (in the `XxxManager`) where the `Operation.Type` is `Patch`. Defaults to `Get`. Specify either just the method name (e.g. `OperationName`) or, interface and method name (e.g. `IXxxManager.OperationName`) to be invoked where in a different `YyyManager.OperationName`.
`PatchUpdateOperation` | The corresponding `Update` method name (in the `XxxManager`) where the `Operation.Type` is `Patch`. Defaults to `Update`. Specify either just the method name (e.g. `OperationName`) or, interface and method name (e.g. `IXxxManager.OperationName`) to be invoked where in a different `YyyManager.OperationName`.

1 change: 1 addition & 0 deletions docs/Entity-Operation-Config.md
Original file line number Diff line number Diff line change
@@ -88,6 +88,7 @@ Property | Description
**`webApiMethod`** | The HTTP Method for the operation. Valid options are: `HttpGet`, `HttpPost`, `HttpPut`, `HttpDelete`. The value defaults as follows: `HttpGet` for `Operation.Type` value `Get` or `GetColl`, `HttpPost` for `Operation.Type` value `Create` or `Custom`, `HttpPut` for `Operation.Type` value `Update`, and `HttpDelete` for `Operation.Type` value `Delete`. An `Operation.Type` value `Patch` can not be specified and will always default to `HttpPatch`.
`webApiStatus` | The primary HTTP Status Code that will be returned for the operation where there is a non-`null` return value. Valid options are: `OK`, `Accepted`, `Created`, `NoContent`, `NotFound`. The value defaults as follows: `OK` for `Operation.Type` value `Get`, `GetColl`, `Update`, `Delete` or `Custom`, `Created` for `Operation.Type` value `Create`.
`webApiAlternateStatus` | The primary HTTP Status Code that will be returned for the operation where there is a `null` return value. Valid options are: `OK`, `Accepted`, `Created`, `NoContent`, `NotFound`, `ThrowException`. The value defaults as follows: `NotFound` for `Operation.Type` value `Get`, `NoContent` for `Operation.Type` value `GetColl`, `Create`, `Update` or `Patch`; otherwise, `ThrowException` which will result in an `InvalidOperationException`.
`webApiLocation` | The HTTP Response Location Header route. This uses similar formatting to the `WebApiRoute`. The response value is accessed using `r.` notation to access underlying properties; for example `{r.Id}` or `person/{r.Id}`. The `Entity.WebApiRoutePrefix` will be prepended automatically; however, to disable set the first character to `!`, e.g. `!person/{r.Id}`. The URI can be inferred from another `Operation` by using a lookup `^`; for example `^Get` indicates to infer from the named `Get` operation (where only `^` is specified this is shorthand for `^Get` as this is the most common value). The Location URI will ensure the first character is a `/` so it acts a 'relative URL absolute path'.
`patchGetOperation` | The corresponding `Get` method name (in the `XxxManager`) where the `Operation.Type` is `Patch`. Defaults to `Get`. Specify either just the method name (e.g. `OperationName`) or, interface and method name (e.g. `IXxxManager.OperationName`) to be invoked where in a different `YyyManager.OperationName`.
`patchUpdateOperation` | The corresponding `Update` method name (in the `XxxManager`) where the `Operation.Type` is `Patch`. Defaults to `Update`. Specify either just the method name (e.g. `OperationName`) or, interface and method name (e.g. `IXxxManager.OperationName`) to be invoked where in a different `YyyManager.OperationName`.

Original file line number Diff line number Diff line change
@@ -50,7 +50,7 @@ public PersonController(IPersonManager manager, IPersonManager personManager)
public IActionResult Create([FromBody] Person value)
{
return new WebApiPost<Person>(this, () => _manager.CreateAsync(WebApiActionBase.Value(value)),
operationType: OperationType.Create, statusCode: HttpStatusCode.Created, alternateStatusCode: null);
operationType: OperationType.Create, statusCode: HttpStatusCode.Created, alternateStatusCode: null, locationUri: (r) => new Uri($"/api/v1/persons/{r.Id}", UriKind.Relative));
}

/// <summary>
@@ -382,7 +382,7 @@ public IActionResult GetWithEf(Guid id)
public IActionResult CreateWithEf([FromBody] Person value)
{
return new WebApiPost<Person>(this, () => _manager.CreateWithEfAsync(WebApiActionBase.Value(value)),
operationType: OperationType.Create, statusCode: HttpStatusCode.Created, alternateStatusCode: null);
operationType: OperationType.Create, statusCode: HttpStatusCode.Created, alternateStatusCode: null, locationUri: (r) => new Uri($"/api/v1/persons/ef/{r.Id}", UriKind.Relative));
}

/// <summary>
Original file line number Diff line number Diff line change
@@ -61,7 +61,7 @@ public IActionResult Get(Guid id)
public IActionResult Create([FromBody] Robot value)
{
return new WebApiPost<Robot>(this, () => _manager.CreateAsync(WebApiActionBase.Value(value)),
operationType: OperationType.Create, statusCode: HttpStatusCode.Created, alternateStatusCode: null);
operationType: OperationType.Create, statusCode: HttpStatusCode.Created, alternateStatusCode: null, locationUri: (r) => new Uri($"/api/v1/robots/{r.Id}", UriKind.Relative));
}

/// <summary>
6 changes: 3 additions & 3 deletions samples/Demo/Beef.Demo.CodeGen/Beef.Demo.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<CodeGeneration RefDataNamespace="Beef.Demo.Common.Entities" Grpc="true" ValidatorLayer="Business" MapperDefaultRefDataConverter="ReferenceDataCodeConverter" RefDataText="true" EventPublish="true" AppBasedAgentArgs="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://github.com/Avanade/Beef/raw/master/tools/Beef.CodeGen.Core/Schema/codegen.entity.xsd">
<Entity Name="Person" Text="Person" Implements="IETag, IChangeLog" Collection="true" CollectionResult="true" Grpc="true" Validator="PersonValidator" WebApiAuthorize="false" WebApiRoutePrefix="api/v1/persons" Create="true" Delete="true" AutoImplement="Database" DatabaseSchema="Demo" EntityFrameworkEntity="EfModel.Person" DataCtorParams="Microsoft.Extensions.Logging.ILogger&lt;PersonData&gt;^Logger, Common.Agents.IPersonAgent" ManagerExtensions="true" DataSvcExtensions="true" DataExtensions="true" EventTransaction="true" TestCodeGen="true" TestExtra="Unknown-Config">
<Entity Name="Person" Text="Person" Implements="IETag, IChangeLog" Collection="true" CollectionResult="true" Grpc="true" Validator="PersonValidator" WebApiAuthorize="false" WebApiRoutePrefix="api/v1/persons" WebApiAutoLocation="true" Create="true" Delete="true" AutoImplement="Database" DatabaseSchema="Demo" EntityFrameworkEntity="EfModel.Person" DataCtorParams="Microsoft.Extensions.Logging.ILogger&lt;PersonData&gt;^Logger, Common.Agents.IPersonAgent" ManagerExtensions="true" DataSvcExtensions="true" DataExtensions="true" EventTransaction="true" TestCodeGen="true" TestExtra="Unknown-Config">
<Property Name="Id" Text="{{Person}} identifier" Type="Guid" GrpcFieldNo="1" UniqueKey="true" IdentifierGenerator="IGuidIdentifierGenerator^GuidIdGen" DataName="PersonId" />
<Property Name="FirstName" Type="string" GrpcFieldNo="2" />
<Property Name="LastName" Type="string" GrpcFieldNo="3" />
@@ -64,7 +64,7 @@
<Operation Name="InvokeApiViaAgent" OperationType="Custom" ReturnType="string" UniqueKey="true" WebApiRoute="invokeApi" AutoImplement="None" />

<Operation Name="GetWithEf" OperationType="Get" UniqueKey="true" WebApiRoute="ef/{id}" AutoImplement="EntityFramework" />
<Operation Name="CreateWithEf" OperationType="Create" Validator="PersonValidator" WebApiRoute="ef" AutoImplement="EntityFramework" EventPublish="false" />
<Operation Name="CreateWithEf" OperationType="Create" Validator="PersonValidator" WebApiRoute="ef" WebApiLocation="^GetWithEf" AutoImplement="EntityFramework" EventPublish="false" />
<Operation Name="UpdateWithEf" OperationType="Update" Validator="PersonValidator" UniqueKey="true" WebApiRoute="ef/{id}" AutoImplement="EntityFramework" />
<Operation Name="DeleteWithEf" OperationType="Delete" UniqueKey="true" WebApiRoute="ef/{id}" AutoImplement="EntityFramework" EventSubject="Demo.Person.{id}" />
<Operation Name="PatchWithEf" OperationType="Patch" Validator="PersonValidator" UniqueKey="true" WebApiRoute="ef/{id}" AutoImplement="EntityFramework" />
@@ -129,7 +129,7 @@
<Property Name="ChangeLog" Type="ChangeLog" IsEntity="true" GrpcFieldNo="7" />

<Operation Name="Get" OperationType="Get" UniqueKey="true" WebApiRoute="{id}" Grpc="true" />
<Operation Name="Create" OperationType="Create" WebApiRoute="" Grpc="true" />
<Operation Name="Create" OperationType="Create" WebApiRoute="" WebApiLocation="^Get" Grpc="true" />
<Operation Name="Update" OperationType="Update" UniqueKey="true" WebApiRoute="{id}" Grpc="true" />
<Operation Name="Patch" OperationType="Patch" UniqueKey="true" WebApiRoute="{id}" />
<Operation Name="Delete" OperationType="Delete" UniqueKey="true" WebApiRoute="{id}" Grpc="true" />
Original file line number Diff line number Diff line change
@@ -61,7 +61,7 @@ public IActionResult Get(Guid id)
public IActionResult Create([FromBody] Employee value)
{
return new WebApiPost<Employee>(this, () => _manager.CreateAsync(WebApiActionBase.Value(value)),
operationType: OperationType.Create, statusCode: HttpStatusCode.Created, alternateStatusCode: null);
operationType: OperationType.Create, statusCode: HttpStatusCode.Created, alternateStatusCode: null, locationUri: (r) => new Uri($"/api/v1/employees/{r.Id}", UriKind.Relative));
}

/// <summary>
Original file line number Diff line number Diff line change
@@ -76,7 +76,7 @@ public IActionResult GetByEmployeeId(Guid employeeId)
public IActionResult Create([FromBody] PerformanceReview value, Guid employeeId)
{
return new WebApiPost<PerformanceReview>(this, () => _manager.CreateAsync(WebApiActionBase.Value(value), employeeId),
operationType: OperationType.Create, statusCode: HttpStatusCode.Created, alternateStatusCode: null);
operationType: OperationType.Create, statusCode: HttpStatusCode.Created, alternateStatusCode: null, locationUri: (r) => new Uri($"/api/v1/reviews/{r.Id}", UriKind.Relative));
}

/// <summary>
3 changes: 2 additions & 1 deletion samples/My.Hr/My.Hr.CodeGen/Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -2,7 +2,8 @@
"profiles": {
"My.Hr.CodeGen": {
"commandName": "Project",
"commandLineArgs": "entity"
"commandLineArgs": "entity",
"workingDirectory": "C:\\Users\\eric.sibly\\source\\repos\\Avanade\\Beef\\samples\\My.Hr\\My.Hr.CodeGen"
}
}
}
2 changes: 1 addition & 1 deletion samples/My.Hr/My.Hr.CodeGen/entity.beef.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" ?>
<CodeGeneration RefDataNamespace="My.Hr.Common.Entities" RefDataText="true" EventSubjectRoot="My" EventActionFormat="PastTense" AppBasedAgentArgs="true" DatabaseSchema="Hr" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://github.com/Avanade/Beef/raw/master/tools/Beef.CodeGen.Core/Schema/codegen.entity.xsd">
<CodeGeneration RefDataNamespace="My.Hr.Common.Entities" RefDataText="true" EventSubjectRoot="My" EventActionFormat="PastTense" AppBasedAgentArgs="true" WebApiAutoLocation="true" DatabaseSchema="Hr" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://github.com/Avanade/Beef/raw/master/tools/Beef.CodeGen.Core/Schema/codegen.entity.xsd">
<!-- Creating an Employee base with only the subset of fields that we want returned from the GetByArgs.
- As we will be returning more than one we need the Collection and CollectionResult.
- Any Text with a handlebars '{{xxx}}' is a shortcut for .NET see comments; e.g. '<see cref="xxx"/>'.
2 changes: 1 addition & 1 deletion src/Beef.AspNetCore.WebApi/Beef.AspNetCore.WebApi.csproj
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<RootNamespace>Beef.AspNetCore.WebApi</RootNamespace>
<Version>4.1.6</Version>
<Version>4.1.7</Version>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Authors>Beef Developers</Authors>
<Company>Avanade</Company>
3 changes: 3 additions & 0 deletions src/Beef.AspNetCore.WebApi/ChangeLog.md
Original file line number Diff line number Diff line change
@@ -2,6 +2,9 @@

Represents the **NuGet** versions.

## v4.1.7
- *Enhancement:* Issue [116](https://github.com/Avanade/Beef/issues/116). Add capability to set the HTTP `Location` Header value.

## v4.1.6
- *Fixed:* Issue [114](https://github.com/Avanade/Beef/issues/114).

143 changes: 85 additions & 58 deletions src/Beef.AspNetCore.WebApi/WebApiActionBase.cs

Large diffs are not rendered by default.

16 changes: 16 additions & 0 deletions src/Beef.AspNetCore.WebApi/WebApiControllerHelper.cs
Original file line number Diff line number Diff line change
@@ -121,5 +121,21 @@ public static void SetMessages(HttpResponse response, MessageItemCollection mess
if (messages != null && messages.Count > 0)
response.Headers[WebApiConsts.MessagesHeaderName] = JsonConvert.SerializeObject(messages);
}

/// <summary>
/// Sets the <see cref="HttpResponse.Headers"/> <see cref="System.Net.Http.Headers.HttpResponseHeaders.Location"/> where the <paramref name="locationUri"/> has a value.
/// </summary>
/// <param name="response">The <see cref="HttpResponse"/> to update.</param>
/// <param name="locationUri">The <see cref="System.Net.Http.Headers.HttpResponseHeaders.Location"/> <see cref="Uri"/>.</param>
public static void SetLocation(HttpResponse response, Uri? locationUri)
{
if (response == null)
throw new ArgumentNullException(nameof(response));

if (locationUri == null)
return;

response.GetTypedHeaders().Location = locationUri;
}
}
}
2 changes: 1 addition & 1 deletion tools/Beef.CodeGen.Core/Beef.CodeGen.Core.csproj
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<RootNamespace>Beef.CodeGen</RootNamespace>
<Version>4.1.20</Version>
<Version>4.1.21</Version>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<ApplicationIcon />
<StartupObject />
3 changes: 3 additions & 0 deletions tools/Beef.CodeGen.Core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -2,6 +2,9 @@

Represents the **NuGet** versions.

## v4.1.21
- *Enhancement:* Issue [116](https://github.com/Avanade/Beef/issues/116). Add capability to set the HTTP `Location` Header value.

## v4.1.20
- *Enhancement:* Added `CdcConfig.IncludeColumnsOnDelete` to enable a list of `Column` names to be specified that should be included (in addition to the primary key) for a logical delete. Otherwise, the .NET property values will be cleared within the `CdcDataOrchestrator` as the data is technically non-existing.
- *Enhancement:* Added `ExcludeBackgroundService` to exclude the generation of the `XxxBackgroundService.cs` class.
2 changes: 1 addition & 1 deletion tools/Beef.CodeGen.Core/Config/Database/CodeGenConfig.cs
Original file line number Diff line number Diff line change
@@ -168,7 +168,7 @@ public class CodeGenConfig : ConfigBase<CodeGenConfig, CodeGenConfig>, IRootConf
/// </summary>
[JsonProperty("eventSubjectRoot", DefaultValueHandling = DefaultValueHandling.Ignore)]
[PropertySchema("CDC", Title = "The root for the event name by prepending to all event subject names.",
Description = "Used to enable the sending of messages to the likes of EventHub, Service Broker, SignalR, etc. This can be overidden within the `Entity`(s).", IsImportant = true)]
Description = "Used to enable the sending of messages to the likes of EventHub, Service Broker, SignalR, etc. This can be overridden within the `Entity`(s).", IsImportant = true)]
public string? EventSubjectRoot { get; set; }

/// <summary>
15 changes: 12 additions & 3 deletions tools/Beef.CodeGen.Core/Config/Entity/CodeGenConfig.cs
Original file line number Diff line number Diff line change
@@ -145,7 +145,7 @@ public class CodeGenConfig : ConfigBase<CodeGenConfig, CodeGenConfig>, IRootConf
/// </summary>
[JsonProperty("webApiAuthorize", DefaultValueHandling = DefaultValueHandling.Ignore)]
[PropertySchema("WebApi", Title = "The authorize attribute value to be used for the corresponding entity Web API controller; generally either `Authorize` or `AllowAnonymous`.",
Description = "This can be overidden within the `Entity`(s) and/or their corresponding `Operation`(s).")]
Description = "This can be overridden within the `Entity`(s) and/or their corresponding `Operation`(s).")]
public string? WebApiAuthorize { get; set; }

/// <summary>
@@ -155,6 +155,14 @@ public class CodeGenConfig : ConfigBase<CodeGenConfig, CodeGenConfig>, IRootConf
[PropertySchema("WebApi", Title = "Indicates whether to create and use a domain-specific `WebApi.WebApiAgentArgs` to simplify dependency injection usage.")]
public bool? AppBasedAgentArgs { get; set; }

/// <summary>
/// Indicates whether the HTTP Response Location Header route (`Operation.WebApiLocation`)` is automatically inferred.
/// </summary>
[JsonProperty("webApiAutoLocation", DefaultValueHandling = DefaultValueHandling.Ignore)]
[PropertySchema("WebApi", Title = "Indicates whether the HTTP Response Location Header route (`Operation.WebApiLocation`) is automatically inferred.",
Description = "This will automatically set the `Operation.WebApiLocation` for an `Operation` named `Create` where there is a corresponding named `Get`. This can be overridden within the `Entity`(s).")]
public bool? WebApiAutoLocation { get; set; }

#endregion

#region Manager
@@ -263,15 +271,15 @@ public class CodeGenConfig : ConfigBase<CodeGenConfig, CodeGenConfig>, IRootConf
/// </summary>
[JsonProperty("eventPublish", DefaultValueHandling = DefaultValueHandling.Ignore)]
[PropertySchema("DataSvc", Title = "Indicates whether to add logic to publish an event on the successful completion of the `DataSvc` layer invocation for a `Create`, `Update` or `Delete` operation.", IsImportant = true,
Description = "Defaults to `true`. Used to enable the sending of messages to the likes of EventHub, Service Broker, SignalR, etc. This can be overidden within the `Entity`(s).")]
Description = "Defaults to `true`. Used to enable the sending of messages to the likes of EventHub, Service Broker, SignalR, etc. This can be overridden within the `Entity`(s).")]
public bool? EventPublish { get; set; }

/// <summary>
/// Gets or sets the root for the event name by prepending to all event subject names.
/// </summary>
[JsonProperty("eventSubjectRoot", DefaultValueHandling = DefaultValueHandling.Ignore)]
[PropertySchema("DataSvc", Title = "The root for the event name by prepending to all event subject names.",
Description = "Used to enable the sending of messages to the likes of EventHub, Service Broker, SignalR, etc. This can be overidden within the `Entity`(s).", IsImportant = true)]
Description = "Used to enable the sending of messages to the likes of EventHub, Service Broker, SignalR, etc. This can be overridden within the `Entity`(s).", IsImportant = true)]
public string? EventSubjectRoot { get; set; }

/// <summary>
@@ -540,6 +548,7 @@ protected override void Prepare()
NamespaceBusiness = DefaultWhereNull(NamespaceBusiness, () => $"{NamespaceBase}.Business");
NamespaceApi = DefaultWhereNull(NamespaceApi, () => $"{NamespaceBase}.{ApiName}");

WebApiAutoLocation = DefaultWhereNull(WebApiAutoLocation, () => false);
RefDataCache = DefaultWhereNull(RefDataCache, () => "ReferenceDataCache");
ValidatorLayer = DefaultWhereNull(ValidatorLayer, () => "Business");
EventPublish = DefaultWhereNull(EventPublish, () => true);
26 changes: 26 additions & 0 deletions tools/Beef.CodeGen.Core/Config/Entity/EntityConfig.cs
Original file line number Diff line number Diff line change
@@ -657,6 +657,14 @@ public class EntityConfig : ConfigBase<CodeGenConfig, CodeGenConfig>
"Where the `Type` matches an already inferred value it will be ignored.")]
public List<string>? WebApiCtorParams { get; set; }

/// <summary>
/// Indicates whether the HTTP Response Location Header route (`Operation.WebApiLocation`)` is automatically inferred.
/// </summary>
[JsonProperty("webApiAutoLocation", DefaultValueHandling = DefaultValueHandling.Ignore)]
[PropertySchema("WebApi", Title = "Indicates whether the HTTP Response Location Header route (`Operation.WebApiLocation`) is automatically inferred.",
Description = "This will automatically set the `Operation.WebApiLocation` for an `Operation` named `Create` where there is a corresponding named `Get`. This is defaulted from the `CodeGen.WebApiAutoLocation`.")]
public bool? WebApiAutoLocation { get; set; }

#endregion

#region Model
@@ -1071,6 +1079,7 @@ protected override void Prepare()
ManagerCtor = DefaultWhereNull(ManagerCtor, () => "Public");
WebApiAuthorize = DefaultWhereNull(WebApiAuthorize, () => Parent!.WebApiAuthorize);
WebApiCtor = DefaultWhereNull(WebApiCtor, () => "Public");
WebApiAutoLocation = DefaultWhereNull(WebApiAutoLocation, () => Parent!.WebApiAutoLocation);
ExcludeEntity = DefaultWhereNull(ExcludeEntity, () => NoOption);
ExcludeIData = DefaultWhereNull(ExcludeIData, () => CompareValue(ExcludeAll, YesOption) ? YesOption : NoOption);
ExcludeData = DefaultWhereNull(ExcludeData, () => CompareValue(ExcludeAll, YesOption) ? YesOption : NoOption);
@@ -1214,6 +1223,23 @@ private void PrepareOperations()
{
operation.Prepare(Root!, this);
}

if (WebApiAutoLocation == true)
{
var co = Operations!.FirstOrDefault(x => x.Type == "Create" && x.Name == "Create");
if (co != null)
{
var go = Operations!.FirstOrDefault(x => x.Type == "Get" && x.Name == "Get");
if (go != null && co.WebApiLocation == null)
co.WebApiLocation = "^";
}
}

// Go back and do another pass.
foreach (var operation in Operations)
{
operation.PrepareAfter();
}
}

/// <summary>
69 changes: 69 additions & 0 deletions tools/Beef.CodeGen.Core/Config/Entity/OperationConfig.cs
Original file line number Diff line number Diff line change
@@ -309,6 +309,15 @@ public class OperationConfig : ConfigBase<CodeGenConfig, EntityConfig>
Description = "The value defaults as follows: `NotFound` for `Operation.Type` value `Get`, `NoContent` for `Operation.Type` value `GetColl`, `Create`, `Update` or `Patch`; otherwise, `ThrowException` which will result in an `InvalidOperationException`.")]
public string? WebApiAlternateStatus { get; set; }

/// <summary>
/// Gets or sets the HTTP Response Location Header route.
/// </summary>
[JsonProperty("webApiLocation", DefaultValueHandling = DefaultValueHandling.Ignore)]
[PropertySchema("WebApi", Title = "The HTTP Response Location Header route.",
Description = "This uses similar formatting to the `WebApiRoute`. The response value is accessed using `r.` notation to access underlying properties; for example `{r.Id}` or `person/{r.Id}`. The `Entity.WebApiRoutePrefix` will be prepended automatically; however, to disable set the first character to `!`, e.g. `!person/{r.Id}`. " +
"The URI can be inferred from another `Operation` by using a lookup `^`; for example `^Get` indicates to infer from the named `Get` operation (where only `^` is specified this is shorthand for `^Get` as this is the most common value). The Location URI will ensure the first character is a `/` so it acts a 'relative URL absolute path'.")]
public string? WebApiLocation { get; set; }

/// <summary>
/// Gets or sets the override for the corresponding `Get` method name (in the `XxxManager`) where the `Operation.Type` is `Patch`.
/// </summary>
@@ -897,5 +906,65 @@ private void PrepareData()

DataArgs.Prepare(Root!, this);
}

/// <summary>
/// Prepare after previous Prepare round.
/// </summary>
public void PrepareAfter()
{
RefactorApiLocation();
}

/// <summary>
/// Refactor the API location URI.
/// </summary>
private void RefactorApiLocation()
{
if (WebApiLocation == null)
return;

if (WebApiLocation.StartsWith('!'))
WebApiLocation = WebApiLocation[1..];
else
{
if (WebApiLocation.StartsWith('^'))
{
var name = WebApiLocation.Length == 1 ? "Get" : WebApiLocation[1..];
var op = Parent!.Operations.FirstOrDefault(x => x.Name == name);
if (op == null)
throw new CodeGenException(this, nameof(WebApiLocation), $"Attempt to lookup Operation '{name}' which does not exist.");

WebApiLocation = op.WebApiRoute;
var s = 0;
if (WebApiLocation != null)
{
while (true)
{
var i = WebApiLocation.IndexOf('{', s);
if (i < 0)
break;

var j = WebApiLocation.IndexOf('}', s);
if (j < 0 || j < i)
throw new CodeGenException(this, nameof(WebApiLocation), $"Operation '{name}' WebApiRoute '{op.WebApiRoute}' tokens are invalid.");

var arg = WebApiLocation.Substring(i, j - i + 1);
var p = op.Parameters.FirstOrDefault(x => x.ArgumentName == arg[1..^1]);
if (p == null)
throw new CodeGenException(this, nameof(WebApiLocation), $"Operation '{name}' WebApiRoute '{op.WebApiRoute}' references Parameter token '{arg}' that does not exist.");

WebApiLocation = WebApiLocation.Replace(arg, "{r." + p.Name + "}");
s = j + 1;
}
}
}

if (!string.IsNullOrEmpty(Parent!.WebApiRoutePrefix))
WebApiLocation = Parent!.WebApiRoutePrefix + "/" + WebApiLocation;
}

if (WebApiLocation.FirstOrDefault() != '/')
WebApiLocation = "/" + WebApiLocation;
}
}
}
2 changes: 1 addition & 1 deletion tools/Beef.CodeGen.Core/Config/XmlYamlTranslate.cs
Original file line number Diff line number Diff line change
@@ -145,7 +145,7 @@ internal static class XmlYamlTranslate
(ConfigType.Entity, ConfigurationEntity.CodeGen, "WebApiAuthorize", typeof(string), new PropertySchemaAttribute("WebApi")
{
Title = "The authorize attribute value to be used for the corresponding entity Web API controller; generally `Authorize` (or `true`), otherwise `AllowAnonymous` (or `false`).",
Description = "Defaults to `AllowAnonymous`. This can be overidden within the `Entity`(s) and/or their corresponding `Operation`(s)."
Description = "Defaults to `AllowAnonymous`. This can be overridden within the `Entity`(s) and/or their corresponding `Operation`(s)."
}),

(ConfigType.Entity, ConfigurationEntity.Entity, "ManagerCtorParams", typeof(string), new PropertySchemaAttribute("Manager")
21 changes: 18 additions & 3 deletions tools/Beef.CodeGen.Core/Schema/codegen.entity.xsd
Original file line number Diff line number Diff line change
@@ -652,6 +652,11 @@
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="WebApiLocation" use="optional" type="xs:string">
<xs:annotation>
<xs:documentation>The HTTP Response Location Header route. This uses similar formatting to the `WebApiRoute`. The response value is accessed using `r.` notation to access underlying properties; for example `{r.Id}` or `person/{r.Id}`. The `Entity.WebApiRoutePrefix` will be prepended automatically; however, to disable set the first character to `!`, e.g. `!person/{r.Id}`. The URI can be inferred from another `Operation` by using a lookup `^`; for example `^Get` indicates to infer from the named `Get` operation (where only `^` is specified this is shorthand for `^Get` as this is the most common value). The Location URI will ensure the first character is a `/` so it acts a 'relative URL absolute path'.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="PatchGetOperation" use="optional" type="xs:string">
<xs:annotation>
<xs:documentation>The corresponding `Get` method name (in the `XxxManager`) where the `Operation.Type` is `Patch`. Defaults to `Get`. Specify either just the method name (e.g. `OperationName`) or, interface and method name (e.g. `IXxxManager.OperationName`) to be invoked where in a different `YyyManager.OperationName`.</xs:documentation>
@@ -1177,6 +1182,11 @@
<xs:documentation>The comma seperated list of additional (non-inferred) Dependency Injection (DI) parameters for the generated `WebApi` constructor. Each constructor parameter should be formatted as `Type` + `^` + `Name`; e.g. `IConfiguration^Config`. Where the `Name` portion is not specified it will be inferred. Where the `Type` matches an already inferred value it will be ignored.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="WebApiAutoLocation" use="optional" type="xs:boolean">
<xs:annotation>
<xs:documentation>Indicates whether the HTTP Response Location Header route (`Operation.WebApiLocation`) is automatically inferred. This will automatically set the `Operation.WebApiLocation` for an `Operation` named `Create` where there is a corresponding named `Get`. This is defaulted from the `CodeGen.WebApiAutoLocation`.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="DataModel" use="optional" type="xs:boolean">
<xs:annotation>
<xs:documentation>Indicates whether a data `model` version of the entity should also be generated (output to `.\Business\Data\Model`). The model will be generated with `OmitEntityBase = true`. Any reference data properties will be defined using their `RefDataType` intrinsic `Type` versus their corresponding (actual) reference data `Type`.</xs:documentation>
@@ -1341,14 +1351,19 @@
</xs:attribute>
<xs:attribute name="WebApiAuthorize" use="optional" type="xs:string">
<xs:annotation>
<xs:documentation>The authorize attribute value to be used for the corresponding entity Web API controller; generally `Authorize` (or `true`), otherwise `AllowAnonymous` (or `false`). Defaults to `AllowAnonymous`. This can be overidden within the `Entity`(s) and/or their corresponding `Operation`(s).</xs:documentation>
<xs:documentation>The authorize attribute value to be used for the corresponding entity Web API controller; generally `Authorize` (or `true`), otherwise `AllowAnonymous` (or `false`). Defaults to `AllowAnonymous`. This can be overridden within the `Entity`(s) and/or their corresponding `Operation`(s).</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="AppBasedAgentArgs" use="optional" type="xs:boolean">
<xs:annotation>
<xs:documentation>Indicates whether to create and use a domain-specific `WebApi.WebApiAgentArgs` to simplify dependency injection usage.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="WebApiAutoLocation" use="optional" type="xs:boolean">
<xs:annotation>
<xs:documentation>Indicates whether the HTTP Response Location Header route (`Operation.WebApiLocation`) is automatically inferred. This will automatically set the `Operation.WebApiLocation` for an `Operation` named `Create` where there is a corresponding named `Get`. This can be overridden within the `Entity`(s).</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="ValidatorLayer" use="optional">
<xs:annotation>
<xs:documentation>The namespace for the Reference Data entities (adds as a c# `using` statement). Defaults to `Business`. A value of `Business` indicates that the Validators will be defined within the `Business` namespace/assembly; otherwise, defined within the `Common` namespace/assembly.</xs:documentation>
@@ -1426,12 +1441,12 @@
</xs:attribute>
<xs:attribute name="EventPublish" use="optional" type="xs:boolean">
<xs:annotation>
<xs:documentation>Indicates whether to add logic to publish an event on the successful completion of the `DataSvc` layer invocation for a `Create`, `Update` or `Delete` operation. Defaults to `true`. Used to enable the sending of messages to the likes of EventHub, Service Broker, SignalR, etc. This can be overidden within the `Entity`(s).</xs:documentation>
<xs:documentation>Indicates whether to add logic to publish an event on the successful completion of the `DataSvc` layer invocation for a `Create`, `Update` or `Delete` operation. Defaults to `true`. Used to enable the sending of messages to the likes of EventHub, Service Broker, SignalR, etc. This can be overridden within the `Entity`(s).</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="EventSubjectRoot" use="optional" type="xs:string">
<xs:annotation>
<xs:documentation>The root for the event name by prepending to all event subject names. Used to enable the sending of messages to the likes of EventHub, Service Broker, SignalR, etc. This can be overidden within the `Entity`(s).</xs:documentation>
<xs:documentation>The root for the event name by prepending to all event subject names. Used to enable the sending of messages to the likes of EventHub, Service Broker, SignalR, etc. This can be overridden within the `Entity`(s).</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="EventActionFormat" use="optional">
2 changes: 1 addition & 1 deletion tools/Beef.CodeGen.Core/Schema/codegen.table.xsd
Original file line number Diff line number Diff line change
@@ -950,7 +950,7 @@
</xs:attribute>
<xs:attribute name="EventSubjectRoot" use="optional" type="xs:string">
<xs:annotation>
<xs:documentation>The root for the event name by prepending to all event subject names. Used to enable the sending of messages to the likes of EventHub, Service Broker, SignalR, etc. This can be overidden within the `Entity`(s).</xs:documentation>
<xs:documentation>The root for the event name by prepending to all event subject names. Used to enable the sending of messages to the likes of EventHub, Service Broker, SignalR, etc. This can be overridden within the `Entity`(s).</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="EventActionFormat" use="optional">
2 changes: 1 addition & 1 deletion tools/Beef.CodeGen.Core/Schema/database.beef.json
Original file line number Diff line number Diff line change
@@ -85,7 +85,7 @@
"eventSubjectRoot": {
"type": "string",
"title": "The root for the event name by prepending to all event subject names.",
"description": "Used to enable the sending of messages to the likes of EventHub, Service Broker, SignalR, etc. This can be overidden within the `Entity`(s)."
"description": "Used to enable the sending of messages to the likes of EventHub, Service Broker, SignalR, etc. This can be overridden within the `Entity`(s)."
},
"eventActionFormat": {
"type": "string",
21 changes: 18 additions & 3 deletions tools/Beef.CodeGen.Core/Schema/entity.beef.json
Original file line number Diff line number Diff line change
@@ -84,12 +84,17 @@
"webApiAuthorize": {
"type": "string",
"title": "The authorize attribute value to be used for the corresponding entity Web API controller; generally either `Authorize` or `AllowAnonymous`.",
"description": "This can be overidden within the `Entity`(s) and/or their corresponding `Operation`(s)."
"description": "This can be overridden within the `Entity`(s) and/or their corresponding `Operation`(s)."
},
"appBasedAgentArgs": {
"type": "boolean",
"title": "Indicates whether to create and use a domain-specific `WebApi.WebApiAgentArgs` to simplify dependency injection usage."
},
"webApiAutoLocation": {
"type": "boolean",
"title": "Indicates whether the HTTP Response Location Header route (`Operation.WebApiLocation`) is automatically inferred.",
"description": "This will automatically set the `Operation.WebApiLocation` for an `Operation` named `Create` where there is a corresponding named `Get`. This can be overridden within the `Entity`(s)."
},
"validatorLayer": {
"type": "string",
"title": "The namespace for the Reference Data entities (adds as a c# `using` statement).",
@@ -159,12 +164,12 @@
"eventPublish": {
"type": "boolean",
"title": "Indicates whether to add logic to publish an event on the successful completion of the `DataSvc` layer invocation for a `Create`, `Update` or `Delete` operation.",
"description": "Defaults to `true`. Used to enable the sending of messages to the likes of EventHub, Service Broker, SignalR, etc. This can be overidden within the `Entity`(s)."
"description": "Defaults to `true`. Used to enable the sending of messages to the likes of EventHub, Service Broker, SignalR, etc. This can be overridden within the `Entity`(s)."
},
"eventSubjectRoot": {
"type": "string",
"title": "The root for the event name by prepending to all event subject names.",
"description": "Used to enable the sending of messages to the likes of EventHub, Service Broker, SignalR, etc. This can be overidden within the `Entity`(s)."
"description": "Used to enable the sending of messages to the likes of EventHub, Service Broker, SignalR, etc. This can be overridden within the `Entity`(s)."
},
"eventActionFormat": {
"type": "string",
@@ -640,6 +645,11 @@
}
]
},
"webApiAutoLocation": {
"type": "boolean",
"title": "Indicates whether the HTTP Response Location Header route (`Operation.WebApiLocation`) is automatically inferred.",
"description": "This will automatically set the `Operation.WebApiLocation` for an `Operation` named `Create` where there is a corresponding named `Get`. This is defaulted from the `CodeGen.WebApiAutoLocation`."
},
"dataModel": {
"type": "boolean",
"title": "Indicates whether a data `model` version of the entity should also be generated (output to `.\\Business\\Data\\Model`).",
@@ -1219,6 +1229,11 @@
"ThrowException"
]
},
"webApiLocation": {
"type": "string",
"title": "The HTTP Response Location Header route.",
"description": "This uses similar formatting to the `WebApiRoute`. The response value is accessed using `r.` notation to access underlying properties; for example `{r.Id}` or `person/{r.Id}`. The `Entity.WebApiRoutePrefix` will be prepended automatically; however, to disable set the first character to `!`, e.g. `!person/{r.Id}`. The URI can be inferred from another `Operation` by using a lookup `^`; for example `^Get` indicates to infer from the named `Get` operation (where only `^` is specified this is shorthand for `^Get` as this is the most common value). The Location URI will ensure the first character is a `/` so it acts a 'relative URL absolute path'."
},
"patchGetOperation": {
"type": "string",
"title": "The corresponding `Get` method name (in the `XxxManager`) where the `Operation.Type` is `Patch`.",
Original file line number Diff line number Diff line change
@@ -123,7 +123,7 @@ namespace {{Root.NamespaceApi}}.Controllers
{{#ifeq WebApiMethod 'HttpDelete'}}
return new WebApiDelete{{#if HasReturnValue}}<{{OperationReturnType}}>{{/if}}(this, () => _manager.{{Name}}Async({{#each Parameters}}{{#unless @first}}, {{/unless}}{{#if IsValueArg}}WebApiActionBase.Value({{ArgumentName}}){{else}}{{#if IsPagingArgs}}WebApiQueryString.CreatePagingArgs(this){{else}}{{ArgumentName}}{{/if}}{{/if}}{{/each}}),
{{/ifeq}}
operationType: OperationType.{{ManagerOperationType}}, statusCode: HttpStatusCode.{{WebApiStatus}}{{#if HasReturnValue}}, alternateStatusCode: {{#ifeq WebApiAlternateStatus 'ThrowException'}}null{{else}}HttpStatusCode.{{WebApiAlternateStatus}}{{/ifeq}}{{/if}});
operationType: OperationType.{{ManagerOperationType}}, statusCode: HttpStatusCode.{{WebApiStatus}}{{#if HasReturnValue}}, alternateStatusCode: {{#ifeq WebApiAlternateStatus 'ThrowException'}}null{{else}}HttpStatusCode.{{WebApiAlternateStatus}}{{/ifeq}}{{/if}}{{#ifval WebApiLocation}}, locationUri: ({{#if HasReturnValue}}r{{/if}}) => new Uri($"{{WebApiLocation}}", UriKind.Relative){{/ifval}});
}
{{/each}}
}

0 comments on commit d5a5daa

Please sign in to comment.