Make requests to SOAP API

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
3
down vote

favorite
1












I would like feedback on this class library, mainly the architecture. It works very well. But maybe someone knows how to improve it.



This is a class library for working towards an external system. I reuse this class library in multiple solutions. The scope of this review is limited to "Retrieve the customer".



Since this is Xamarin I can't use the proxy class because it takes ages to load on a mobile device (related question here). Which is why I do the requests manually.



Project structure:



enter image description here



The main interface for the class library is the Facade class. It will call on the proper services to retrieve the data that the application requests.



public class Facade

WebRequester WebRequester get;

public Facade(string endpointUrl, string apiUser, string apiPassword)

WebRequester = new WebRequester(endpointUrl, apiUser, apiPassword);


/// <exception cref="SoapRequestException"></exception>
/// <exception cref="System.Net.WebException"></exception>
public Customer RetrieveCustomer(string customerId)

return new EntityService(WebRequester).RetrieveCustomer(customerId);




BaseService. The WebRequester is injected into the base service.



abstract class BaseService

protected WebRequester WebRequester get;

public BaseService(WebRequester webRequester)

WebRequester = webRequester;




Here's EntityService:



class EntityService : BaseService

public EntityService(WebRequester webRequester) : base(webRequester)



/// <exception cref="Exceptions.SoapRequestException">Thrown if the response has a Fault.</exception>
/// <exception cref="System.Net.WebException">Thrown if the request timed out.</exception>
IEnumerable<XElement> Query(string esql)

// Prepare request parameters.

var soapAction = "url-to-soap-action";
var method = "Query";
var parameters = new Dictionary<string, string>

"Esql", esql
;

// Call the service.

var result = WebRequester.Invoke(soapAction, method, parameters);
return result.Descendants(nsTf + "Data")?.FirstOrDefault()?.Elements(nsEm + "Record");


/// <exception cref="Exceptions.SoapRequestException"></exception>
/// <exception cref="System.Net.WebException"></exception>
public Customer RetrieveCustomer(string customerId)

var esql = $@"
select Id, Email, Name
from Customer
where Id = 'customerId'";

var row = Query(esql).FirstOrDefault();
var serializer = new XmlSerializer(typeof(Customer));
return serializer.Deserialize(row.CreateReader()) as Customer;




On the bottom is WebRequester. Couldn't find a better name. It makes the request to the external API and returns the SOAP response as an XDocument. Also checks for faults.



class WebRequester

string EndpointUrl get;
string ApiUser get;
string ApiPassword get;

public WebRequester(string endpointUrl, string apiUser, string apiPassword)

EndpointUrl = endpointUrl;
ApiUser = apiUser;
ApiPassword = apiPassword;


static string SessionId get; set;

/// <exception cref="SoapRequestException"></exception>
/// <exception cref="WebException"></exception>
string RetrieveSessionId() => new SecurityService(this).BeginSession(ApiUser, ApiPassword);

/// <exception cref="VerifyLoginFaultException"></exception>
/// <exception cref="SoapRequestException">Thrown if the SOAP response has a Fault.</exception>
/// <exception cref="WebException">Thrown if the request times out.</exception>
public XDocument Invoke(string soapAction, string method, Dictionary<string, string> parameters, bool requireSession = true)

if (requireSession && SessionId == null)

SessionId = RetrieveSessionId();


try

return Invoke(soapAction, method, parameters, SessionId);

catch (SessionRequiredException)

SessionId = RetrieveSessionId();
return Invoke(soapAction, method, parameters, true);



/// <exception cref="VerifyLoginFaultException"></exception>
/// <exception cref="SessionRequiredException"></exception>
/// <exception cref="SoapRequestException">Thrown if the SOAP response has a Fault.</exception>
/// <exception cref="WebException">Thrown if the request times out.</exception>
XDocument Invoke(string soapAction, string method, Dictionary<string, string> parameters, string sessionId)

// Create the web request

var request = WebRequest.Create(new Uri(EndpointUrl)) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/soap+xml; charset=utf-8; action="" + soapAction + """;
request.Timeout = 10000;

// Prepare the session value.

var session = string.Empty;
if (sessionId != null)

session =
$@"<soap:Header>
<ns1:Session>
<ns1:SessionId>sessionId</ns1:SessionId>
</ns1:Session>
</soap:Header>";


// Define which namespace to use for the request body.

string bodyNs;

if (method == "Query")
bodyNs = "ns1";
else
bodyNs = "ns2";

// Prepare the parameters.

var postValues = new StringBuilder();
foreach (var param in parameters)

postValues.AppendLine($"<bodyNs:param.Key>param.Value</bodyNs:param.Key>");


// Prepare the SOAP envelope.

string soapEnvelope =
$@"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope
xmlns:soap=""Constants.NsSoap""
xmlns:ns1=""Constants.NsBase""
xmlns:ns2=""Constants.Ns2008"">
session
<soap:Body>
<bodyNs:method>
postValues.ToString()
</bodyNs:method>
</soap:Body>
</soap:Envelope>";

// Create a byte array of the data we want to send.

byte byteData = Encoding.UTF8.GetBytes(soapEnvelope.ToString());

// Set the content length in the request headers.

request.ContentLength = byteData.Length;

// Write data to request.

using (var postStream = request.GetRequestStream())

postStream.Write(byteData, 0, byteData.Length);


// Get response.

using (var responseReader = new StreamReader(request.GetResponse().GetResponseStream()))

var stringResult = responseReader.ReadToEnd();
var result = XDocument.Parse(HttpUtility.HtmlDecode(stringResult));
var nsSoap = Constants.NsSoap;

// Look for the <Fault> element in the response.

var fault = result?.Root?.Element(nsSoap + "Body")?.Element(nsSoap + "Fault");
if (fault != null)

// Get the error code value and remove the namespace.
// Example value: s:InvalidUsernameAndPasswordPair

var codeWithNs = fault.Element(nsSoap + "Code").Element(nsSoap + "Value").Value;
var codeSplit = codeWithNs.Split(':');
var code = codeSplit.Length == 2 ? codeSplit[1] : codeSplit[0];

if (code == "SessionRequired")

throw new SessionRequiredException();

else if (code == "InvalidUsernameAndPasswordPair")

throw new VerifyLoginFaultException();

else

throw new SoapRequestException(code);



return result;









share|improve this question





















  • Please post complete classes and not only some snippets so one can also see if they are derived and what fields/properties they have?
    – t3chb0t
    May 1 at 14:56

















up vote
3
down vote

favorite
1












I would like feedback on this class library, mainly the architecture. It works very well. But maybe someone knows how to improve it.



This is a class library for working towards an external system. I reuse this class library in multiple solutions. The scope of this review is limited to "Retrieve the customer".



Since this is Xamarin I can't use the proxy class because it takes ages to load on a mobile device (related question here). Which is why I do the requests manually.



Project structure:



enter image description here



The main interface for the class library is the Facade class. It will call on the proper services to retrieve the data that the application requests.



public class Facade

WebRequester WebRequester get;

public Facade(string endpointUrl, string apiUser, string apiPassword)

WebRequester = new WebRequester(endpointUrl, apiUser, apiPassword);


/// <exception cref="SoapRequestException"></exception>
/// <exception cref="System.Net.WebException"></exception>
public Customer RetrieveCustomer(string customerId)

return new EntityService(WebRequester).RetrieveCustomer(customerId);




BaseService. The WebRequester is injected into the base service.



abstract class BaseService

protected WebRequester WebRequester get;

public BaseService(WebRequester webRequester)

WebRequester = webRequester;




Here's EntityService:



class EntityService : BaseService

public EntityService(WebRequester webRequester) : base(webRequester)



/// <exception cref="Exceptions.SoapRequestException">Thrown if the response has a Fault.</exception>
/// <exception cref="System.Net.WebException">Thrown if the request timed out.</exception>
IEnumerable<XElement> Query(string esql)

// Prepare request parameters.

var soapAction = "url-to-soap-action";
var method = "Query";
var parameters = new Dictionary<string, string>

"Esql", esql
;

// Call the service.

var result = WebRequester.Invoke(soapAction, method, parameters);
return result.Descendants(nsTf + "Data")?.FirstOrDefault()?.Elements(nsEm + "Record");


/// <exception cref="Exceptions.SoapRequestException"></exception>
/// <exception cref="System.Net.WebException"></exception>
public Customer RetrieveCustomer(string customerId)

var esql = $@"
select Id, Email, Name
from Customer
where Id = 'customerId'";

var row = Query(esql).FirstOrDefault();
var serializer = new XmlSerializer(typeof(Customer));
return serializer.Deserialize(row.CreateReader()) as Customer;




On the bottom is WebRequester. Couldn't find a better name. It makes the request to the external API and returns the SOAP response as an XDocument. Also checks for faults.



class WebRequester

string EndpointUrl get;
string ApiUser get;
string ApiPassword get;

public WebRequester(string endpointUrl, string apiUser, string apiPassword)

EndpointUrl = endpointUrl;
ApiUser = apiUser;
ApiPassword = apiPassword;


static string SessionId get; set;

/// <exception cref="SoapRequestException"></exception>
/// <exception cref="WebException"></exception>
string RetrieveSessionId() => new SecurityService(this).BeginSession(ApiUser, ApiPassword);

/// <exception cref="VerifyLoginFaultException"></exception>
/// <exception cref="SoapRequestException">Thrown if the SOAP response has a Fault.</exception>
/// <exception cref="WebException">Thrown if the request times out.</exception>
public XDocument Invoke(string soapAction, string method, Dictionary<string, string> parameters, bool requireSession = true)

if (requireSession && SessionId == null)

SessionId = RetrieveSessionId();


try

return Invoke(soapAction, method, parameters, SessionId);

catch (SessionRequiredException)

SessionId = RetrieveSessionId();
return Invoke(soapAction, method, parameters, true);



/// <exception cref="VerifyLoginFaultException"></exception>
/// <exception cref="SessionRequiredException"></exception>
/// <exception cref="SoapRequestException">Thrown if the SOAP response has a Fault.</exception>
/// <exception cref="WebException">Thrown if the request times out.</exception>
XDocument Invoke(string soapAction, string method, Dictionary<string, string> parameters, string sessionId)

// Create the web request

var request = WebRequest.Create(new Uri(EndpointUrl)) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/soap+xml; charset=utf-8; action="" + soapAction + """;
request.Timeout = 10000;

// Prepare the session value.

var session = string.Empty;
if (sessionId != null)

session =
$@"<soap:Header>
<ns1:Session>
<ns1:SessionId>sessionId</ns1:SessionId>
</ns1:Session>
</soap:Header>";


// Define which namespace to use for the request body.

string bodyNs;

if (method == "Query")
bodyNs = "ns1";
else
bodyNs = "ns2";

// Prepare the parameters.

var postValues = new StringBuilder();
foreach (var param in parameters)

postValues.AppendLine($"<bodyNs:param.Key>param.Value</bodyNs:param.Key>");


// Prepare the SOAP envelope.

string soapEnvelope =
$@"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope
xmlns:soap=""Constants.NsSoap""
xmlns:ns1=""Constants.NsBase""
xmlns:ns2=""Constants.Ns2008"">
session
<soap:Body>
<bodyNs:method>
postValues.ToString()
</bodyNs:method>
</soap:Body>
</soap:Envelope>";

// Create a byte array of the data we want to send.

byte byteData = Encoding.UTF8.GetBytes(soapEnvelope.ToString());

// Set the content length in the request headers.

request.ContentLength = byteData.Length;

// Write data to request.

using (var postStream = request.GetRequestStream())

postStream.Write(byteData, 0, byteData.Length);


// Get response.

using (var responseReader = new StreamReader(request.GetResponse().GetResponseStream()))

var stringResult = responseReader.ReadToEnd();
var result = XDocument.Parse(HttpUtility.HtmlDecode(stringResult));
var nsSoap = Constants.NsSoap;

// Look for the <Fault> element in the response.

var fault = result?.Root?.Element(nsSoap + "Body")?.Element(nsSoap + "Fault");
if (fault != null)

// Get the error code value and remove the namespace.
// Example value: s:InvalidUsernameAndPasswordPair

var codeWithNs = fault.Element(nsSoap + "Code").Element(nsSoap + "Value").Value;
var codeSplit = codeWithNs.Split(':');
var code = codeSplit.Length == 2 ? codeSplit[1] : codeSplit[0];

if (code == "SessionRequired")

throw new SessionRequiredException();

else if (code == "InvalidUsernameAndPasswordPair")

