Select theme:
Custom business logic is key to most applications - call a third party API, execute complex database query or perform some calculation and return its result.
Radzen provides out-of-the-box support for such cases via the Invoke custom method action type.
Invoking custom methods is supported in Angular applications that have server-support enabled and target the .NET Core 2.0 framework.
All Radzen applications that have server-side support enabled contain a special file.
For C# applications it is server\Controllers\ServerMethodsController.cs
and for VB.NET it is server\Controllers\ServerMethodsController.vb
.
By default it contains just boiler-plate code and a sample custom method which is commented out.
Let's try invoking that sample method in Radzen and display its result.
Sum
method. Now you can invoke that method from Radzen.
Sum
method. x
and y
parameters of the Sum
method. Then
event of the invoke.${result.sum}
.${result.sum}
mean? The result
keyword is a placeholder which means "the result of the current custom method". Then sum
is the property which our custom method happens to use to return its result.
Now run the application to test the Sum
method.
Here is what happened:
Sum
method with parameters x=1
and y=2
by making a HTTP request. Sum
method returns the sum of its arguments in JSON format.Now let's pass the user input to the custom method. If you need a refreshment on getting user input in Radzen check the Properties help article.
x
and y
. They will store the user input and be the arguments of the Sum
method.x
and the second to y
.x
parameter to ${x}
and the y
parameter to ${y}
. This will use the values of the x
and y
properties as method arguments. Run the application to see it in action.
The previous examples used the sample custom method which doesn't do anything particularly useful. Let's do something real-life instead such as making a database query and returning its result. As usual we will use the Northwind database.
Let's make the method return the number of orders that ship to a user specified country.
server\Controllers\ServerMethodsController.cs
(or ServerMethodsController.vb
) file in your favorite text editor.[Route("api/[controller]/[action]")]
public class ServerMethodsController : Controller
{
private NorthwindContext northwind;
public ServerMethodsController(NorthwindContext context)
{
this.northwind = context;
}
}
<Route("api/[controller]/[action]")>
Public Class ServerMethodsController
Inherits Controller
Private northwind As Data.NorthwindContext
Public Sub New(ByVal context As Data.NorthwindContext)
Me.northwind = context
End Sub
End Class
public IActionResult OrdersByCountry(string country)
{
var orders = northwind.Orders.Where(o => o.ShipCountry == country);
return Json(new { count = orders.Count() });
}
Public Function OrdersByCountry(ByVal country As String) As IActionResult
Dim orders = northwind.Orders.Where(Function(o) o.ShipCountry = country)
Return Json(New With {
.count = orders.Count()
})
End Function
The UI will be simple:
Follow these steps:
country
and data-bind the TextBox to that property.
country
parameter to ${country}
.
Orders: ${result.count}
Run the application to try it:
Another common task is to display the result of a custom DB query in a DataGrid. We will use again the Northwind database and will display the number of orders per ShipCity in a DataGrid component.
Newtonsoft.Json
and Newtonsoft.Json.Serialization
namespaces.using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Serialization
public IActionResult OrdersByCity()
{
var orders = northwind.Orders.GroupBy(o => o.ShipCity)
.Select(group => new {
ShipCity = group.Key,
Count = group.Count()
});
// Using DefaultContractResolver to preserve the property
// name casing when serializing the result to JSON.
return Json(new { value = orders }, new JsonSerializerSettings() {
ContractResolver = new DefaultContractResolver()
});
}
Public Function OrdersByCity() As IActionResult
Dim orders = northwind.Orders.GroupBy(Function(o) o.ShipCity) _
.[Select](Function(group) New With {
.ShipCity = group.Key,
.Count = group.Count()
})
' Using DefaultContractResolver to preserve the property
' name casing when serializing the result to JSON.
Return Json(New With {
.value = orders
}, New JsonSerializerSettings() With {
.ContractResolver = New DefaultContractResolver()
})
End Function
ShipCity
(you have to type it in). Set Title to City
.Count
. Set Title to Orders
.OrdersByCity
method so we can use it with the DataGrid.${result.value}
.
${ordersByCity}
(click the gear icon to type that expression).
If you run the application you should see the following in your browser:
Another common task that is easily doable with custom methods is handling file uploads.
server\wwwroot
. The wwwroot
is a special directory - ASP.NET Core applications use it by default to serve static files.
This will allow you to serve any uploaded without extra effort.using System.Collections.Generic;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
Imports System.Collections.Generic
Imports Microsoft.AspNetCore.Hosting
Imports Microsoft.AspNetCore.Http
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Serialization
IHostingEnvironment
service in the constructor of the ServerMethodsController class. This service provide the file system location of the wwwroot
directory.private readonly IHostingEnvironment hostingEnvironment;
public ServerMethodsController(IHostingEnvironment hostingEnvironment)
{
this.hostingEnvironment = hostingEnvironment;
}
Private ReadOnly hostingEnvironment As IHostingEnvironment
Public Sub New(ByVal hostingEnvironment As IHostingEnvironment)
Me.hostingEnvironment = hostingEnvironment
End Sub
[HttpPost]
public IActionResult UploadFiles(IEnumerable<IFormFile> files)
{
var result = files.Select(file => {
// Save the files in the default static file directory - wwwroot
var path = Path.Combine(hostingEnvironment.WebRootPath, file.FileName);
using (var stream = new FileStream(path, FileMode.Create))
{
// Save the file
file.CopyTo(stream);
var request = HttpContext.Request;
// Create the URL for the uploaded file
var url = $"{request.Scheme}://{request.Host.Value}/{file.FileName}";
// Return the FileName and Url
return new {
FileName = file.FileName,
Url = url
};
}
}).ToList();
// Return the file names and URL of the uploaded files
return Json(new { value = result }, new JsonSerializerSettings() {
ContractResolver = new DefaultContractResolver()
});
}
<HttpPost>
Public Function UploadFiles(ByVal files As IEnumerable(Of IFormFile)) As IActionResult
Dim result = files.[Select](Function(file)
' Save the files in the default static file directory - wwwroot
Dim filePath = Path.Combine(hostingEnvironment.WebRootPath, file.FileName)
Using stream = New FileStream(filePath, FileMode.Create)
' Save the file
file.CopyTo(stream)
Dim request = HttpContext.Request
' Create the URL for the uploaded file
Dim url = $"{request.Scheme}://{request.Host.Value}/{file.FileName}"
Return New With {
.FileName = file.FileName,
.Url = url
}
End Using
End Function).ToList()
' Return the file names and URL of the uploaded files
Return Json(New With {
.value = result
}, New JsonSerializerSettings() With {
.ContractResolver = New DefaultContractResolver()
})
End Function
${event.files}
.
console.log(${result.value})
. This will log the result of the UploadFiles
method to the browser console. In your actual application you can use the result for other purposes - assign it to a property, display it in a DataGrid or other component etc.
If you run the application and upload a file you should see similar output in the browser console:
Add custom method to the partial class similar to previos chapter and invoke it when needed.
[Inject]
YourDbContext Context { get; set; }
public async Task<int> UspUpdateEmployeeHireInfos(int? someID, string someOtherParam)
{
SqlParameter[] @params =
{
new SqlParameter("@returnVal", SqlDbType.Int) {Direction = ParameterDirection.Output},
new SqlParameter("@someID", SqlDbType.Int) {Direction = ParameterDirection.Input, Value = someID},
new SqlParameter("@someOtherParam", SqlDbType.VarChar) {Direction = ParameterDirection.Input, Value = someOtherParam}
};
Context.Database.ExecuteSqlRaw("EXEC @returnVal=[YourSPSchema].[YourSP] @someID, @someOtherParam", @params);
int result = Convert.ToInt32(@params[0].Value);
return await Task.FromResult(result);
}
Radzen is free to use. You can also test the premium features for 15 days.
Download NowSelect theme: