Philippsen's Blog

Everyday findings in my world of .net and related stuff

Archive for January, 2015

A call to SSPI failed–DynAx 2012 AIF/WCF

Posted by Torben M. Philippsen on January 13, 2015

Recently I deployed an AIF service to a customer environment. Everything was working fine in my single server development environment, but after deploy to the distributed customer environment, calls to the webservice resulted in the error “A call to sspi failed”.

The scenario:

  • My service – a simple document service. No hex about that.
  • I needed to deploy the service to IIS in order for it to be consumable from a corporate website
  • The customer environment contained a standalone server for the AOS and a standalone server for IIS
  • I created a simple test webform – my test client, in order to being able to test that everything was working ok.

Having deployed the service, the service was browsable. The identity of the application running the AIF site was the same as the one used for the Business connector proxy account (System administration –> setup –-> service accounts) The app pool was configured like this:

AppPoolConfig

Authentication was configured like this:

Authentication

Here’s a nice reference on how to install AIF on IIS when using Ax2012

From AX my service was configured to use a customBinding using NTLM and my clienct was also configured to use NTLM. Any call from the client to the service would result in the error “A call to SSPI failed – see inner exception…” – and no inner exception were to be found.

Trying to narrow down the problem a basicHTTPBinding was tried – still the same error.

As different kinds of blogposts suggested, I was able to call the AIF/WCF service when the service itself was using the ipaddress (to avoid the use of kerberos) of the aos server instead of the url. However this wasn’t an acceptable solution, as any new deployment of the service from AX, would result in a non working webservice, since the web.config would be overwritten when deploying from AX. And as it turned out, it was not possible to alter settings in AX forcing ax to deploy the service and having the endpoint in web.config reference the ip address instead af the FQDN. However the problem was now narrowed down to be caused by kerberos. I found this great blogpost explaining some basic things about Kerberos.

Another thing we tried out was to set the spn for the user running the service:

Setspn –A HTTP/2012webtest.myDomain.local myDomain\sa-proxy-lon

Having done that we tried to setup trust for delegation in AD according to this. We are not sure whether this had any effect, but we didn’t reverse the process.

This blogpost (see comment from Eric Ledoux and Brian Kinser) suggested that this might be caused by a kernel error. My customer recently upgraded to R2CU7 and I was expecting this to be fine, but talking with the technician from the customer revealed that IIS might not have been updated in that process with the new AX components. Running the setup file from the CU7 install media, suggested to update some core AX components. Choosing yes to update, restarting IIS and the AOS service, fault messages from ax started to show up when calling the webservice – meaning that everything was starting to work as expected.

Conclusion

In my case the “a call to sspi failed” error turned out to be resolved when upgrading to CU7. The problem I was facing was just caused by the fact that only the AOS had been upgraded – not IIS. Resolving this mismatch solved the problem.

Thanks to my colleague Morten Uldall for both moral and technical support:-)

Posted in AIF, Microsoft Dynamics AX | Tagged: , , , , | Comments Off on A call to SSPI failed–DynAx 2012 AIF/WCF

Display image from AX as embedded object in usercontrol

Posted by Torben M. Philippsen on January 9, 2015

Example of usercontrol markup:

<%@ Control Language=”C#” AutoEventWireup=”true” CodeFile=”DIVendInvoiceImage.ascx.cs” Inherits=”DIVendInvoiceImage” %>

<%@ Register Assembly=”Microsoft.Dynamics.Framework.Portal, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35″

    Namespace=”Microsoft.Dynamics.Framework.Portal.UI.WebControls.WebParts” TagPrefix=”dynamics” %>

<%@ Register Assembly=”Microsoft.Dynamics.Framework.Portal, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35″

    Namespace=”Microsoft.Dynamics.Framework.Portal.UI.WebControls” TagPrefix=”dynamics” %>

<%@ Register Assembly=”Microsoft.Dynamics.Framework.Data.Ax, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35″

    Namespace=”Microsoft.Dynamics.Framework.Data.Ax” TagPrefix=”dynamics” %>

<%@ Register Assembly=”Microsoft.Dynamics.Framework.Metadata.Ax, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35″

    Namespace=”Microsoft.Dynamics.Framework.Metadata.Ax” TagPrefix=”dynamics” %>

<%@ Register Assembly=”Microsoft.Dynamics.Framework.BusinessConnector, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35″

    Namespace=”Microsoft.Dynamics.Framework.BusinessConnector” TagPrefix=”dynamics” %>