throw new VerifyLoginFaultException();

else

throw new SoapRequestException(code);



return result;









share|improve this question





















  • Please post complete classes and not only some snippets so one can also see if they are derived and what fields/properties they have?
    – t3chb0t
    May 1 at 14:56













up vote
3
down vote

favorite
1









up vote
3
down vote

favorite
1






1





I would like feedback on this class library, mainly the architecture. It works very well. But maybe someone knows how to improve it.



This is a class library for working towards an external system. I reuse this class library in multiple solutions. The scope of this review is limited to "Retrieve the customer".



Since this is Xamarin I can't use the proxy class because it takes ages to load on a mobile device (related question here). Which is why I do the requests manually.



Project structure:



enter image description here



The main interface for the class library is the Facade class. It will call on the proper services to retrieve the data that the application requests.



public class Facade

WebRequester WebRequester get;

public Facade(string endpointUrl, string apiUser, string apiPassword)

WebRequester = new WebRequester(endpointUrl, apiUser, apiPassword);


/// <exception cref="SoapRequestException"></exception>
/// <exception cref="System.Net.WebException"></exception>
public Customer RetrieveCustomer(string customerId)

return new EntityService(WebRequester).RetrieveCustomer(customerId);




BaseService. The WebRequester is injected into the base service.



abstract class BaseService

protected WebRequester WebRequester get;

public BaseService(WebRequester webRequester)

WebRequester = webRequester;




Here's EntityService:



class EntityService : BaseService

public EntityService(WebRequester webRequester) : base(webRequester)



/// <exception cref="Exceptions.SoapRequestException">Thrown if the response has a Fault.</exception>
/// <exception cref="System.Net.WebException">Thrown if the request timed out.</exception>
IEnumerable<XElement> Query(string esql)

// Prepare request parameters.

var soapAction = "url-to-soap-action";
var method = "Query";
var parameters = new Dictionary<string, string>

"Esql", esql
;

// Call the service.

var result = WebRequester.Invoke(soapAction, method, parameters);
return result.Descendants(nsTf + "Data")?.FirstOrDefault()?.Elements(nsEm + "Record");


/// <exception cref="Exceptions.SoapRequestException"></exception>
/// <exception cref="System.Net.WebException"></exception>
public Customer RetrieveCustomer(string customerId)

var esql = $@"
select Id, Email, Name
from Customer
where Id = 'customerId'";

var row = Query(esql).FirstOrDefault();
var serializer = new XmlSerializer(typeof(Customer));
return serializer.Deserialize(row.CreateReader()) as Customer;




On the bottom is WebRequester. Couldn't find a better name. It makes the request to the external API and returns the SOAP response as an XDocument. Also checks for faults.



class WebRequester

string EndpointUrl get;
string ApiUser get;
string ApiPassword get;

public WebRequester(string endpointUrl, string apiUser, string apiPassword)

EndpointUrl = endpointUrl;
ApiUser = apiUser;
ApiPassword = apiPassword;


static string SessionId get; set;

/// <exception cref="SoapRequestException"></exception>
/// <exception cref="WebException"></exception>
string RetrieveSessionId() => new SecurityService(this).BeginSession(ApiUser, ApiPassword);

/// <exception cref="VerifyLoginFaultException"></exception>
/// <exception cref="SoapRequestException">Thrown if the SOAP response has a Fault.</exception>
/// <exception cref="WebException">Thrown if the request times out.</exception>
public XDocument Invoke(string soapAction, string method, Dictionary<string, string> parameters, bool requireSession = true)

if (requireSession && SessionId == null)

SessionId = RetrieveSessionId();


try

return Invoke(soapAction, method, parameters, SessionId);

catch (SessionRequiredException)

SessionId = RetrieveSessionId();
return Invoke(soapAction, method, parameters, true);



/// <exception cref="VerifyLoginFaultException"></exception>
/// <exception cref="SessionRequiredException"></exception>
/// <exception cref="SoapRequestException">Thrown if the SOAP response has a Fault.</exception>
/// <exception cref="WebException">Thrown if the request times out.</exception>
XDocument Invoke(string soapAction, string method, Dictionary<string, string> parameters, string sessionId)

// Create the web request

