Soap 调用在 c# 中给出 500(内部服务器错误)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16104707/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Soap call gives 500 (internal server error) in c#
提问by user1562231
I have one affiliate account and I need to make a soapcall to get data. I got ready code from one site and I tried to apply it, but I'm getting 500(internal server error). My code is given below.
我有一个附属帐户,我需要soap打电话来获取数据。我从一个站点获得了现成的代码并尝试应用它,但我得到了500(internal server error). 我的代码如下。
public void getdata()
{
var _url = "http://secure.directtrack.com/api/soap_affiliate.php";
var _action = "http://secure.directtrack.com/api/soap_affiliate.php/dailyStatsInfo";
XmlDocument soapEnvelopeXml = CreateSoapEnvelope();
HttpWebRequest webRequest = CreateWebRequest(_url, _action);
InsertSoapEnvelopeIntoWebRequest(soapEnvelopeXml, webRequest);
// begin async call to web request.
IAsyncResult asyncResult = webRequest.BeginGetResponse(null, null);
// suspend this thread until call is complete. You might want to
// do something usefull here like update your UI.
asyncResult.AsyncWaitHandle.WaitOne();
// get the response from the completed web request.
string soapResult;
using (WebResponse webResponse = webRequest.EndGetResponse(asyncResult))
using (StreamReader rd = new StreamReader(webResponse.GetResponseStream()))
{
soapResult = rd.ReadToEnd();
}
Console.Write(soapResult);
}
private static HttpWebRequest CreateWebRequest(string url, string action)
{
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Headers.Add("SOAPAction", action);
webRequest.ContentType = "text/xml;charset=\"utf-8\"";
webRequest.Accept = "text/xml";
webRequest.Method = "POST";
return webRequest;
}
private static XmlDocument CreateSoapEnvelope()
{
XmlDocument soapEnvelop = new XmlDocument();
soapEnvelop.LoadXml(@"<SOAP-ENV:Envelope xmlns:SOAP-ENV=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:xsi=""http://www.w3.org/1999/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/1999/XMLSchema""><SOAP-ENV:Body xmlns=""http://soapinterop.org//"" SOAP-ENV:encodingStyle=""http://schemas.xmlsoap.org/soap/encoding/""> <q1:Execute xmlns:q1=""http://secure.directtrack.com/api/soap_affiliate.php/dailyStatsInfo""><client xsi:type=""xsd:string"">MyClientNAme</client><add_code xsi:type=""xsd:string"">MyCode</add_code><password xsi:type=""xsd:string"">MyPassword</password><program_id xsi:type=""xsd:int"">161</program_id></q1:Execute></SOAP-ENV:Body></SOAP-ENV:Envelope>");
return soapEnvelop;
}
private static void InsertSoapEnvelopeIntoWebRequest(XmlDocument soapEnvelopeXml, HttpWebRequest webRequest)
{
using (Stream stream = webRequest.GetRequestStream())
{
soapEnvelopeXml.Save(stream);
}
}
What is the problem? Thanks in advance.
问题是什么?提前致谢。
回答by Dietz
You should really try wrapping your code in one or more try-catch blocks, as the Internal Server Error is likely the result of an unhandled exception.
您真的应该尝试将您的代码包装在一个或多个 try-catch 块中,因为内部服务器错误很可能是未处理异常的结果。
If the soap xml is malformed, this line would throw an XmlException:
如果soap xml 格式错误,这一行将抛出一个XmlException:
soapEnvelop.LoadXml(@"<SOAP-ENV:Envelope xmlns:SOAP-ENV=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:xsi=""http://www.w3.org/1999/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/1999/XMLSchema""><SOAP-ENV:Body xmlns=""http://soapinterop.org//"" SOAP-ENV:encodingStyle=""http://schemas.xmlsoap.org/soap/encoding/""> <q1:Execute xmlns:q1=""http://secure.directtrack.com/api/soap_affiliate.php/dailyStatsInfo""><client xsi:type=""xsd:string"">MyClientNAme</client><add_code xsi:type=""xsd:string"">MyCode</add_code><password xsi:type=""xsd:string"">MyPassword</password><program_id xsi:type=""xsd:int"">161</program_id></q1:Execute></SOAP-ENV:Body></SOAP-ENV:Envelope>");
This one could produce IOExceptions:
这可能会产生 IOExceptions:
soapEnvelopeXml.Save(stream);
There are probably more, but this should give you a poke in the right direction...
可能还有更多,但这应该会让你朝正确的方向戳...
回答by Suveer Singh
You should try using reflection in order to send data to a web service. Try using something like this:
您应该尝试使用反射来将数据发送到 Web 服务。尝试使用这样的东西:
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!
希望能帮助到你!
回答by JDB still remembers Monica
An internal server error means that the error is on the server side. Your code may be calling the service exactly correctly, or you may be passing a parameter that the server doesn't know how to process (but the server code isn't smart enough to tell you so).
内部服务器错误意味着错误发生在服务器端。您的代码可能完全正确地调用了服务,或者您可能传递了服务器不知道如何处理的参数(但服务器代码不够聪明,无法告诉您)。
Without knowing more about the server and what it expects, it isn't possible to diagnose the issue.
如果不了解有关服务器及其预期的更多信息,就无法诊断问题。
That said, it's possible that your soap envelope is the issue. Are you sure you've entered the correct client name, add code, password, program id, etc?
也就是说,您的肥皂信封可能是问题所在。您确定输入了正确的客户端名称、添加代码、密码、程序 ID 等吗?
回答by Tommy Holman
I went through this as well, I can even tell where you got this code :)
我也经历过这个,我什至可以告诉你从哪里得到这个代码:)
so check it out
所以检查一下
webRequest.Headers.Add("SOAPAction", action);
is the issue
是问题
simply use
简单地使用
webRequest.Headers.Add("SOAP:Action");

