AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX Blogs
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 08.05.2008, 22:06   #1  
Blog bot is offline
Blog bot
Участник
 
25,617 / 848 (80) +++++++
Регистрация: 28.10.2006
axStart: InfoPath with default AIF web services
Источник: http://axstart.spaces.live.com/Blog/...C0A0!310.entry
==============


Introduction
When completed this session you have created an InfoPath form that can interact with a Microsoft Dynamics AX Web service. On the end of this document we will use Microsoft Visual Tools for Applications for automatically generate GuidID and Source Endpoint User ID. Also enhancements to the AxdClass will be made.
Create a web service in AX
  • Create the AOT query
  • Click New Query in the AOT menu and rename it to ProjHours
  • Drag the table ProjJournalTrans to the data source node of new Query
    Save the changes.
NOTE: If you want to update or delete records with AIF, turn the update property on
 
NOTE: only Tables with a unique primary index will work correctly in AIF when you want to find, delete or update the record.
 
Creating the related classes
  • Click Tools/Developers Tools/Wizards/AxdWizard
  • Click the 'Next' button and select the ProjHours Query
  • Click the 'Next' button.
  • Select CreateList and press the Next Button
  • Select Regenerate existing AxBC classes and press Generate Button.
    Click the 'Finish' button.
As you can see the generated code does not compile. You can remove the 2 non compiling methods.
Change class AxdProjHours method prepareForSave



This method is used for additional programming logic. In our casem we have to create a journal. We decide to make a journal for every week.
public boolean prepareForSave(AxdStack _axdStack,  str _dataSourceName)
{
    ProjJournalTable projJournalTable;
    JournalID       journalID;
    axProjJournalTrans    axProjJournalTrans;
    ;
    switch (classidget(_axdStack.top()))
    {
        case classnum(AxProjJournalTrans) :
            axProjJournalTrans = _axdStack.top();
            //InfoPath Demo create journal in case not exist
            journalID          = strfmt("Week %1",wkofyr(axProjJournalTrans.parmProjTransDate()));
            if(!ProjJournalTable::exist(journalID))
            {
                projJournalTable.initFromProjJournalName(ProjJournalName::Find("Hour"));
                projJournalTable.JournalId  = journalID;
                projJournalTable.insert();
            }
            axProjJournalTrans.parmJournalId(journalID);
            //InfoPath Demo create journal in case not exist
 
            return true;
 
        default :
            error(strfmt("@SYS88979",classId2Name(classidget(_axdStack.top()))));
            return false;
    }
    return false;
}
  Create the new Web service
  • Open Menu/Basic/Setup/Application Integration Framework/Action
  • Click the 'Scan and register' button.
  • Turn the Enabled and web Enabled option on for the createListProjHours Action
    Press  generate button
Turn directory browsing on in the IIS site of our web services. This makes it easier to investigate.

   Create a new Endpoint for the action with additional authorization.
  • Open Menu/Basic/Setup/Application Integration Framework/EndPoints
  • Create a new record
    • Endpoint ID = Hours
    • Local endpoint ID = DMO
    Select Tab page Constrains and turn option No Constraints On
  • Select Tab page Users and add user group Admin
  • Save the record
  • Click the 'Action policies' button.
  • Select the correct Action ID.
  • Set status to Enabled
  • Set Logging Mode to Log All
  • Click the 'Data Policies' button.
  • Click the 'Set' button.
  • Click the 'Enable all' menu.
    Don’t forget to set our new endpoint to active.
[FONT='Arial','sans-serif']
[/FONT]
  Create an InfoPath document


Open InfoPath 2007 on the VPC. Select design a Form Template. Select Web Service and press OK.

InfoPath will open a wizard that helps you to find and connect the right way to our AIF ProjHours Web Service. In our case we will Submit Data. The web service is located at http://dynamicsvm/DynamicsWebService/ProjHoursService.asmx.
InfoPath will show a list of operations that will submit data. We can only select our creareListProjHours operation. We don’t change the name of this web service because it is still our main submit.
Designing the Form
Drag the fields to the form that you need. First we drag the DocumentContext node to the design. When dropping it into the design we select ‘Controls in Layout Table’


Next select the end of your document and press Insert/repeating Table.

Select the ProjJournalTrans record and press next.


Select the fields that are needed for the InfoPath dialog and press Finish

Finally give the CurrencyID a default value EUR , by double clicking on the CurrencyID of the datasource and entering the value. Programming in InfoPath