var request = WebRequest.Create(new Uri(EndpointUrl)) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/soap+xml; charset=utf-8; action="" + soapAction + """;
request.Timeout = 10000;

// Prepare the session value.

var session = string.Empty;
if (sessionId != null)

session =
$@"<soap:Header>
<ns1:Session>
<ns1:SessionId>sessionId</ns1:SessionId>
</ns1:Session>
</soap:Header>";


// Define which namespace to use for the request body.

string bodyNs;

if (method == "Query")
bodyNs = "ns1";
else
bodyNs = "ns2";

// Prepare the parameters.

var postValues = new StringBuilder();
foreach (var param in parameters)

postValues.AppendLine($"<bodyNs:param.Key>param.Value</bodyNs:param.Key>");


// Prepare the SOAP envelope.

string soapEnvelope =
$@"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope
xmlns:soap=""Constants.NsSoap""
xmlns:ns1=""Constants.NsBase""
xmlns:ns2=""Constants.Ns2008"">
session
<soap:Body>
<bodyNs:method>
postValues.ToString()
</bodyNs:method>
</soap:Body>
</soap:Envelope>";

// Create a byte array of the data we want to send.

byte byteData = Encoding.UTF8.GetBytes(soapEnvelope.ToString());

// Set the content length in the request headers.

request.ContentLength = byteData.Length;

// Write data to request.

using (var postStream = request.GetRequestStream())

postStream.Write(byteData, 0, byteData.Length);


// Get response.

using (var responseReader = new StreamReader(request.GetResponse().GetResponseStream()))

var stringResult = responseReader.ReadToEnd();
var result = XDocument.Parse(HttpUtility.HtmlDecode(stringResult));
var nsSoap = Constants.NsSoap;

// Look for the <Fault> element in the response.

var fault = result?.Root?.Element(nsSoap + "Body")?.Element(nsSoap + "Fault");
if (fault != null)

// Get the error code value and remove the namespace.
// Example value: s:InvalidUsernameAndPasswordPair

var codeWithNs = fault.Element(nsSoap + "Code").Element(nsSoap + "Value").Value;
var codeSplit = codeWithNs.Split(':');
var code = codeSplit.Length == 2 ? codeSplit[1] : codeSplit[0];

if (code == "SessionRequired")

throw new SessionRequiredException();

else if (code == "InvalidUsernameAndPasswordPair")

throw new VerifyLoginFaultException();

else

throw new SoapRequestException(code);



return result;









share|improve this question













I would like feedback on this class library, mainly the architecture. It works very well. But maybe someone knows how to improve it.



This is a class library for working towards an external system. I reuse this class library in multiple solutions. The scope of this review is limited to "Retrieve the customer".



Since this is Xamarin I can't use the proxy class because it takes ages to load on a mobile device (related question here). Which is why I do the requests manually.



Project structure:



enter image description here



The main interface for the class library is the Facade class. It will call on the proper services to retrieve the data that the application requests.



public class Facade

WebRequester WebRequester get;

public Facade(string endpointUrl, string apiUser, string apiPassword)

WebRequester = new WebRequester(endpointUrl, apiUser, apiPassword);


/// <exception cref="SoapRequestException"></exception>
/// <exception cref="System.Net.WebException"></exception>
public Customer RetrieveCustomer(string customerId)

return new EntityService(WebRequester).RetrieveCustomer(customerId);




BaseService. The WebRequester is injected into the base service.



abstract class BaseService

protected WebRequester WebRequester get;

public BaseService(WebRequester webRequester)

WebRequester = webRequester;




Here's EntityService:



class EntityService : BaseService

public EntityService(WebRequester webRequester) : base(webRequester)



/// <exception cref="Exceptions.SoapRequestException">Thrown if the response has a Fault.</exception>
/// <exception cref="System.Net.WebException">Thrown if the request timed out.</exception>
IEnumerable<XElement> Query(string esql)

// Prepare request parameters.

var soapAction = "url-to-soap-action";
var method = "Query";
var parameters = new Dictionary<string, string>

"Esql", esql
;

// Call the service.

var result = WebRequester.Invoke(soapAction, method, parameters);
return result.Descendants(nsTf + "Data")?.FirstOrDefault()?.Elements(nsEm + "Record");


/// <exception cref="Exceptions.SoapRequestException"></exception>
/// <exception cref="System.Net.WebException"></exception>
public Customer RetrieveCustomer(string customerId)

var esql = $@"
select Id, Email, Name
from Customer
where Id = 'customerId'";

var row = Query(esql).FirstOrDefault();
var serializer = new XmlSerializer(typeof(Customer));
return serializer.Deserialize(row.CreateReader()) as Customer;




On the bottom is WebRequester. Couldn't find a better name. It makes the request to the external API and returns the SOAP response as an XDocument. Also checks for faults.



class WebRequester

string EndpointUrl get;
string ApiUser get;
string ApiPassword get;

public WebRequester(string endpointUrl, string apiUser, string apiPassword)

EndpointUrl = endpointUrl;
ApiUser = apiUser;
ApiPassword = apiPassword;


static string SessionId get; set;

/// <exception cref="SoapRequestException"></exception>
/// <exception cref="WebException"></exception>
string RetrieveSessionId() => new SecurityService(this).BeginSession(ApiUser, ApiPassword);

/// <exception cref="VerifyLoginFaultException"></exception>
/// <exception cref="SoapRequestException">Thrown if the SOAP response has a Fault.</exception>
/// <exception cref="WebException">Thrown if the request times out.</exception>
public XDocument Invoke(string soapAction, string method, Dictionary<string, string> parameters, bool requireSession = true)

if (requireSession && SessionId == null)

SessionId = RetrieveSessionId();


try

return Invoke(soapAction, method, parameters, SessionId);

catch (SessionRequiredException)

SessionId = RetrieveSessionId();
return Invoke(soapAction, method, parameters, true);



/// <exception cref="VerifyLoginFaultException"></exception>
/// <exception cref="SessionRequiredException"></exception>
/// <exception cref="SoapRequestException">Thrown if the SOAP response has a Fault.</exception>
/// <exception cref="WebException">Thrown if the request times out.</exception>
XDocument Invoke(string soapAction, string method, Dictionary<string, string> parameters, string sessionId)

// Create the web request

var request = WebRequest.Create(new Uri(EndpointUrl)) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/soap+xml; charset=utf-8; action="" + soapAction + """;
request.Timeout = 10000;

