Welcome to MSDN Blogs Sign in | Join | Help

Add all Role Centers to AX Client Favorites for demo purpose

Run this job in AX Client to add all oob role centers to your favorites section in AX Client for easy demo purpose. 

static void AddRoleCentersToFavorite(Args _args)
{
str sDefault ="Default";
SysProfiles uprofile;
MenuFunction mf;
TreeNode treeNode;
    TreeNodeIterator iterator;
    TreeNode newTreeNode;
    UserMenuList userMenu;
    Menu menuNode;
    #AOT
;

 treeNode = infolog.userNode();
    iterator = treeNode.AOTiterator();
    treeNode = iterator.next();
    if (treeNode)
    {
        userMenu = treeNode;

        // find 'My Favorites' user menu; if not found, create one
        treeNode = userMenu.AOTfindChild("@SYS95713");
        if (!treeNode)
        {
            userMenu.createMenu("@SYS95713");
            treeNode = userMenu.AOTfindChild("@SYS95713");
        }
        menuNode = treeNode;

while select ProfileId from uprofile
{

mf = new MenuFunction("DemoRoleCenter"+uprofile.ProfileId,MenuItemType::Action);
mf.AOTsetProperty("Label",uprofile.ProfileId);
mf.AOTsetProperty("ObjectType","Class");
mf.AOTsetProperty("Object","SwitchRoleCenter");
mf.AOTsetProperty("Parameters",uprofile.ProfileId);

mf.AOTsave();
menuNode.addMenuitem(mf);
menuNode.save();
}

mf = new MenuFunction("DemoRoleCenter"+sDefault,MenuItemType::Action);
mf.AOTsetProperty("Label",sDefault);
mf.AOTsetProperty("ObjectType","Class");
mf.AOTsetProperty("Object","SwitchRoleCenter");
mf.AOTsetProperty("Parameters",sDefault);

mf.AOTsave();
menuNode.addMenuitem(mf);
menuNode.save();


        infolog.navPane().refreshFavorites("@SYS95713");

    }
}

Posted by meysun | 2 Comments
Filed under:

How to set focus on the asp.net textbox in AxPopup form?

To set the focus include this method in your page that is opened in the popup window and call the method without control name in the page load event.

For example to set the focus on txtCustAccount

 

protected void Page_Load(object sender, EventArgs e)

    {

       

        SetFocus(txtCustAccount);

    }

 

public static void SetFocus(Control control)

    {

        StringBuilder sb = new StringBuilder();

 

        sb.Append("<script language='JavaScript'>");

        sb.Append("function SetFocus(){document.");

 

        Control p = control.Parent;

        while (!(p is System.Web.UI.HtmlControls.HtmlForm)) p = p.Parent;

 

        sb.Append(p.ClientID);

        sb.Append("['");

        sb.Append(control.UniqueID);

        sb.Append("'].focus();}");

       

        sb.Append("window.onload = SetFocus;</script>\r\n");

 

        control.Page.RegisterClientScriptBlock("SetFocus", sb.ToString());

    }

Posted by meysun | 0 Comments
Filed under:

AxPopup Controls in EP

AxPopup Controls

AxPopup controls are used to open a page in a popup browser window and upon closing a popup page, pass data from the popup page back to the parent page and trigger an OnPopupClosed server event on the parent. This functionality is encapsulated in two controls - AxPopupParentControl to be used in the parent page and AxPopupChildControl to be used on the popup page. They both derive from AxPopupBaseControl. These controls are AJAX-compatible, so they can be created conditionally as part of a partial update.

Data can be passed from the popup page back to the parent page using AxPopupField objects. They are exposed via the Fields property of the AxPopupBaseControl, from which both AxPopupParentControl and AxPopupChildControl are derived.

AxPopupParentControl and AxPopupChildControl have fields with the same names. When the popup page closes, the value of each field of the AxPopupChildControl is assigned (via client-side script) to the correspondent field in the AxPopupParentControl.

AxPopupField can optionally be associated with another control, such as TextBox or any other control, by assigning its TargetId property to the ID property of the target control. This is useful, for instance, when the popup page has a TextBox control. In order to pass the user input to the parent page upon closing the popup, and to do it entirely on the client hence avoiding the round trip, a field needs to be associated with the TextBox control.

