Access to OTRS web services from .NET application

English! place to talk about development, programming and coding
Post Reply
Warlib
Znuny newbie
Posts: 20
Joined: 07 Jan 2015, 21:03
Znuny Version: 3.3.10
Real Name: Andrey
Company: Ridan

Access to OTRS web services from .NET application

Post by Warlib »

Hello,

I'm stuck with accessing to OTRS web services (via SOAP) from .NET application. I have OTRS installed over Apache/2.2.22 (Linux/SUSE) with Active Directory integration to authenticate users. I used WSDL файл from OTRS github to create needed classes to access OTRS web services. Then I create app.config (in attache app.txt) to connect to OTRS. A added small peace of test code:

Code: Select all

    public class Test : OTRS_WebService.GenericTicketConnector_InterfaceClient
    {

    }

class Program
    {
        static void Main(string[] args)
        {
            Test tst = new Test();
            OTRS_WebService.OTRS_SessionCreate sc = new OTRS_WebService.OTRS_SessionCreate();
            sc.ItemElementName = OTRS_WebService.ItemChoiceType8.UserLogin;
            sc.Item = "soap"; //Login to access SOAP
            sc.Password = "1234567"; //Password to access SOAP
            var rsp = tst.SessionCreate(sc);
}
}
After executing SessionCreate if clientCredentialType="Ntlm" then I got error:
Message: "The HTTP request is unauthorized with client authentication scheme 'Ntlm'. The authentication header received from the server was 'Negotiate'."
Inner exception: "The remote server returned an error: (401) Unauthorized."

If transport security is "Windows", then error message: "The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was 'Negotiate'."

In Fiddler i see, that application send:
POST http://server/otrs/nph-genericinterface ... tConnector HTTP/1.1
Content-Type: text/xml; charset=utf-8
VsDebuggerCausalityData: uIDPo2tfoPanyV1Jv/dArk4GAlYAAAAAor3hfiwdfUiXbw4v++F/XuOLDfsx8X1JjAnSfiTfksMACQAA
SOAPAction: "http://www.otrs.org/TicketConnector/SessionCreate"
Host: server
Content-Length: 369
Expect: 100-continue
Accept-Encoding: gzip, deflate
Connection: Keep-Alive

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Sess ... <UserLogin xmlns="http://www.otrs.org/TicketConnector/">s ... ><Password xmlns="http://www.otrs.org/TicketConnector/">1 ... s:Envelope>

Response is:
HTTP/1.1 302 Found
Date: Wed, 07 Jan 2015 18:26:59 GMT
Server: Apache/2.2.22 (Linux/SUSE)
Location: http://server/otrs/nph-genericinterface ... tConnector
Content-Length: 277
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>302 Found</title>
</head><body>
<h1>Found</h1>
<p>The document has moved <a href="http://server/otrs/nph-genericinterface ... re</a>.</p>
</body></html>

Then next request in Fiddler is:
GET http://server/otrs/nph-genericinterface ... tConnector HTTP/1.1
Content-Type: text/xml; charset=utf-8
VsDebuggerCausalityData: uIDPo2tfoPanyV1Jv/dArk4GAlYAAAAAor3hfiwdfUiXbw4v++F/XuOLDfsx8X1JjAnSfiTfksMACQAA
SOAPAction: "http://www.otrs.org/TicketConnector/SessionCreate"
Accept-Encoding: gzip, deflate
Host: server

and response:
HTTP/1.1 401 Authorization Required
Date: Wed, 07 Jan 2015 18:26:59 GMT
Server: Apache/2.2.22 (Linux/SUSE)
WWW-Authenticate: Negotiate
Vary: accept-language,accept-charset
Accept-Ranges: bytes
Content-Length: 589
Content-Type: text/html; charset=iso-8859-1
Content-Language: en
Proxy-Support: Session-Based-Authentication

<!--#set var="TITLE" value="Authentication required!"
--><!--#include virtual="include/top.html" -->