// Prepare the session value.

var session = string.Empty;
if (sessionId != null)

session =
$@"<soap:Header>
<ns1:Session>
<ns1:SessionId>sessionId</ns1:SessionId>
</ns1:Session>
</soap:Header>";


// Define which namespace to use for the request body.

string bodyNs;

if (method == "Query")
bodyNs = "ns1";
else
bodyNs = "ns2";

// Prepare the parameters.

var postValues = new StringBuilder();
foreach (var param in parameters)

postValues.AppendLine($"<bodyNs:param.Key>param.Value</bodyNs:param.Key>");


// Prepare the SOAP envelope.

string soapEnvelope =
$@"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope
xmlns:soap=""Constants.NsSoap""
xmlns:ns1=""Constants.NsBase""
xmlns:ns2=""Constants.Ns2008"">
session
<soap:Body>
<bodyNs:method>
postValues.ToString()
</bodyNs:method>
</soap:Body>
</soap:Envelope>";

// Create a byte array of the data we want to send.

byte byteData = Encoding.UTF8.GetBytes(soapEnvelope.ToString());

// Set the content length in the request headers.

request.ContentLength = byteData.Length;

// Write data to request.

using (var postStream = request.GetRequestStream())

postStream.Write(byteData, 0, byteData.Length);


// Get response.

using (var responseReader = new StreamReader(request.GetResponse().GetResponseStream()))

var stringResult = responseReader.ReadToEnd();
var result = XDocument.Parse(HttpUtility.HtmlDecode(stringResult));
var nsSoap = Constants.NsSoap;

// Look for the <Fault> element in the response.

var fault = result?.Root?.Element(nsSoap + "Body")?.Element(nsSoap + "Fault");
if (fault != null)

// Get the error code value and remove the namespace.
// Example value: s:InvalidUsernameAndPasswordPair

var codeWithNs = fault.Element(nsSoap + "Code").Element(nsSoap + "Value").Value;
var codeSplit = codeWithNs.Split(':');
var code = codeSplit.Length == 2 ? codeSplit[1] : codeSplit[0];

if (code == "SessionRequired")

throw new SessionRequiredException();