In AX 2009 this approach is used in number of places and one such control is the Business Relations list.

The AxPopupField control is placed in the user control displaying the list. In the code behind, the toolbar action calls the popup using the GetOpenPopUpEventReference method. Both the parent control and the childcontrol uses the field with the same name hiddenCustomerAccountNo to pass the values back& forth. The childcontrol gets the value from the text box using the TargetControlID.

smmBusRelListGrid.ascx

List containing the ParentControl from the popup

<dynamics:AxPopupParentControl ID="PopupConvertCustomer" runat="server" PopupHeight ="180" PopupWidth="400"  >

    <dynamics:AxPopupField name="hiddenCustomerAccountNo"  />   

</dynamics:AxPopupParentControl>

smmBusRelListGrid.ascx.cs

Code behind opening up the popup using GetOpenPopUpEventReference

protected void AddCustomerAccountNoScript(SetMenuItemPropertiesEventArgs e, string custAccount)

    {

        AxUrlMenuItem menuItem = new AxUrlMenuItem(CUSTOMER_ACCOUNT_DIALOG);

        DataSetViewRow row = this.GetCurrentDataSetViewRow();

        if (row != null)

        {

            AxTableContext context = AxTableContext.Create

            (row.GetTableDataKey(row.DataSetView.Metadata.RootDataSource, null));

 

            menuItem.MenuItemContext = context;

 

            //Adding the CustAccount QueryString variable

            if (custAccount != string.Empty)

            {

                menuItem.ExtraParams.Add("CustAccount", custAccount);

            }

            menuItem.RemoveNavigation = true;

 

            //Calling the javascript function to set the properties of opening the customer account

            //on clicking the menu items.

            e.MenuItem.ClientOnClickScript = this.PopupConvertCustomer.GetOpenPopupEventReference(menuItem);

        }

    }

CustomerAccountDialog.ascx

The popup form  transferring  the value entered in the target  to the parent control by using the same control name.

<div>

    <br />

    <br />

    <table style="width: 100%">       

        <tr>

            <td class="PopoverFormText">

                <asp:Label ID="lblCustAccount" runat="server" Text="<%$ axlabel:@SYS7149 %>"></asp:Label>                       

            </td>

            <td class="PopoverFormText" >

                <asp:TextBox ID="txtCustAccount" runat="server" MaxLength="20" ></asp:TextBox>  

                <dynamics:AxPopupChildControl ID="popupChild" runat="server">

                    <dynamics:AxPopupField name="hiddenCustomerAccountNo" TargetControlId="txtCustAccount" />

                </dynamics:AxPopupChildControl>       

            </td>                   

        </tr>

        <tr><td colspan="3"><br /> <hr class="hr" />

            </td></tr>

        <tr>

            <td align="right" colspan="2">

            <asp:Button  id = "OkButton" CssClass="okCancelButton" runat ="server"  Text="<%$ axlabel:@SYS5473 %>" onclick="OkButton_Click" />

            <input id="CancelButton" class="okCancelButton" runat ="server" type="button" value="<%$ axlabel:@SYS50163 %>" onclick="window.close();" />

           

            </td>

            <td style="width: 10%"></td>

        </tr>

    </table>   

</div>

 

CustomerAccountDialog.ascx.cs

Pop up closed after validing the data entered in the popup , giving control back to the parent page.

//Used to validate the CustAccount no etered.

    protected void OkButton_Click(object sender, EventArgs e)

    {

        try

        {

            if (this.txtCustAccount.Text.Equals(string.Empty))

            {

                //Displaying error message: Account number is not specified

                DisplayInfolog(InfoType.Error, "@SYS24085");

                return;

            }

 

            //Validating the Customer Account no. entered

            if (!ApplicationProxy.SmmOpportunityStatusUpdate.checkCustomerAccount(this.AxSession.AxaptaAdapter, this.txtCustAccount.Text))

            {

                return;

            }

 

            //Calling the script for closing the dialogbox

            this.popupChild.ClosePopup(true, true);

        }

        catch (Exception ex)

        {

            AxExceptionCategory exceptionCategory;

            // This returns true if the exception can be handled here

            if (!AxControlExceptionHandler.TryHandleException(this, ex, out exceptionCategory))

            {

                // The exception was fatal - in this case we re-throw.

                throw;

            }

        }

    }

 