<%@ Register Assembly=”Microsoft.Dynamics.Framework.BusinessConnector.Proxy, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35″

    Namespace=”Microsoft.Dynamics.Framework.BusinessConnector.Proxy” TagPrefix=”dynamics” %>   

<%@ Register Assembly=”Microsoft.Dynamics.Framework.Portal, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35″

    Namespace=”Microsoft.Dynamics.Framework.Portal.UI.WebControls.Workflow” TagPrefix=”dynamics” %>    

 

 <dynamics:AxDataSource ID=”DS_VendInvoiceImage” runat=”server”

    DataSetName=”DIVendInvoiceImage” ProviderView=”LedgerJournalTrans” />

 

<dynamics:AxMultiSection

    ID=”AxMultiSection1″ runat=”server”>

<dynamics:AxSection ID=”AxSection_Image” runat=”server” Caption=”Faktura”

        Expanded=”True” >

    <%=showImage() %> 

</dynamics:AxSection>

</dynamics:AxMultiSection>

Usercontrol codebehind

using System;

using System.Collections;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Web.UI.HtmlControls;

using System.Globalization;

using Microsoft.Dynamics.Framework.Portal;

using Microsoft.Dynamics.Framework.Portal.UI.WebControls;

using Microsoft.Dynamics.Framework.Portal.UI.WebControls.WebParts;

using Microsoft.Dynamics.Framework.Portal.UI.WebControls.Workflow;

using Microsoft.Dynamics.Framework.Portal.UI;

using Microsoft.Dynamics.Framework.Data.Ax;

using Microsoft.Dynamics.Framework.Metadata.Ax;

using Microsoft.Dynamics.Framework.BusinessConnector;

using Proxy = Microsoft.Dynamics.Framework.BusinessConnector.Proxy;

using ApplicationProxy = Microsoft.Dynamics.Portal.Application.Proxy;

using Microsoft.Dynamics.Framework.BusinessConnector.Session;

using Microsoft.Dynamics.Framework.BusinessConnector.Adapter;

using System.Collections.Generic;

using System.Diagnostics;

 

public partial class DIVendInvoiceImage : System.Web.UI.UserControl

{

    string imageHtml;

 

    protected string showImage()

    {

        return imageHtml;    

    }

    protected void Page_Load(object sender, EventArgs e)

    {

        AxBaseWebPart.GetWebpart(this).ExternalContextChanged += new EventHandler<AxExternalContextChangedEventArgs>(ExternalContextChanged);

       

    }

 

    void ExternalContextChanged(object sender, AxExternalContextChangedEventArgs e)

    {

        IAxaptaRecordAdapter currentRecord = AxBaseWebPart.GetWebpart(this).ExternalRecord;

        if (currentRecord != null)

        {

            imageHtml = (string)this.DS_VendInvoiceImage.GetDataSet().DataSetRun.AxaptaObjectAdapter.Call(“showImage”, (Int64)currentRecord.GetField(“RecId”), Convert.ToString(AxBaseWebPart.GetWebpart(this).Width), Convert.ToString(AxBaseWebPart.GetWebpart(this).Height));

 

        }

    }

 

}

 

ShowImage method on dataset (x++ code) – pushing differenet kinds of object tags

//Called from ASP.NET