This server could not verify that you are authorized to access
the URL "<!--#echo encoding="url" var="REDIRECT_URL" -->".
You either supplied the wrong credentials (e.g., bad password), or your
browser doesn't understand how to supply the credentials required.

<!--#include virtual="include/spacer.html" -->

In case you are allowed to request the document, please
check your user-id and password and try again.

<!--#include virtual="include/bottom.html" -->

and that's all. :-( I tried to change app.config file in different ways, but there is no success.
You do not have the required permissions to view the files attached to this post.
Warlib
Znuny newbie
Posts: 20
Joined: 07 Jan 2015, 21:03
Znuny Version: 3.3.10
Real Name: Andrey
Company: Ridan

Re: Access to OTRS web services from .NET application

Post by Warlib »

I found one problem. When I request using address http://server/otrs/nph-genericinterface ... tConnector, the server was redirector to another address. So, when I changed in app.config endpoint address for direct adddress, the situation is getting better, I got another error:

Message=The content type application/soap+xml; charset=UTF-8 of the response message does not match the content type of the binding (text/xml; charset=utf-8). If using a custom encoder, be sure that the IsContentTypeSupported method is implemented properly. The first 514 bytes of the response were:

Code: Select all

'<?xml version="1.0" encoding="UTF-8"?><soap:Envelope soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soap:Body><SessionCreateResponse xmlns="http://www.otrs.org/TicketConnector/"><SessionID>akHCZ3gfyyS6rt1GOwAq4Yah7fg4E8KN</SessionID></SessionCreateResponse></soap:Body></soap:Envelope>'
.

So, I see that server response with right XML file with proper SessionID, but unfortunately .NET application couldn't recognize it as correct SOAP response and couldn't bind results to specified class.

I checked this error with different forums. One of the recommendation, that SOAP versions is differ, e.g. 1.2 and 1.1, but I don't know how to check this info.

In Fiddler request is (RAW):

Code: Select all

POST http://server/otrs/nph-genericinterface.pl/Webservice/GenericTicketConnector HTTP/1.1
Content-Type: text/xml; charset=utf-8
VsDebuggerCausalityData: uIDPo0lE6nZ19oREtxaCnEm4ZOEAAAAArdeqfPxwr0SkvVxygIu6ObiFPrmqzxZAncz8in079F8ACQAA
SOAPAction: "http://www.otrs.org/TicketConnector/SessionCreate"
Accept-Encoding: gzip, deflate
Authorization: Negotiate ...
Host: server
Content-Length: 369
Expect: 100-continue

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><SessionCreate><UserLogin xmlns="http://www.otrs.org/TicketConnector/">soap</UserLogin><Password xmlns="http://www.otrs.org/TicketConnector/">1234567</Password></SessionCreate></s:Body></s:Envelope>
In Fiddler response is (RAW):

Code: Select all

HTTP/1.1 200 OK
Content-Type: application/soap+xml; charset=UTF-8
Content-Length: 514
Connection: close

<?xml version="1.0" encoding="UTF-8"?><soap:Envelope soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soap:Body><SessionCreateResponse xmlns="http://www.otrs.org/TicketConnector/"><SessionID>r8ZiV2DbPJAqd6tYGOCxvS0GfuHPQYaU</SessionID></SessionCreateResponse></soap:Body></soap:Envelope>
Warlib
Znuny newbie
Posts: 20
Joined: 07 Jan 2015, 21:03
Znuny Version: 3.3.10
Real Name: Andrey
Company: Ridan

Re: Access to OTRS web services from .NET application

Post by Warlib »

I found the solution. OTRS used SOAP 1.2 version. basicHttpBinding support SOAP 1.1 version. So, right app.config when OTRS works on Apache with Windows authentication is:

