I am trying to do a SOAP request but the server is returning an 500 error.
The SOAP request returns correctly the XML message via jmeter for example, so it must be something in my code, but i fail to see what. Can you help?
private void soapRequest(string regID)
{
string soapReq= @"<?xml version=""1.0"" encoding=""utf-8""?>";
soapReq= "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:mpc=\"urn://mobility-platform.de/mpcustomerdb/\">\n";
soapReq += "<soapenv:Header/>\n";
soapReq += "<soapenv:Body>\n";
soapReq += "<mpc:findRegistrationByID>\n";
soapReq += "<registrationID>" + regID + "</registrationID>\n";
soapReq += "</mpc:findRegistrationByID>\n";
soapReq += "</soapenv:Body>\n";
soapReq += "</soapenv:Envelope>";
//Builds the connection to the WebService.
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://url?wsdl");
req.Credentials = new NetworkCredential("user", "pass");
req.Headers.Add("SOAP:Action");
req.ContentType = "text/xml;charset=\"utf-8\"";
req.Accept = "text/xml";
req.Method = "POST";
//Passes the SoapRequest String to the WebService
using (Stream stm = req.GetRequestStream())
{
using (StreamWriter stmw = new StreamWriter(stm))
{
stmw.Write(soapReq.ToString());
}
}
try
{
//Gets the response
HttpWebResponse soapResponse = (HttpWebResponse)req.GetResponse();
//Writes the Response
Stream responseStream = soapResponse.GetResponseStream();
//read the stream
XmlDocument soapResponseXML = new XmlDocument();
StreamReader responseStreamRead = new StreamReader(responseStream);
soapResponse.ContentType = "text/xml";
//MessageBox.Show(responseStreamRead.ReadToEnd().ToString());
string soapURL = responseStreamRead.ReadToEnd().ToString();
soapResponseXML.LoadXml(soapURL);
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message);
}
}
Here is the soap request
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:mpc="urn://mobility-platform.de/mpcustomerdb/">
<soapenv:Header/>
<soapenv:Body>
<mpc:findRegistrationByID>
<registrationID>2304580</registrationID>
</mpc:findRegistrationByID>
</soapenv:Body>
</soapenv:Envelope>
Later edit:
If i change
req.Headers.Add("SOAP:Action");
to:
req.Headers.Add("SOAPAction", ""\"http://url\"" + "findRegistrationByID");
i get an different error:
«This property is not implemented by this class»
asked Mar 15, 2012 at 11:11
observobserv
1572 gold badges4 silver badges12 bronze badges
3
Is not very easy to make an proper soap request with this method. I am strongly recommending to use rather the whole web service, and rather make the request like this:
WebService aa = new WebService;
registrationName = aa.findRegistrationByID("123");
This will accomplish all the above code
answered Apr 11, 2012 at 8:33
observobserv
1572 gold badges4 silver badges12 bronze badges
You should try using reflection in order to send data to a web service. Try using something like this:
Uri mexAddress = new Uri(URL);
// For MEX endpoints use a MEX address and a
// mexMode of .MetadataExchange
MetadataExchangeClientMode mexMode = MetadataExchangeClientMode.HttpGet;
var binding = new WSHttpBinding(SecurityMode.None);
binding.MaxReceivedMessageSize = Int32.MaxValue;
XmlDictionaryReaderQuotas readerQuotas = new XmlDictionaryReaderQuotas();
readerQuotas.MaxNameTableCharCount = Int32.MaxValue;
binding.ReaderQuotas = readerQuotas;
//SS Get Service Type and set this type to either Galba and Powersale
string contractName = "";
string operationName = "RegisterMerchant";
object[] operationParameters;// = new object[] { 1, 2 };
// Get the metadata file from the service.
//MetadataExchangeClient mexClient = new MetadataExchangeClient(mexAddress, mexMode);
MetadataExchangeClient mexClient = new MetadataExchangeClient(binding);
mexClient.ResolveMetadataReferences = true;
MetadataSet metaSet = mexClient.GetMetadata(mexAddress, mexMode);
// Import all contracts and endpoints
WsdlImporter importer = new WsdlImporter(metaSet);
Collection<ContractDescription> contracts = importer.ImportAllContracts();
ServiceEndpointCollection allEndpoints = importer.ImportAllEndpoints();
// Generate type information for each contract
ServiceContractGenerator generator = new ServiceContractGenerator();
var endpointsForContracts = new Dictionary<string, IEnumerable<ServiceEndpoint>>();
foreach (ContractDescription contract in contracts)
{
generator.GenerateServiceContractType(contract);
// Keep a list of each contract's endpoints
endpointsForContracts[contract.Name] = allEndpoints.Where(se => se.Contract.Name == contract.Name).ToList();
}
if (generator.Errors.Count != 0) { throw new Exception("There were errors during code compilation."); }
// Generate a code file for the contracts
CodeGeneratorOptions options = new CodeGeneratorOptions();
options.BracingStyle = "C";
CodeDomProvider codeDomProvider = CodeDomProvider.CreateProvider("C#");
// Compile the code file to an in-memory assembly
// Don't forget to add all WCF-related assemblies as references
CompilerParameters compilerParameters = new CompilerParameters(
new string[] { "System.dll", "System.ServiceModel.dll", "System.Runtime.Serialization.dll" });
compilerParameters.GenerateInMemory = true;
CompilerResults results = codeDomProvider.CompileAssemblyFromDom(compilerParameters, generator.TargetCompileUnit);
if (results.Errors.Count > 0)
{
throw new Exception("There were errors during generated code compilation");
}
else
{
// Find the proxy type that was generated for the specified contract
// (identified by a class that implements
// the contract and ICommunicationbject)
Type[] types = results.CompiledAssembly.GetTypes();
Type clientProxyType = types
.First(t => t.IsClass && t.GetInterface(contractName) != null && t.GetInterface(typeof(ICommunicationObject).Name) != null);
// Get the first service endpoint for the contract
ServiceEndpoint se = endpointsForContracts[contractName].First();
// Create an instance of the proxy
// Pass the endpoint's binding and address as parameters
// to the ctor
object instance = results.CompiledAssembly.CreateInstance(
clientProxyType.Name,
false,
System.Reflection.BindingFlags.CreateInstance,
null,
new object[] { se.Binding, se.Address },
CultureInfo.CurrentCulture, null);
Type parameterType = types.First(t => t.IsClass && t.Name=="Method()");
Object o = Activator.CreateInstance(parameterType);
FieldInfo[] props = parameterType.GetFields();
FieldInfo fi = parameterType.GetField("NewMerchantDetail");
//PropertyInfo pi = parameterType.GetProperty("NewMerchantDetail");
Type p1Type = fi.FieldType;
//Pass in the values here!!!
Object o1 = Activator.CreateInstance(p1Type);
PropertyInfo pi1 = p1Type.GetProperty("MerchantID");//7
pi1.SetValue(o1, vendingClient.VendingClientID, null);
pi1 = p1Type.GetProperty("FirstName");// John
pi1.SetValue(o1, vendingClient.DescriptiveName, null);
fi.SetValue(o, o1, BindingFlags.Default, null, null);
operationParameters = new object[] { o1 };
// Get the operation's method, invoke it, and get the return value
object retVal = instance.GetType().GetMethod(operationName).
Invoke(instance, operationParameters);
I used this code for distributing data instead of having to insert into each individual database.
Hope it helps!
К сожалению, похоже, что бы вы ни пытались (например, передать array('exceptions' => 0)
, SoapClient()
будет вызывать неуправляемый E_ERROR при проблемах с сетевым подключением. Эта ошибка по-прежнему присутствует как высоко, как PHP 5.5.4 (REF).
Резюме:
Тестовый скрипт:
$client=@new SoapClient('garbage',array('exceptions'=>FALSE));
echo 'OK';
Ожидаемый результат: мы должны увидеть «ОК»,
Фактический результат:
Если мы используем error_get_last()
register_shutdown_function
для отображения содержимого error_get_last()
, получаем:
Array
(
[type] => 1
[message] => SOAP-ERROR: Parsing WSDL: Couldn't load from 'garbage' : failed
to load external entity "garbage"
)
Чтобы объяснить, почему вы вдруг получаете эту ошибку, не меняя ничего в своей системе, и объясните, почему SoapClient работает на вашем локальном компьютере, а не на вашей производственной системе, это, скорее всего, проблема с брандмауэром.
Вот что сообщил другой человек, который решил свою проблему:
Я решил свою проблему. Это была проблема с моим брандмауэром. Брандмауэр удалял пакеты, отправленные через PHP, но с помощью curl или wget не удалялись. Я добавил правило для всего трафика с этого сервера и увеличил длину пакета, и теперь все работает отлично!
Совет:
Мой лучший совет на этот раз написать код в том же PHP файле, который проверяет, правильно ли разрешает и загружает URL-адрес службы SOAP перед вызовом SoapClient.
Answer by Drew Santiago
The SoapClient will throw an exception if it can’t access the remote file (due to networking), or it couldn’t parse the XML.,The 500 Internal Server Error indicates that PHP encountered a Fatal Error.,A SoapFault exception will be thrown if the wsdl URI cannot be loaded.,Making statements based on opinion; back them up with references or personal experience.
Check your error log for more info or turn on error reporting:
error_reporting(E_ALL);
ini_set('display_errors', '1');
Answer by Johnny Coleman
The problem of the SoapClient is that his temporary files are messed up somehow, maybe the PHP version was upgraded or maybe the /tmp dir was full on production and the server was not able to create new ones but yes, this is the problem.,So, the solution is simple, just delete all files from /tmp directory on the server that are starting with “wsdl-“ and the error will disappear.,Went to an error 500 in production server while using PHP SoapClient library to connect to some third-party API. The error was really strange, just error 500 and nothing more, even if you are using try catch, you won’t be able to catch and see the error.
The Example:,This site uses Akismet to reduce spam. Learn how your comment data is processed.
Went to an error 500 in production server while using PHP SoapClient library to connect to some third-party API. The error was really strange, just error 500 and nothing more, even if you are using try catch, you won’t be able to catch and see the error.
The Example:
try{
$client = new SoapClient("https://api.thirdparty.com/some/service?wsdl", ['exceptions' => true, 'trace' => true]);
} catch(SoapFault $fault) {
trigger_error("SOAP Fault: (faultcode: " . $fault->faultcode . ", faultstring: " . $fault->faultstring . ")", E_USER_ERROR);
} catch(Exception $e) {
trigger_error("SOAP Error: " . $e->getMessage(), E_USER_ERROR);
}
Answer by Leila Hodge
It seems Magento threw an Exception wich result in Internal Server Error.
For me helped that I log all exceptions that are thrown by adding,The response I get from the server is now internal error 500. I have maximum 90 sku’s/product ids.,I’m getting a 500 internal error response when I try to retrieve data via SOAP.,Maybe your webserver is configured to accept only browser requests. E.g. by UserAgent rules…? Or the API route has special protection.
Untested but something like this should work:
class Foo_Bar {
$_client = new SoapClient('http://example.com/api/soap/?wsdl');
$_session = $client->login('xxx', 'xxx');
public function productPrices($id) {
$client = $this->_client;
$session = $client->login('xxx', 'xxx');
$att = array("visibility","sku","special_price", "price");
$arguments = array( $id, NULL, $att);
$resultPrice = $client->call($session, 'catalog_product.info', $arguments);
echo $resultPrice['visibility'].",".$resultPrice['sku'].",".$resultPrice['special_price'].",".$resultPrice['price'];
}
}
Answer by Alanna Sweeney
[2007-09-27 03:40 UTC] tjerk dot meesters at muvee dot com
Description:
------------
Failure to load a WSDL file using the SoapClient class causes more than just an exception. The error is also caught by the error handler and a 500 status code is sent back.
This error is classified as a PHP Fatal error and can't be caught by any custom error handlers.
This error shouldn't be triggered at all, that's what we have exceptions for ;-)
Reproduce code:
---------------
<?php
try {
$s = new SoapClient('http://localhost/invalid_wsdl');
} catch (Exception $e) {
echo $e->getMessage();
}
?>
Expected result:
----------------
SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://localhost/invalid_wsdl'
Actual result:
--------------
[HTTP/1.x 500 Internal Server Error]
PHP Fatal error: SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://localhost/invalid_wsdl' in /var/www/html/test.php on line 4
SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://localhost/invalid_wsdl'
Answer by Esperanza Weber
When a Web service request is being processed, if an error is encountered, the nature of the error needs to be communicated to the client, or sender of the request. Because clients can be written on a variety of platforms using different languages, there must exist a standard, platform-independent mechanism for communicating the error.,The faults are returned to the sender only if request/response messaging is in use. If a Web service operation is configured as one-way, the SOAP fault is not returned to the sender, but stored for further processing.,In JAX-WS, Java exceptions (java.lang.Exception) that are thrown by your Java Web service are mapped to a SOAP fault and returned to the client to communicate the reason for failure. SOAP faults can be one of the following types:,Create the client implementation class to call the Web service method and throw the custom exception. Then, compile and run the client. For more information about creating Web service clients, see «Invoking Web Services» in Getting Started With JAX-WS Web Services for Oracle WebLogic Server.
Example 16-1 Example of SOAP 1.2 Fault Message
<?xml version="1.0"?>
<env:Envelope xmlns:env=http://www.w3.org/2003/05/soap-envelope>
<env:Body>
<env:Fault>
<env:Code>
<env:Value>env:Sender</env:Value>
<env:Subcode>
<env:Value>rpc:BadArguments</env:Value>
</env:Subcode>
</env:Code>
<env:Reason>
<env:Text xml:lang=en-US>Processing error<env:Text>
</env:Reason>
<env:Detail>
<e:myFaultDetails
xmlns:e=http://travelcompany.example.org/faults>
<e:message>Name does not match card number</e:message>
<e:errorcode>999</e:errorcode>
</e:myFaultDetails>
</env:Detail>
</env:Fault>
</env:Body>
</env:Envelope>
Сервер IIS (Internet Information Services) является одним из самых распространенных серверов веб-приложений, используемых для разработки и хостинга веб-сайтов и приложений на Windows. Однако, иногда пользователи могут столкнуться с проблемой, когда сервер IIS возвращает в качестве ответа на запросы по SOAP ошибку 500. В этой статье мы более подробно рассмотрим причины такого поведения сервера IIS и предложим возможные решения для данной проблемы.
Ошибка 500, или «Внутренняя ошибка сервера», является общей ошибкой HTTP, которая указывает на то, что произошла непредвиденная ошибка сервера и сервер не может обработать запрос пользователя. Когда сервер IIS возвращает эту ошибку в ответ на SOAP-запросы, это может быть вызвано несколькими факторами.
Одной из возможных причин ошибки 500 в ответ на SOAP-запросы может быть нарушение контракта службы. SOAP (Simple Object Access Protocol) является протоколом обмена структурированными сообщениями веб-сервисов. Веб-служба, которая обрабатывает SOAP-запросы, должна соответствовать определенному контракту, чтобы обеспечить правильное взаимодействие с клиентами. Если контракт веб-службы нарушен, сервер IIS может возвращать ошибку 500 в ответ на SOAP-запросы.
Другой возможной причиной ошибки 500 может быть наличие проблем в коде веб-службы. Веб-служба может содержать ошибки в своей реализации, такие как ошибки в обработке входных параметров, неправильной обработке исключений или проблемах с доступом к ресурсам, таким как базы данных или файловая система. Если веб-служба обнаруживает ошибку, она может вернуть ошибку 500 в ответ на SOAP-запросы.
Также, проблема может быть связана с конфигурацией сервера IIS. Неправильная конфигурация сервера IIS может привести к неправильной обработке SOAP-запросов или вызвать конфликты и ошибки при обработке запросов. Например, проблемы с настройками аутентификации, авторизации или уровня доступа могут вызывать ошибку 500 в ответ на SOAP-запросы.
При возникновении ошибки 500 в ответ на SOAP-запросы, следует принять несколько шагов для диагностики и решения проблемы.
Во-первых, рекомендуется проверить контракт и реализацию веб-службы. Убедитесь, что контракт веб-службы правильно определен и соответствует ожиданиям клиента. Проверьте код веб-службы на наличие ошибок и возможных проблем, которые могут вызвать ошибку 500. Обратитесь к логам сервера IIS для получения дополнительной информации о возможных ошибках и исключениях.
Далее, проверьте настройки сервера IIS. Проверьте конфигурацию сервера IIS, такую как настройки аутентификации, авторизации и уровня доступа. Убедитесь, что эти настройки правильно сконфигурированы и соответствуют требованиям веб-службы. Если вы не знакомы с настройками сервера IIS, вы можете обратиться к документации Microsoft или к специалистам по серверному администрированию.
Также, рекомендуется проверить ресурсы сервера, такие как доступ к базе данных или файловой системе. Убедитесь, что веб-служба имеет корректные права доступа к необходимым ресурсам. Проверьте соответствующие журналы или логи для получения информации о возможных проблемах доступа.
В случае непредвиденных или сложных ошибок, которые не удается решить, рекомендуется обратиться к команде поддержки серверов IIS или консультантам по программированию и серверному администрированию. Они могут оказать экспертную помощь и помочь вам решить проблему со возвращаемой ошибкой 500 на сервере IIS.
В заключение, ошибка 500 в ответ на запросы SOAP от сервера IIS может быть вызвана несколькими причинами: нарушенный контракт службы, проблемы в коде веб-службы или неправильная конфигурация сервера IIS. Для устранения этой проблемы рекомендуется проверить контракт и реализацию веб-службы, настройки сервера IIS и доступ к ресурсам сервера. В случае затруднений или неопределенных ошибок, рекомендуется обратиться к специалистам по серверному администрированию и программированию.