else if (code == "InvalidUsernameAndPasswordPair")

throw new VerifyLoginFaultException();

else

throw new SoapRequestException(code);



return result;











share|improve this question












share|improve this question




share|improve this question








edited May 2 at 8:59
























asked Apr 30 at 7:35









Jam

1236




1236











  • Please post complete classes and not only some snippets so one can also see if they are derived and what fields/properties they have?
    – t3chb0t
    May 1 at 14:56

















  • Please post complete classes and not only some snippets so one can also see if they are derived and what fields/properties they have?
    – t3chb0t
    May 1 at 14:56
















Please post complete classes and not only some snippets so one can also see if they are derived and what fields/properties they have?
– t3chb0t
May 1 at 14:56





Please post complete classes and not only some snippets so one can also see if they are derived and what fields/properties they have?
– t3chb0t
May 1 at 14:56











1 Answer
1






active

oldest

votes

















up vote
-1
down vote



accepted










I've just the same approach more than once. Sometimes you just have to work with bad designed soap apis. You should refactor the large Invoke method in WebRequester. It's way to long and should be devided in separate methods for building the request and parsing the response.



But all and all I thin it's a okay solution. The downside is that it's harder to update if the api changes.






share|improve this answer





















  • This would be a more useful answer if you gave some concrete suggestions besides "refactor the large Invoke method"
    – Dannnno
    May 7 at 13:52










Your Answer




StackExchange.ifUsing("editor", function ()
return StackExchange.using("mathjaxEditing", function ()
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
);
);
, "mathjax-editing");

StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);








 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f193244%2fmake-requests-to-soap-api%23new-answer', 'question_page');

);

Post as a guest






























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
-1
down vote



accepted










I've just the same approach more than once. Sometimes you just have to work with bad designed soap apis. You should refactor the large Invoke method in WebRequester. It's way to long and should be devided in separate methods for building the request and parsing the response.



But all and all I thin it's a okay solution. The downside is that it's harder to update if the api changes.






share|improve this answer





















  • This would be a more useful answer if you gave some concrete suggestions besides "refactor the large Invoke method"
    – Dannnno
    May 7 at 13:52














up vote
-1
down vote



accepted










I've just the same approach more than once. Sometimes you just have to work with bad designed soap apis. You should refactor the large Invoke method in WebRequester. It's way to long and should be devided in separate methods for building the request and parsing the response.



But all and all I thin it's a okay solution. The downside is that it's harder to update if the api changes.






share|improve this answer





















  • This would be a more useful answer if you gave some concrete suggestions besides "refactor the large Invoke method"
    – Dannnno
    May 7 at 13:52












up vote
-1
down vote



accepted







up vote
-1
down vote



accepted






I've just the same approach more than once. Sometimes you just have to work with bad designed soap apis. You should refactor the large Invoke method in WebRequester. It's way to long and should be devided in separate methods for building the request and parsing the response.



But all and all I thin it's a okay solution. The downside is that it's harder to update if the api changes.






share|improve this answer













I've just the same approach more than once. Sometimes you just have to work with bad designed soap apis. You should refactor the large Invoke method in WebRequester. It's way to long and should be devided in separate methods for building the request and parsing the response.



But all and all I thin it's a okay solution. The downside is that it's harder to update if the api changes.







share|improve this answer













share|improve this answer



share|improve this answer











answered May 7 at 11:44









Rikard Engström

16




16











  • This would be a more useful answer if you gave some concrete suggestions besides "refactor the large Invoke method"
    – Dannnno
    May 7 at 13:52
















  • This would be a more useful answer if you gave some concrete suggestions besides "refactor the large Invoke method"
    – Dannnno
    May 7 at 13:52















This would be a more useful answer if you gave some concrete suggestions besides "refactor the large Invoke method"
– Dannnno
May 7 at 13:52




This would be a more useful answer if you gave some concrete suggestions besides "refactor the large Invoke method"
– Dannnno
May 7 at 13:52












 

draft saved


draft discarded


























 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f193244%2fmake-requests-to-soap-api%23new-answer', 'question_page');

);

Post as a guest













































































Popular posts from this blog

Greedy Best First Search implementation in Rust

Function to Return a JSON Like Objects Using VBA Collections and Arrays

C++11 CLH Lock Implementation