Code: Select all

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
    </configSections>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
    <system.serviceModel>
        <bindings>
            <customBinding>
                <binding name="GenericTicketConnector_Service">
                    <textMessageEncoding messageVersion="Soap12" writeEncoding="utf-8" />
                    <httpTransport authenticationScheme="Negotiate" />
                </binding>
            </customBinding>
        </bindings>
        <client>
            <endpoint address="http://server/otrs/nph-genericinterface.pl/Webservice/GenericTicketConnector"
                binding="customBinding" bindingConfiguration="GenericTicketConnector_Service"
                contract="OTRS.GenericTicketConnector_Interface" name="GenericTicketConnector_endPoint" />
        </client>
    </system.serviceModel>
</configuration>
server - it's DIRECT url (wo redirection) to server where OTRS is hosted.

Unfortuately, in Fiddler i see SOAP response but in .NET application reponse is null. :-(
tzarot
Znuny newbie
Posts: 13
Joined: 20 Oct 2014, 20:08
Znuny Version: 3.3.9
Real Name: Themis Zarotiadis

Re: Access to OTRS web services from .NET application

Post by tzarot »

Many thanks to Warlib.

After reading your article I could also unlock my .NET connectivity problems. I had followed the approach of importing the .yml and .wsdl fies found in GitHub.

So after changing the default app.config file that was created to:

Code: Select all

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
  <system.serviceModel>
    <bindings>
      <customBinding>
        <binding name="GenericTicketConnector_Service">
          <textMessageEncoding messageVersion="Soap12" />
          <httpTransport />
        </binding>
      </customBinding>
    </bindings>
    <client>
      <endpoint address="http://<myserveraddress:myserverport>/otrs/nph-genericinterface.pl/Webservice/GenericTicketConnectorSOAP"
          binding="customBinding" bindingConfiguration="GenericTicketConnector_Service"
          contract="OtrsWS.GenericTicketConnector_Interface" name="GenericTicketConnector_endPoint" />
    </client>
  </system.serviceModel>
</configuration>
I was able to connect to the OTRS web service. Thanks again.
grunge
Znuny newbie
Posts: 5
Joined: 15 Jan 2014, 18:45
Znuny Version: 3.3.3
Real Name: Philipp Grunge

Re: Access to OTRS web services from .NET application

Post by grunge »

I did get it running, with the response.
-> i hope that an Error will come as Order 3 ????


What did you do:
1. WSDL from here:
https://raw.githubusercontent.com/OTRS/ ... rSOAP.wsdl
added to c# mvc project with "Add Service Reference"

2. changed web.config according to this forum: (can be app.config in your project)

Code: Select all

      
      <customBinding>
        <binding name="GenericTicketConnector_Service">
          <textMessageEncoding messageVersion="Soap12"/>
          <httpTransport />
        </binding>
      </customBinding>

Code: Select all

<endpoint address="http://YOURDOMAIN/otrs/nph-genericinterface.pl/Webservice/GenericTicketConnectorSOAP"
        binding="customBinding" bindingConfiguration="GenericTicketConnector_Service"
        contract="kszbugs.GenericTicketConnector_Interface" name="GenericTicketConnector_endPoint" />
3. changed Reference.cs

FROM

Code: Select all

[System.Xml.Serialization.XmlElementAttribute(DataType="positiveInteger", Order=0)]
        public string TicketID {
            get {
                return this.ticketIDField;
            }
            set {
                this.ticketIDField = value;
                this.RaisePropertyChanged("TicketID");
            }
        }
        
        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Order=1)]
        public string TicketNumber {
            get {
                return this.ticketNumberField;
            }
            set {
                this.ticketNumberField = value;
                this.RaisePropertyChanged("TicketNumber");
            }
        }
        
        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(DataType="positiveInteger", Order=2)]
TO