str showImage(RecId _ledgerJournalTransRecId, str _widthZone = ‘450px’, str _heightZone = ‘600px’)
{
#Web
NAX_ScanImageTable      NAX_ScanImageTable;
str                     ret;
str                     url;
LedgerJournalTrans      ledgerJournalTransLocal = LedgerJournalTrans::findRecId(_ledgerJournalTransRecId, false);
EPWebsiteParameters     EPWebsiteParameters;
;

    _widthZone = ‘470px’; // tec, cts, 2011.01.20, Defect 229,335  width changed from 250px to 350px
_heightZone = ‘450px’;

    ret = ‘<P style=”TEXT-ALIGN: center”>’+’@VIA98’+'</p>’;
NAX_ScanImageTable = NAX_ScanImageTable::find(ledgerJournalTransLocal.naxImageId);
if (NAX_ScanImageTable.ScanImage)
{
select firstOnly EPWebsiteParameters;
url = EPWebsiteParameters.ExternalUrl+’/’+#resourcesRelDir+’/diimageaction.aspx?’;
url +=’table=’+int2str(NAX_ScanImageTable.tableId);
url +=’&field=’+int2str(fieldnum(NAX_ScanImageTable,ScanImage));
url +=’&recid=’+int642str(NAX_ScanImageTable.RecId);
//EG/2015.01.07/EGTOP, 00414358 Integration til Picasso –>
url += ‘&fileType=’+NAX_ScanImageTable.ImageFormat;
//EG/2015.01.07/EGTOP, 00414358 Integration til Picasso <–
//EG/2015.01.07/EGTOP, 00414358 Integration til Picasso –>
//do something to handle pdf file extension
if (NAX_ScanImageTable.ImageFormat == ‘pdf’)
{
ret = strfmt(‘http://%2‘, url, url);
}
else
{
//if not pdf do as usual – handle as tiff
//EG/2015.01.07/EGTOP, 00414358 Integration til Picasso <–
ret = strfmt(‘http://%2‘, url, url);

          //EG/2015.01.07/EGTOP, 00414358 Integration til Picasso –>
}
//EG/2015.01.07/EGTOP, 00414358 Integration til Picasso <–
}
else if(NAX_ScanImageTable.Text)
{
ret = ‘<DIV id=”bsplustxt”>’+NAX_ScanImageTable.Text+'</DIV>’;
}
return ret;
}

diimageCaption.aspx markup and code – setting the content type according to the memorystream content:

<%@ Page Language=”C#” Trace=”false” %>

<%@ Assembly Name=”Microsoft.Dynamics.BusinessConnectorNet, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, Custom=null” %>

<%@ Assembly Name=”Microsoft.Dynamics.Framework.Portal, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, Custom=null” %>

<%@ Assembly Name=”Microsoft.Dynamics.Framework.BusinessConnector, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, Custom=null” %>

<%@ Assembly Name=”Microsoft.Dynamics.Framework.BusinessConnector.Proxy, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, Custom=null” %>

<%@ Import Namespace=”Microsoft.Dynamics.BusinessConnectorNet” %>

<%@ Import Namespace=”Microsoft.Dynamics.Framework.Portal” %>

<%@ Import Namespace=”Microsoft.Dynamics.Framework.BusinessConnector.Proxy” %>

<%@ Import Namespace=”Microsoft.Dynamics.Framework.BusinessConnector.Session” %>

<%@ Import Namespace=”Microsoft.Dynamics.Framework.BusinessConnector.Adapter” %>

 

<script runat=”server”>

    void Page_Load(object sender, EventArgs e)

    {

        string table = this.Request.QueryString[“table”];

        string field = this.Request.QueryString[“field”];

        string recid = this.Request.QueryString[“recid”];

        //EG/2015.01.07/EGTOP, 00414358 Integration til Picasso –>

        string fileType = this.Request.QueryString[“fileType”];

        //EG/2015.01.07/EGTOP, 00414358 Integration til Picasso <–       

        if (recid != null && recid != String.Empty)

        {

            AxSharepointWebSession session = null;

            try

            {

                table = table == null ? String.Empty : table;

                field = field == null ? String.Empty : field;

 

                session = SessionHelper.Instance.GetSharepointSession();

 

                if (session != null)

                {

                    session.InitWeb(HttpContext.Current, Page.IsPostBack);

                    string base64 = (string)session.AxaptaAdapter.CallStaticClassMethod(“Webapplication”, “GetImage”,

                                    int.Parse(table), int.Parse(field), long.Parse(recid));

                    

                    byte[] bytes = Convert.FromBase64String(base64);                   

                    if (bytes != null && bytes.GetLength(0)>0)

                    {

                        //EG/2015.01.07/EGTOP, 00414358 Integration til Picasso –>

                        string contentType;

                        if (fileType.Equals(“pdf”))

                        {

                            contentType = “application/pdf”;

                        }

                        else

                        {

                            //EG/2015.01.07/EGTOP, 00414358 Integration til Picasso <–

                            contentType = “image/tiff”;

                            //EG/2015.01.07/EGTOP, 00414358 Integration til Picasso –>                           

                        }

                        //EG/2015.01.07/EGTOP, 00414358 Integration til Picasso <–

                        this.Response.ContentType = contentType;

                        this.Response.BinaryWrite(bytes);

                    }

                }

            }

            catch (System.Exception E)

            {

                System.Diagnostics.EventLog.WriteEntry(“EP”, string.Format(“Error {0}”, E.Message),System.Diagnostics.EventLogEntryType.Error, 3);

           

            }

            finally

            {

                if (session != null)

                {

                      SessionHelper.Instance.ReleaseSharepointSession(session);

                }

            }

        }

    }   

</script>

Posted in Enterprise Portal Development | Tagged: , , , | Comments Off on Display image from AX as embedded object in usercontrol

 
%d bloggers like this: