Kentico 11 Portal Page Template - how to set Page AsyncMode? - kentico

I have a custom webpart that is inside a Portal Page template. It needs to call an async web api method on a button click.
I know for an ASPX based template we would see the Page property like:
<%# Page Title="" Language="C#" ...... Async="true" %>
But I'm not sure if this is accessible using portal template.
If it's not possible and I have to create an ASPX template - is it possible for it to reference a portal based masterPage or would I have to pull that out into an aspx page too?
The reason I need this property set is support this code:
protected void btnProcessPayment_Click(object sender, EventArgs e)
{
Page.RegisterAsyncTask(new PageAsyncTask(ExecuteValidation));
}
private async Task ExecuteValidation()
{
I have found this to be a reliable implementation in web forms.

Although I am not sure that you can set a whole page as Async, there are other options here.
You could use Kentico's AsyncControl - this control is used throughout the admin interface for asynchronous processing
You could use Kentico's AsyncWorker - if for some reason you cannot
use the AsyncControl this can be a valid alternative

Async does not really stick well with whole webforms life cycle for controlls and callbacks can break the cycle, for example if a page is loaded. Running worker thread or AJAX calls are usually better option. Even AsyncControl is attaching to a thread at some point and leveraging it to do the job and changing its rendering based on that.
It could work as long as there are no other complex controls on the page. MVC will really help here, but that is beyond Kentico 11 and portal at this point.

Related

Can Custom Action Buttons run javascript in handler? Sharepoint add-in

I created a Custom Action Ribbon button for sharepoint online and i want to run a javascript code when the button is clicked.
Sharepoint documentation even provides an example of it: https://learn.microsoft.com/en-us/sharepoint/dev/schema/commanduihandler-element?redirectedfrom=MSDN#example
but when i'm trying it always returns an error Custom action urls must start with "http:", "https:", "~appWebUrl" or "~remoteAppUrl".
Another part of the documentation says that it is not possible https://learn.microsoft.com/en-us/sharepoint/dev/sp-add-ins/sharepoint-add-ins-ux-design-guidelines?redirectedfrom=MSDN#figure-4-a-custom-action-in-the-contextual-menu
So how do i make it work? is not possible anymore and only can do redirections?
or it deppends of the location? i have it defined as <CommandUIDefinition Location="Ribbon.Documents.Actions.Controls._children"> so it is displayed in the command bar.
is it possible? ... I suppose no
Unfortunately it is not possible to add a custom ribbon action with a javascript logic with a provider hosted add-in πŸ€”. I think the articles/links where you found it is possible refer to the Server ribbon xml custom action that could be modified using sandbox solutions (like the old school SharePoint days 😊), but now the sandbox is rather not supported in SP online.
For the Ribbon custom actions that are added with the add-in you should specify the direct link. This is already what needs to be specified when we add a Ribbon action in VS to the Add-in project (we should specify were we navigate to)
I also found this MSDN article (quite up to date - from 2020) where we may find:
CustomAction cannot contain JavaScript: Any UrlActions or CommandActions must be a URL to navigate to. (...)
So I am like 95% sure it should πŸ˜‰ not be possible... but I leave the 5% as I am not like an SP PRO (I think it is hard to be one as it is like sooooo much to know πŸ˜‹)
possible solution you might take
What you might do is to add the custom Ribbion xml using PowerShell and attach any javascript logic to it also using PowerShell πŸ˜‹. The only drawback is that the javascript file needs to be also somehow added to the page (like it could be stored in the SiteAssets library).
So to do that we need to:
create an xml file locally with our Ribbon command button like:
<CommandUIExtension>
<CommandUIDefinitions>
<CommandUIDefinition Location="Ribbon.Library.ViewFormat.Controls._children">
<Button Id="Ribbon.Library.ViewFormat.About"
Command="TestButton"
LabelText="Test"
Image32by32="{SiteUrl}/_layouts/15/1033/Images/formatmap32x32.png?rev=23"
Image32by32Top="-273"
Image32by32Left="-1"
Description="Test"
TemplateAlias="o1" />
</CommandUIDefinition>
</CommandUIDefinitions>
<CommandUIHandlers>
<CommandUIHandler
Command="TestButton"
CommandAction="javascript:test({SelectedItemId});"
EnabledScript="javascript:checkOneItemSelected();" />
</CommandUIHandlers>
</CommandUIExtension>
the output of the above will be a button like this
Next create a js file (also locally) with functions for the CommandAction and EnabledScript (so we need a test() function and checkOneItemSelected()). So the contents like
function test(itemId) {
alert(itemId);
}
function checkOneItemSelected() {
return (SP.ListOperation.Selection.getSelectedItems().length == 1)
}
... so locally I have two files
Now we need to connect to the site we want to add the Ribbon button using PowerShell (best would be to use PnP Powershell πŸ‘)
connect to site using Connect-PnPOnline -Url <SiteUrl>
now lets add the JS local file to the site assets library like Add-PnPFile -Path .\customJS.js -Folder "SiteAssets"
so the output is (the file in the library)
now lets add the Ribbon button to the site (using xml) like
$ribbon = Get-Content .\CustomRibbonButton.xml
$ribbon = [string]$ribbon
Add-PnPCustomAction -Name "RibbonTester" -Title "RibbonTester" -Description "-" -Group "Tester" -Location "CommandUI.Ribbon" -CommandUIExtension $ribbon -RegistrationType ContentType -RegistrationId 0x0101
so the output of the above will be our button in the ribbon (also we need to turn on classic UI /off modern UI, to see the ribbon πŸ˜‰)
now lets attach our JS to the button like Add-PnPJavaScriptLink -Name "AboutButtonScript" -Url https://tenanttocheck.sharepoint.com/sites/ClassicDeveloperSite/SiteAssets/customJS.js -Scope Web please be aware the change url to your tenantπŸ˜‰
and the output is like
did you considerπŸ€”
Also did you consider to use spfx extensions and modern UI to be more up to date? In extensions you may use JS and maybe do some http request to some endpoint you want to target with the ids array (but this is only a suggestion)
hope my post will be of any help πŸ‘
BR

Azure AD B2C Customizing loading screen for Custom Policy

I'm creating a custom policy and I'm trying to customize the behavior when the policy is loading between different pages. Currently, the behavior is that the screen darkens and some text is displayed that overlaps with the rest of the UI. If possible, I'd like to display some completely different HTML content during loading. So far, I've been unable to affect the loading content in the same way that I've been able to affect the rest of the UI.
I have been able to see that a couple divs do appear during loading with IDs "simplemodal-overlap" and "simplemodal-container", and I've attempted to modify these divs using JQuery in the HTML file I've provided to Azure for the custom policy, but nothing I've done seems to have affected those divs in any way.
Has someone customized the loading UI for a custom policy before and can they give me advice on how I can affect its behavior?
Actually, the div with id: simplemodal-overlap is added/removed from HTML page by B2C dynamically:
So you can't capture it directly via JS code. If you just want to change its CSS display, you can just overwrite it on your custom page, on my side, I just use the code below to change its color to grey:
If you want to do more things on it by JS, you can add an event listener to monitor if a dom node with id simplemodal-overlap has been added into your html body. See code below:
<script>
$('body').on('DOMNodeInserted', function(e) {
if($(e.target).attr('id') == 'simplemodal-overlay'){
$(e.target).css({"background":"green","font-size":"100px"});
$(e.target).html("LOADING !!!!!")
}
});
</script>
Result:

Using the Existing Redirection to an External URL

How do you use redirection on Acumatica mobile xml or msdl to redirect to an external link?
All I could find is If an action on an Acumatica ERP form provides redirection to an external URL, you can map the action to use it in the mobile app. To do this, you need no additional attributes in the action object. However, the redirect attribute of the tag must be set to True, as shown in the following example.
Thanks
There may be other ways, but from the new T410 course for MSDL in 2018R2, you need to do a couple of steps. (Got this at Acumatica Summit 2018 Web Services course - Lesson 6 in the training guide which should be available soon if not already.)
First, define a new toolbar button on the form for your external link
(This example is for the SO303000 screen)
public PXAction<AR.ARInvoice> TestURL;
[PXButton(CommitChanges=true)]
[PXUIField(DisplayName = "TestURL")]
protected void testURL(){
throw new PXRedirectToUrlException(
"http://www.acumatica.com",
"Redirect:http://www.acumatica.com"
)
}
After publishing your project, go back to the Customization Project in the Mobile Application section to map the button. Add this to the commands section of the page as shown in the following example.
add container "InvoiceSummary" {
add field …
add recordAction "TestURL" {
behavior = Void
redirect = True
}
}
Not sure if this answered your question as you pretty much had the MSDL code listed, so maybe it is a matter of where you placed your code within the mobile definition? In the training class, we placed it inside the container where we wanted the link which then appears on the menu on the mobile app when viewing that container.

How can i check if user is logged in from the MVC5 Layout file

I have an MVC 5 Site, using a shared _Layout view.
In this _Layout view i render my scripts in the bottom part, after the body.
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/jqueryui")
#*BootStrap must be loaded after JQuery UI in order to override the tooltip function*#
#Scripts.Render("~/bundles/bootstrap")
#Scripts.Render("~/bundles/jqueryval")
#Scripts.Render("~/bundles/Session")
My Problem now, is that i want to include the Session Bundle in every page, except my Login pages.
In other words, i want to use the Session Bundle only for pages where the user is logged in and they have an active session.
How can i check for this condition in my _Layout View and render the Script Render conditionally?
In other pages, i would add a bool field to my Model and then use an C# If construction to only render the Script part if true, but i do not have a Model in my _Layout View.
I am also using custom, very simple login methods, so i am not using the Identity Framework of MVC5.
EDIT
I was suggested to use the Request object
#if (Request.IsAuthenticated) { #Render...}
This does not work since im using custom login, that does not work with the built in framework.
I read up on how this field works, here How does Request.IsAuthenticated work?
The problem is still unresolved
#if (Request.IsAuthenticated)
{
// Render stuff for authenticated user
}
I found an Answer.
access session variable from layout page ASP.NET MVC3 RAZOR
I am able to access the Session object from my Layout. Using that, i can check if my custom authentication object is null. If its not null, the user is logged in
#if (Session["BrugerSession"] != null)
{
#Scripts.Render("~/bundles/Session")
}

Calling Controller from aspx page

I have been trying to find a solution to my problem for 2 days now and I am really stuck. Here's the problem:
I have an MVC application (with Dependency injection and the works) with just one webform. This page needs to be a webform because it has a ReportViewer in it and please correct me if I am wrong but an MVC View is incompatible with server controls like ReportViewer. This is the navigation flow of the pages:
Home page navigates to the ReportList page
ReportList page displays the reports that a user is able to view and navigates to the Report page and passes it the ID of the report that the user selected.
Report page should look up the ReportPath and the ServerUrl from the database based on the ID passed from the ReportList page at the same time authorizing the user, whose permissions are stored in the database.
I could potentially pass the ReportPath and the ServerUrl as part of the query string so that the report page (aspx, not driven by a controller) does not have to go to the database to get these values. The problem however is how to check that the user is authorized to view the report (someone could just use a link to look at the report).
I did try to hook it into the MVC model and inherited the page from the ViewPage class. The problem there is that the page kept reloading itself for some reason. I still want my page to do as little as possible and a controller to handle calls to the authorization attribute and to the business layer. So, as a last resort, I want to call the controller from the aspx page but I can't create an object of it becasue dependency injection.
Can someone please provide some guidance on this? I have all the code available but don't know what to post.
I found out the answer and posting here if it helps anyone.
I added another class called ReportManager, which the aspx code behind calls to execute the requests. The ReportManager simulates the Controller call through this code:
var routeData = new RouteData();
routeData.Values["controller"] = "Report";
routeData.Values["action"] = "SomeAction";
routeData.Values["SomeRouteValueKey"] = "someroutevalue";
var requestContext = new RequestContext(new HttpContextWrapper(HttpContext.Current), routeData);
IController controller = DependencyResolver.Current.GetService<ReportController>();
controller.Execute(requestContext);

Resources