Code: Select all

        [System.Xml.Serialization.XmlElementAttribute(DataType="positiveInteger", Order=1)]
        public string TicketID {
            get {
                return this.ticketIDField;
            }
            set {
                this.ticketIDField = value;
                this.RaisePropertyChanged("TicketID");
            }
        }
        
        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Order=2)]
        public string TicketNumber {
            get {
                return this.ticketNumberField;
            }
            set {
                this.ticketNumberField = value;
                this.RaisePropertyChanged("TicketNumber");
            }
        }
        
        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(DataType="positiveInteger", Order=0)]
        public string ArticleID {
            get {
                return this.articleIDField;
            }
            set {
                this.articleIDField = value;
                this.RaisePropertyChanged("ArticleID");
            }
        }
Thanks everybody here for your posts
grunge
Znuny newbie
Posts: 5
Joined: 15 Jan 2014, 18:45
Znuny Version: 3.3.3
Real Name: Philipp Grunge

Re: Access to OTRS web services from .NET application

Post by grunge »

i would like to have email when a new ticket was created, how to i do this in otrs?

this is the code i use to create a ticket.
--> the wsdl is shit <--

bugdata is my model class.
User my principal.

Code: Select all

try
            {                
                // webservice
                var client = new GenericTicketConnector_InterfaceClient();
                
                //create article
                var theArticle = new OTRS_Article();
                theArticle.Subject = bugdata.subject;
                theArticle.Body = bugdata.message;
                theArticle.ItemElementName = ItemChoiceType2.ArticleType;
                theArticle.Item = "email-external";
                theArticle.Item1ElementName = Item1ChoiceType1.SenderType;
                theArticle.Item1 = "customer";
                theArticle.From = User.firstname + " " + User.lastname + "<" + User.mail + ">";
                theArticle.Items = new string[] { "text/plain; charset=utf8" };
                theArticle.ItemsElementName = new ItemsChoiceType[]{ItemsChoiceType.ContentType};

                //create ticket of ticket
                var theTicket = new OTRS_TicketCreate_Ticket();
                theTicket.Title = bugdata.subject;      //subject
                theTicket.CustomerUser = User.username; //username
                theTicket.ItemElementName = ItemChoiceType1.Queue; // departement as text
                theTicket.Item = bugdata.categorie.ToString();     // departement as text
                theTicket.Item4ElementName = Item4ChoiceType.State;//new
                theTicket.Item4 = "new";                           //new
                theTicket.Item5ElementName = Item5ChoiceType.PriorityID;
                theTicket.Item5 = "3"; //3 == normal
                theTicket.Item6ElementName = Item6ChoiceType.OwnerID;
                theTicket.Item6 = "1"; // admin                  
              
                //unlock
                //theTicket.Lock = "unlock"; //custom added attribut
                //not needed
                /*
                theTicket.Item3ElementName = Item3ChoiceType.SLAID;
                theTicket.Item3 = "0";//sla = service level agreement  
                theTicket.Item7ElementName = Item7ChoiceType.ResponsibleID;
                theTicket.Item7 = "1"; //why???                
                */

                //create ticket - insert atricle and ticket in ticket
                var ticketCreateRequest = new kszbugs.OTRS_TicketCreate
                {
                    Article = theArticle,    
                    Ticket = theTicket,
                    Item = ConfigurationManager.AppSettings.Get("otrsuser"),
                    ItemElementName = ItemChoiceType.UserLogin,
                    Password = ConfigurationManager.AppSettings.Get("otrspw")
                };

                //send request, receive response
                var sessionCreateResult = client.TicketCreate(ticketCreateRequest);

                //check Result?
                ViewBag.TicketNumber = sessionCreateResult.TicketNumber;
                
            }
            catch (Exception ex)
            {
                ViewBag.Error = "Ticket konnte nicht erzeugt werden. Fehler: " + ex.ToString();
            }

            return View();
Warlib
Znuny newbie
Posts: 20
Joined: 07 Jan 2015, 21:03
Znuny Version: 3.3.10
Real Name: Andrey
Company: Ridan

Re: Access to OTRS web services from .NET application

Post by Warlib »