Posted by meysun | 0 Comments
Filed under:

Redirecting in EP user control to download a file

If you have a webpage to generate files such as word doc or pdf and you need to invoke them in a button click event of  an user control used in EP and allow the user to download the file through the browser. generally you would think of calling response.redirect function. This function  redirects to the download page and since it sets the mime type as the respective file, it prompts the user to save the file to the local machine or open it using the right application. Since AX usercontrols inherently  uses AJAX postbacks, the postback progressbar will continue to display "Loading Information" even after the file is downloaded when response.redirect is used. This is because response.redirect supposed to replace the current page displayed in the browser, but in this case it actually streams file and does not replace the currently rendered page in the browser. For such scenarios, instead of using response.redirect, you could execute a client side javascript to push the generated file in a new browser window and avoid the above issue.
 
protected void Button1_Click(object sender, EventArgs e)
    {
        AxUrlMenuItem menuItem = new AxUrlMenuItem("EPDocuGet");
        DataSetViewRow row = dsEPCustInvoiceJournalInfo.GetDataSet().DataSetViews[0].GetCurrent();
        AxTableContext context = AxTableContext.Create(row.GetDefaultTableDataKey(row.DataSetView.Metadata.RootDataSource));
        menuItem.MenuItemContext = context;
  
        //Response.Redirect(menuItem.Url.ToString());
 
        string downloadURL = "window.open('" + menuItem.Url.ToString() + "', '_blank', '' );";
        ScriptManager.RegisterStartupScript(this, typeof(string), "OPEN_WINDOW", downloadURL, true);
 
 
    }
 
Posted by meysun | 1 Comments
Filed under:

Persisting Filter conditions in EP Grid

Persisting Filter condition in EP Grid

In AX 2009, EP grid control comes with an advanced filter. Here is a code to persist the filter condition the user last entered in a page for that user, so that later when the user comes back to the same page the last filter is applied and user didn’t have to reenter then.

This code sample assumes a dataset with the name “EPSalesTableList” which contains the datasource “SalesTable”

 (1) First override the pack method of the dataset ( EPSalesTableList in this example) in AOT

public container pack()
{

container ret;
SysLastValue sysLastValue;

formdatasource filterDataSource;
;

filterDataSource = SalesTable_ds; // Put your datasource name

    ttsbegin;
       // Delete last saved query for the current dataset
    delete_from sysLastValue
        where sysLastValue.Company      == curext()
           && sysLastValue.UserId       == curuserid()
           && sysLastValue.RecordType   == UtilElementType::DataSet
           && sysLastValue.ElementName  == filterDataSource.name()
           && sysLastValue.DesignName   == filterDataSource.name();

    // If there is a new queryRun() object then serialize and save it
    // in the sys last value table
    // Put your datasource name
   
    if (filterDataSource.queryRun())
   {
   
        sysLastValue.RecId = 0;
        sysLastValue.Company      = curext();
        sysLastValue.UserId       = curuserid();
        sysLastValue.RecordType   = UtilElementType::DataSet;
        sysLastValue.ElementName  = filterDataSource.name();
        sysLastValue.DesignName   = filterDataSource.name();
        sysLastValue.value = SysQuery::packRangeAndSortorder(filterDataSource.queryRun().query());   
        sysLastValue.insert();
    }
    ttscommit;

 

    ret = super();

 

 

    return ret;

}

 

 

(2) Second override the init method of the datasource ( SalesTable in this example) within that dataset in AOT

public void init()
{
SysLastValue    sysLastValue;
    Query savedQuery;
    ;
    super();

// get the last value from the  sys last value table
    select firstonly sysLastValue
        where sysLastValue.Company      == curext()
           && sysLastValue.UserId       == curuserid()
           && sysLastValue.RecordType   == UtilElementType::DataSet
           && sysLastValue.ElementName  == this.name()
           && sysLastValue.DesignName   == this.name();

    if (sysLastValue && sysLastValue.Value)
    {
              // If there is an unpack error delete the saved query

       if (!SysQuery::unpackRangeAndSortorder(this.query(), sysLastValue.value))
        {

            ttsbegin;
            delete_from sysLastValue
                where sysLastValue.Company      == curext()
                   && sysLastValue.UserId       == curuserid()
                   && sysLastValue.RecordType   == UtilElementType::DataSet
                   && sysLastValue.ElementName  == this.name()
                   && sysLastValue.DesignName   == this.name();
            ttscommit;
        }

    }
               

 

 Make sure you replace the datasourcename variable filterDataSource in the pack method with your datasource name.Save the changes, refresh AOD and now go to the page that is using this dataset and enter some filter condition & apply. Close the browser and reopen the page. Now you should see that the filter that you last applied before the browser was closed is still applied in this page.

Arif Kureshy, who is the dev manager for EP came out with this code snippet. So thanks to him for providing this sample code.

 

Posted by meysun | 1 Comments
Filed under:

X++ based Web User Interface is discontinued in the next version of Microsoft Dynamics AX Enterprise Portal

During AX 2009, we introduced ASP.net based EP framework which brings in tons of value such AJAX out of the box, rich and responsive controls, power of .net etc. We kept the old X++ Web framework in the product for one release to help the partners and customers migrate to the new framework. Now we have published the discontinuation notice in customer source / partner source. In the next version of AX, only asp.net based web user interface will be shipped.

 https://mbs.microsoft.com/partnersource/newsevents/news/newsgeneral/ax_epuiframework.htm  

 https://mbs.microsoft.com/customersource/newsevents/news/generalnews/ax_epuiframework.htm    

 

Posted by meysun | 0 Comments
Filed under:

Screencast - How to set up Enterprise Portal (EP) in a Network Load Balancing (NLB) MOSS 2007 cluster

Anunay Kumar from the Enterprise Portal test team created a step-by-step guide on setting up SharePoint in NLB http://blogs.msdn.com/epblog/attachment/9727309.ashx and the screencast on setting up EP on such NLB web farm http://msdn.microsoft.com/en-us/dynamics/ax/ee384254.aspx. This screencast and more videos are available at "How do I" Videos - Dynamics AX section.

Thanks Anunay and we are excited to see that EP team members continue to add more content, videos and samples about Microsoft Dynamics AX 2009 EP.

Next we are targeting to create a similar Screencast about Perimeter setup / External facing Web site setup.

Posted by meysun | 2 Comments
Filed under:

Enterprise portal application functionality overview document

Jim Brotherton created this very useful document that describes the modules, features and business tasks that user perform in Enterprise Portal http://www.microsoft.com/downloads/details.aspx?FamilyID=0a0abfc4-964f-43ee-ad26-3d5d4c156269&displaylang=en. We have produced lots of good documentation for EP in AX 2009 and continue to look for ways to adding even more. If you have suggestions, please post a comment to this blog post with the topic name.

 

Posted by meysun | 0 Comments

Record Context

Steve Kubis from the UA team recented added the topic about Context in Enterprise Portal. It's talks about common context scenraios http://msdn.microsoft.com/en-us/library/ee330228.aspx and how the framework enables this without any code and an advanced topic on how to use it in code http://msdn.microsoft.com/en-us/library/ee330227.aspx. Thanks Steve
Posted by meysun | 0 Comments
Filed under:

Custom Bound Fields in FieldGroup

You could make the AxBoundFieldGroup use the CustomBoundField (http://blogs.msdn.com/solutions/archive/2009/04/20/ax-custom-bound-fields.aspx) instead of the regular bound field by hooking into the OnCreatingBoundField event (KB971547) of the  AxBoundFieldFactory.

 For example create an assembly with the below code and put it in GAC.

public class AxSampleBoundFieldFactory
{
 public
void OnCreatingBoundField(object sender, CreatingBoundFieldEventArgs eventArgs)
 {
   if (eventArgs.Field.Name == "Date")
     eventArgs.BoundField =
new AxSampleDateBoundField();
 }
}

Then modify the master page (C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES\DynamicsAxEnterprisePortal\defaultax.master) and add the below code to invoke this eventhandler in page init. Now any page that displays a fieldgroup will use the AxSampleDateBoundField for any field with the name "Date". You can add any logic that you want here for example you may want to use other field meta data properties instead of the name.


  private AxSampleBoundFieldFactory customBoundFieldFactory;
   
    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);

        // Subscribe to the bound field factory event
        this.customBoundFieldFactory = new AxSampleBoundFieldFactory();
        AxBoundFieldFactory.Instance.CreatingBoundField += this.customBoundFieldFactory.OnCreatingBoundField;
    }

    protected override void OnUnload(EventArgs e)
    {
        // Unsubscribe to the bound field factory event
        AxBoundFieldFactory.Instance.CreatingBoundField -= this.customBoundFieldFactory.OnCreatingBoundField;       
       
        base.OnUnload(e);
    }

Posted by meysun | 1 Comments
Filed under:

Inside Microsoft Dynamics AX 2009 book RTM'ed

Inside Microsoft Dynamics AX 2009 book RTM'ed

http://blogs.msdn.com/microsoft_press/archive/2009/05/20/rtm-d-today-inside-microsoft-dynamics-ax-2009.aspx

I wrote two chapters in Inside Dynamics AX 2009 book about Enterprise Portal and Role Centers. I also contributed to the Architecture Chapter and upgrade. Thanks to the entire EP team who implemented these great features and contributed in many ways to the content of these chapters. These chapters have wealth of info for developers and I would recommend strongly for EP / Role Center developers :) :) .

 

Posted by meysun | 5 Comments
Filed under: ,

Kerberos configuration for Clients accessing Role Center from outside of intranet

If you have EP/Role Centers rolled out in your intranet with Kerberos configured ( refer to Kerberos configuration document )  and now would like to expose this to your domain users outside of your corpnet, for example employee would access their role center from home, then you need to additionally configure Kerberos protocol configuration. You might have got enabled your firewall settings to allow them to access the EP and Reporting servers from outside network. Since the user comes outside of the network, IE will prompt them to enter the user account / password even though IIS authentication is set to windows integrated authentication. In this case, for Kerberos to work you need to configure protocol transition in Kerberos. To do that
1. Open up your “Active Directory Users and Computers” admin tool on your domain controller and locate the user account that you are using as business connector proxy and right click and open up its properties window.
2. Navigate to the “Delegation” tab and change the setting to “Trust this user for delegation to specified services only” and “User any authenticate protocol”.
3. Click the add button in the “Delegation” tab. It will bring up the “Add Services” dialog.
4. Click on the “Users or Computers” button. It will bring up the “Select Users or Computers” dialog.
5. Enter the account that is used as business proxy account ( This is the same account that the EP and report web site use as the application pool and the SSAS window service logon account).
6. Click “OK”. This will close the “Select Users or Computers” dialog and list the services (SPNs registered for Kerberos for the bc proxy account) in the “All Services” list of “Add Services: dialog.
7. Click “Select All” and then “OK” in “Add Services” dialog. This will close “ADD Services dialog” and list them in “Services to which this account can present delegated credentials” list in the “Delegation” tab.
8. Click “OK” to save this setting to the user account.
9. Do “IISReset” on the EP server



The alternate approach could be to use ISA 2006 as the firewall and let ISA collect the user account/password using a form over ssl and ISA will user Kerberos constrained delegation.
http://technet.microsoft.com/en-us/library/bb794858.aspx

Posted by meysun | 4 Comments
Filed under:

Move EP site from one machine to another

Microsoft Dynamics AX 2009 provides simple way to import your changes to pages into AOT and use the AX xpo mechanism to export/import the page/web control and other aot changes to the other machine and deploy them.

 But there amy be cases where you have heavily customized your SharePoint site not just the pages but the theme, added content , links, libraries etc and if you need to take a back of this customzied EP SharePoint site and restore it in another machine for testing, here are the steps

Let us say you are planning to move the site from MachineA to MachineB. In MachineA you have the site with the url http://MachineA/Sites/DynamicsAX and you want to create the same site in MachineB with the url http://MachineB/Sites/AX , then

(1) In Machine  A, open up a command prompt and navigate to C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN

(2) Execute the below command

stsadm -o backup -url http://MachineA/Sites/DynamicsAX -filename c:\axep.bak

(3) Copy c:\axep.bak from MachineA to MachineB to c:\

(4) Make sure the AOD files in MachineB are the same as in MachineA

(5) Make sure EP is deployed in MachineB. ( You don't need to create the EP Site, but EP must have been deployed)

(6) Open up AX Client in Machine B And navigate to Administration->Setup->Internet->Enterprise Portal->Web Sites and delete any site entry that may already be there with http://MachineB/Sites/Ax ( Since this is the site url that you are going to use to restore).

(7) In Machine  B, open up a command prompt and navigate to C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN

(8) Execute the below command

stsadm -o restore -url http://MachineB/Sites/AX -filename c:\axep.bak

(9) Open up AX Client in Machine B And navigate to Administration->Setup->Internet->Enterprise Portal->Web Sites and Click the "Register Site" button. This will add a new row to the Websites grid. Enter http://MachineB/Sites/Ax as the internal url and external url and Type as "Full". Click on the "General" tab and check the "Company independent" check box ( or uncheck it if you want this site to be specific to a particular company in AX) and save.

(10) Now navigate to http://MachineB/Sites/AX and this should have all the changes that you made in http://MachineA/Sites/DynamicsAX

 

Posted by meysun | 2 Comments

Passing parameters from Managed code to X++ in dataset

In the user control code behing add an event handler to the CreatingDataSetRun event on the AxDataSource control

protected void Page_Init(object sender, EventArgs e)
{
this.AxDataSource1.CreatingDataSetRun += new EventHandler<CreatingDataSetRunEventArgs>(AxDataSource1_CreatingDataSetRun);
}

Set the param value  to the event arugments

void AxDataSource1_CreatingDataSetRun(object sender, CreatingDataSetRunEventArgs e)

{

e.DataSetRunArgs.parm = "4000";

}

 

In AOT override or add method in the data set and use element.args().parm() to received the paramter  

public void executeQuery()
{

 QueryBuildRange             custRange;
 ;
        custRange = SysQuery::findOrCreateRange(this.query().dataSourceNo(1), fieldnum(CustTable, AccountNum));
        custRange.value(element.args().parm());
   super();

}

You can also pass an Enum. For example

void AxDataSource1_CreatingDataSetRun(object sender, CreatingDataSetRunEventArgs e)
{
e.DataSetRunArgs.parmEnumType =
EnumMetadata.EnumNum(this.AxSession, "EPFormAction");
e.DataSetRunArgs.parmEnum(2);
}

 

public void init()
{
    super();

     if (element.args().parmEnumType() == enumnum(EPFormAction) && element.args().parmEnum() == EPFormAction::CreateMode)
    {
        //do somethign here

    }
}

Posted by meysun | 1 Comments
Filed under:

Setting Up EP with host headers

Host headers are used either to provide a user-friendly name to the web site address ( and not expose the actual machine name of the web server) or to have multiple IIS websites running on the same port but distinguished by different names.

For example, you may have a machine with the name abcxyz but you want the website url to be http://contoso and not http://abcxyz or you want to have two websites running in port 80 one going to c:\inetpub\wwwroot\folder1 and another going to c:\inetpub\wwwroot\folder2. In these scenarios host headers are useful.

To install EP with host headers

(1)    Create an IIS Web site and configure host header http://support.microsoft.com/kb/190008

(2)    Create a web application in SharePoint Central Admin tool and choose existing IIS Website and pick the one that is created in the above step

(3)    Change to NTLM authentication for HTTPWebRequest in Version 3.5 SP1 http://msdn.microsoft.com/en-us/library/cc982052.aspx

(4)    Install EP and select the IIS Web site / SharePoint Web application created in step 2

Refer to the attached document for screenshots

Posted by meysun | 1 Comments
Filed under:

Attachment(s): Setting up EP with host headers.docx
More Posts Next page »
 
Page view tracker