We have the general design for our InfoPath dialog available, but we don’t have match intelligence. It would be better if we dynamical generate:
  • MessageID
  • Source Endpoint User
  • Source Endpoint
    Destination Endpoint
We can do this by using the Visual Studio Tools for Applications. Select Tools/Programming/Load event. InfoPath wants that you save first your InfoPath Form so we do that (call it ProjHours). Next a C# project is generated.
Go to the FormEvents_Loading method and add these lines of code:
public void FormEvents_Loading(object sender, LoadingEventArgs e)
        {
            string xmpPath = "/dfs:myFields/dfs:dataFields/tns:createListProjHours/tns:DocumentContext";
            XPathNavigator xmlGuid           = this.MainDataSource.CreateNavigator().SelectSingleNode(xmpPath +"/tns:MessageId", this.NamespaceManager);
            XPathNavigator xmlEndPointUser   = this.MainDataSource.CreateNavigator().SelectSingleNode(xmpPath +"/tns:SourceEndpointUser", this.NamespaceManager);
            XPathNavigator xmlSourceEndpoint = this.MainDataSource.CreateNavigator().SelectSingleNode(xmpPath + "/tns:SourceEndpoint", this.NamespaceManager);
            XPathNavigator xmlEndPoint       = this.MainDataSource.CreateNavigator().SelectSingleNode(xmpPath + "/tns:DestinationEndpoint", this.NamespaceManager);
 
            xmlGuid.SetValue(System.Guid.NewGuid().ToString());
            xmlEndPointUser.SetValue(System.Environment.UserDomainName + "\" + System.Environment.UserName);
            xmlSourceEndpoint.SetValue("Hours");
            xmlEndPoint.SetValue("dmo");
        }
 
Next Build (compile) your solution in Visual Studio. Close Visual Studio and do your first test in InfoPath by pressing the Preview button. And ……….. we get an error!


This error tells us that we are not allowed to check for the user and domain name. Think about secure x++ code you have to ask permission for it. So let’s ask for permission. Close the preview and go back to visual studio and add next line in the FormEvent_loading method
new EnvironmentPermission(PermissionState.Unrestricted).Assert();
 
Also add the library for this Class at top of your c# project
using System.Security.Permissions;
 
Now the code is ready for secure coding but our InfoPath Form is not trusted jet. To get our InfoPath trusted, do the next steps:
  • Select Tools/Form Options
  • Select Security and Trust
  • Deactivate automatically determine security level
  • Select full trust
    Select sign this Form and create a certificate (this is not mandatory as long you don’t publish this Form)
Preview your InfoPath form again and test the web service with next data
EmplID
RAV
ProjID
40010
CategoryID
Install
Qty
8
LinePropertyID
Charge
  Testing, debugging & fixing


If you submit your data and you get an error. The information of this error is a little bit incomplete. Detailed information about the error is available in AX. Look at the Form at Menu/Basic/Periodic/AIF/Exceptions.
NOTE AIF will skip fields when the property allowEditOnCeate is set to NO, without any warning
 
Good luck
for dowloading the solution:  Code + article in pdf format
What’s Next Next week we will redesign our InfoPath form so it can interact with AIF file inbound adapter.


In the final week we will introduce offline working and automatic synchronization and add lookup fields for selecting project, Employee etc.

Источник: http://axstart.spaces.live.com/Blog/...C0A0!310.entry
__________________
Расскажите о новых и интересных блогах по Microsoft Dynamics, напишите личное сообщение администратору.
Старый 15.05.2008, 02:27   #2  
Blog bot is offline
Blog bot
Участник
 
25,617 / 848 (80) +++++++
Регистрация: 28.10.2006
axStart: InfoPath with default AIF file inbound
Источник: http://axstart.spaces.live.com/Blog/...C0A0!322.entry
==============

Introduction


Last week we used an AX Web service in combination with InfoPath. The solution we build had still some limitations. This week we will create an InfoPath Document that post documents to the AIF inbound file adapter. There is no difference on user experience when he posts to a web service or the AIF File inbound adapter.
 Create a file inbound service in AX


We can reuse all Axapta code from the previous session, but I make some additional enhancement on them. Till now, the created ProjJournalTrans records where nicely, but if we look more closely on it; it’s not as beautiful as expected. A lot of fields where not set:
  • Cost Price
  • Sales Price
  • Taxgroep
  • Period
    Dimensions
Personally I also don’t like that the user had to set the LinePropertyID. So let’s improve the prepareForSave method. Our Interface can become match more cleaver and user friendly
public boolean prepareForSave(AxdStack _axdStack,  str _dataSourceName)
{
    //TODO: Remember to make code for validating fields that are added to the initMandatoryFieldsMap method
    //      that are not mandatory in the table
    ProjJournalTable projJournalTable;
    JournalID       journalID;
    axProjJournalTrans    axProjJournalTrans;
    ProjJournalTrans      projJournalTrans;
    ;
    switch (classidget(_axdStack.top()))
    {
        case classnum(AxProjJournalTrans) :
            axProjJournalTrans = _axdStack.top();
            journalID          = strfmt("Week %1",wkofyr(axProjJournalTrans.parmProjTransDate()));
            if(!ProjJournalTable::exist(journalID))
            {
                projJournalTable.initFromProjJournalName(ProjJournalName::Find("Hour"));
                projJournalTable.JournalId  = journalID;
                projJournalTable.insert();
            }
            axProjJournalTrans.projJournalTrans().initFromProjTable(ProjTable::find(projJournalTrans.ProjId));
            axProjJournalTrans.projJournalTrans().setTransDate();
            axProjJournalTrans.setFieldAsTouched(fieldnum(projJournalTrans,dimension));
            axProjJournalTrans.setFieldAsTouched(fieldnum(projJournalTrans,CostPrice));
            axProjJournalTrans.setFieldAsTouched(fieldnum(projJournalTrans,salesPrice));
            axProjJournalTrans.setFieldAsTouched(fieldnum(projJournalTrans,PeriodDate));
            axProjJournalTrans.setFieldAsTouched(fieldnum(projJournalTrans,TaxGroupId));
            axProjJournalTrans.setFieldAsTouched(fieldnum(projJournalTrans,TaxItemGroupId));
            axProjJournalTrans.setFieldAsTouched(fieldnum(projJournalTrans,CategoryId));
            axProjJournalTrans.setFieldAsTouched(fieldnum(projJournalTrans,TransDate));
            axProjJournalTrans.parmJournalId(journalID);
            //TODO Put validating code for ProjJournalTrans here
            return true;
 
        default :
            error(strfmt("@SYS88979",classId2Name(classidget(_axdStack.top()))));
            return false;
    }
    return false;
}

 
NOTE: Changes on table fields without using the ParmFIeldName method need an addition setFieldAsTouched call, otherwise the changes are lost.

  Create the new file inbound service


We will reuse the existing file Inbound adaptor of the Contoso VPC (c:\AIF\Inbound). The InfoPath document will post the xml messages in this map and AX AIF Batch will process them. It is also posible to process the messages with below x++ job.
static void AifReceiveSend(Args _args)
{
    ;
    // receive documents in inbound processing queue and process
    new AifGatewayReceiveService().run();
    new AifInboundProcessingService().run();
 
    // create documents in outbound processing queue and process
   // new AifOutboundProcessingService().run();
   // new AifGatewaySendService().run();
}

 
NOTE: Change class AifInboundProcessingService method run for debugging purpose. You have to replace the  runas(……) code with  AifInboundProcessingService::processRequest(message); After debugging your AIF inbound process can gets corrupted. In that case you have to clean up manually the table AifResourceLock & AifGatewayQueue

 
Before we can connect InfoPath to the file inbound adapter, we have to get all XSD information.
  • Select the createListProjHours Action Form of AX.
  • Press View schema button
    Press Save as button (use createListProjJours name).

Create an InfoPath document


Open InfoPath 2007 on the VPC. Select design a Form Template. Select XML or Schema and press OK.


InfoPath will open a wizard that helps you to find and connect the right way to the XSD of ProjHours. The main XSD is the message.XSD. Select this one from C:\Program Files\Microsoft Dynamics AX\Application\Share\Include

 
   
 
   
       
           
           
       
   
   
   
                 
           
           
           
           
           
           
       
   
 
   
       
           
       
   
 


 
  • browse for your createListProjHours.XDS that you saved from the action Form in AX
  • Press Next
    Press No for any additional data sources and press finished.


From this point we have an InfoPath form with data source that can do the job.

  Designing the Form
  • Drag the fields to the form that you need. First we drag the Header node to the design. When dropping it into the design we select ‘Controls in Layout Table’
  • Next select the end of your document and press Insert/repeating Table.
  • Select the ProjJournalTrans record and press next.
    Select the fields that are needed for the InfoPath dialog and press Finish

Our InfoPath design will looks like:

  Programming in InfoPath


We have the general design for our InfoPath dialog available, but we don’t have match intelligence. It would be better if we dynamical generate:
  • MessageID
  • Source Endpoint User
  • Source Endpoint
    Destination Endpoint
We can do this by using the Visual Studio Tools for Applications. Select Tools/Programming/Load event. InfoPath wants that you save first your InfoPath Form so we do that (call it ProjHoursFile). Next a C# project is generated.
Go to the FormEvents_Loading method and add these lines of code:
public void FormEvents_Loading(object sender, LoadingEventArgs e)
        {
            string guidID = System.Guid.NewGuid().ToString();
            XPathNavigator root = this.MainDataSource.CreateNavigator();
 
            root.SelectSingleNode("/ns1:Envelope/ns1:Header/ns1:MessageId", this.NamespaceManager).SetValue(guidID);
            root.SelectSingleNode("/ns1:Envelope/ns1:Header/ns1:SourceEndpointUser", this.NamespaceManager).SetValue(System.Environment.ExpandEnvironmentVariables("%userdomain%\%username%"));
            root.SelectSingleNode("/ns1:Envelope/ns1:Header/ns1:SourceEndpoint", this.NamespaceManager).SetValue("ProjHours");
            root.SelectSingleNode("/ns1:Envelope/ns1:Header/ns1:DestinationEndpoint", this.NamespaceManager).SetValue("DMO");
            root.SelectSingleNode("/ns1:Envelope/ns1:Header/ns1:Action", this.NamespaceManager).SetValue("createListProjHours");
        }

 
Next Build (compile) your solution in Visual Studio. Close Visual Studio and do your first test in InfoPath by pressing the Preview button. And ……….. we get an error!

This error tells us that we are not allowed to check for the user and domain name. Think about secure x++ code you have to ask permission for it. So let’s ask for permission. Close the preview and go back to visual studio and add next line in the FormEvent_loading method
new EnvironmentPermission(PermissionState.Unrestricted).Assert();

 
Also add the library for this Class at top of your c# project
using System.Security.Permissions;

 
Now the code is ready for secure coding but our InfoPath Form is not trusted jet. To get our InfoPath trusted, do the next steps:
  • Select Tools/Form Options
  • Select Security and Trust
  • Deactivate automatically determine security level
  • Select full trust
    Select sign this Form and create a certificate (this is not mandatory as long you don’t publish this Form)
Submit to the file inbound adapter of AX
  • Drag a button Control to the design of InfoPath.
  • Double click on this button.
  • Set the action to Submit.
  • Press Submit Options button.
    Configure the Submit options (select Perform custom action using code)
  • Press Edit Code button

 
public void FormEvents_Submit(object sender, SubmitEventArgs e)
    {
         try
        {
            string filepath = "\\Dynamicsvm\Inbound\";
            string file = System.Guid.NewGuid().ToString() + ".xml";
 
            XmlDocument soapXML = new XmlDocument();
            soapXML.Load(this.MainDataSource.CreateNavigator().ReadSubtree());
            XPathNavigator soapXMLnav = soapXML.CreateNavigator();
 
            new FileIOPermission(FileIOPermissionAccess.Write, filepath + file).Assert();
            soapXML.Save(filepath + file);
            e.CancelableArgs.Cancel = false;
        }
        catch (Exception)
        {
            MessageBox.Show("aif message is not stored");
        }
   }

 
Preview your InfoPath form again and test the web service with next data
EmplID
RAV
ProjID
40010
CategoryID
Install
Qty
8
LinePropertyID
Charge

 
Testing, debugging & fixing
If you submit your data and you get an error. The information of this error is a little bit incomplete. Detailed information about the error is available in AX. Look at the Form at Menu/Basic/Periodic/AIF/Exceptions.

Good luck
 
article in PDF format + code  download

What’s Next


Next week we will create lookups and make offline working possible.
 

Источник: http://axstart.spaces.live.com/Blog/...C0A0!322.entry
__________________
Расскажите о новых и интересных блогах по Microsoft Dynamics, напишите личное сообщение администратору.
Теги
aif, axbc, webservice

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
axStart: InfoPath with default AIF file inbound offline Blog bot DAX Blogs 0 20.05.2008 19:05
Dynamics AX: DAXGuy: Infopath, Web Services & AX Integration Blog bot DAX Blogs 0 08.05.2008 03:18
Arijit Basu: Infopath, Web Services & AX Integration Blog bot DAX Blogs 0 04.05.2008 23:05
Dianne Siebold: Update on the Dynamics AX SDK Team kashperuk DAX Blogs 1 16.10.2007 08:23
Pokluda: Outbound web service (AIF) Blog bot DAX Blogs 0 28.10.2006 17:43

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 20:14.