grunge wrote:i would like to have email when a new ticket was created, how to i do this in otrs?

this is the code i use to create a ticket.
--> the wsdl is shit <--

bugdata is my model class.
User my principal.
As far as I know, there is no way to get events from OTRS. So, only one way - to use TicketSearch method and regualrly find messages which is newer than specified interval of check.

Code: Select all

                OTRS.ServiceReference.OTRS_TicketSearch ticketSearch = new OTRS.ServiceReference.OTRS_TicketSearch();
                ticketSearch.ItemElementName = ItemChoiceType6.SessionID;
                ticketSearch.Item = Session.SessionID;
                //tickets changed less than 120 minutes ago
                ticketSearch.TicketChangeTimeNewerMinutes = 5;
                string[] searchResult = OTRS.TicketSearch(ticketSearch);
wheels
Znuny newbie
Posts: 1
Joined: 16 Apr 2015, 13:18
Znuny Version: 3.3.12

Re: Access to OTRS web services from .NET application

Post by wheels »

So like the people above, i'm trying to access OTRS webservices but without much success.

Currently for development, I have installed 3.3.12 Windows version on my machine and created a webservice named GenericTicketConnectorSOAP. I followed the instructions described by the user "grunge" but it's not working. Currently here is my webconfig:

Code: Select all

<system.serviceModel>
    <bindings>
      <customBinding>
        <binding name="GenericTicketConnector_Service">
          <textMessageEncoding messageVersion="Soap12" />
          <httpTransport />
        </binding>
      </customBinding>
    </bindings>
    <client>
      <endpoint address="http://localhost/otrs/nph-genericinterface.pl/Webservice/GenericTicketConnectorSOAP"
        binding="customBinding" bindingConfiguration="GenericTicketConnector_Service"
        contract="OTRS.GenericTicketConnector_PortType" name="GenericTicketConnector_endPoint" />
    </client>
 </system.serviceModel>
The user also said that he changed the reference file but uy generated code was diferente from his so dont know if I can change it or not.

Anyway, the error I'm currently having is

Code: Select all

XmlSerializer attribute System.Xml.Serialization.XmlChoiceIdentifierAttribute is not valid in Item. Only XmlElement, XmlArray, XmlArrayItem, XmlAnyAttribute and XmlAnyElement attributes are supported when IsWrapped is true.
can anyone help me out? completly lost on what to do:(
grunge
Znuny newbie
Posts: 5
Joined: 15 Jan 2014, 18:45
Znuny Version: 3.3.3
Real Name: Philipp Grunge

Re: Access to OTRS web services from .NET application

Post by grunge »

Hello Again

Because we just updated OTRS to Version 5 and changed from http to HTTPS i had do do it again.

1. in VisualStudio, Project, add Service Reference from your URL like
https://YOUR-DOMAIN/GenericTicketConnectorSOAP.wsdl

2. go to files, find created Reference.cs
3. replace all entries
Namespace=""
with
Namespace="http://www.otrs.org/TicketConnector/"

4.change the response in Reference.cs - because the wsdl and the response aren't in the same order.

so under OTRS_TicketCreateResponse

TicketID gets Order=1
TicketNumber gets Order=2
ArticleID gets Order=0
Error gets Order=3

Thats it. But i'm not sure if the WSDL is there originaly or if i copied it there myself.
Greetings



Update, other change i made:
Because the Ticket is always locked, i add a field "Lock" to OTRS_TicketCreate_Ticket.
1. in Reference.cs go to
class OTRS_TicketCreate_Ticket

2. add member
lockField
(a added this as last member, after pendingtime)

3. add Attribut
[System.Xml.Serialization.XmlElementAttribute(Order = 20)]
public string Lock
{
get
{
return this.lockField;
}
set
{
this.lockField = value;
this.RaisePropertyChanged("Lock");
}
}

(also after Pending Time )

use is like
theTicket.Lock = "unlock";
Post Reply