【问题标题】:Soap call gives 500 (internal server error) in c#Soap 调用在 C# 中给出 500(内部服务器错误)
【发布时间】:2013-04-19 12:33:57
【问题描述】:

我有一个附属帐户,我需要拨打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);
    }
}

有什么问题?提前致谢。

【问题讨论】:

  • 这里解释错误:checkupdown.com/status/E500.html
  • 这是一般原因,他已经解释了他的 500 内部服务器错误。那我的呢。还有其他东西干扰了这个电话
  • 如果你不知道,我们怎么知道?请在您的代码中进行一些适当的错误检查,尝试调试,尝试记录。正如您自己所说,错误 500 非常普遍。
  • 找出 500 错误的最佳方法是调试。去你的代码,某个地方抛出了你的代码未处理的异常..

标签: c# soap


【解决方案1】:

内部服务器错误意味着错误在服务器端。您的代码可能完全正确地调用了服务,或者您可能传递了服务器不知道如何处理的参数(但服务器代码不够聪明,无法告诉您)。

如果不了解有关服务器及其预期的更多信息,就无法诊断问题。

也就是说,您的肥皂信封可能是问题所在。您确定您输入了正确的客户端名称、添加代码、密码、程序 ID 等吗?

【讨论】:

    【解决方案2】:

    我也经历过这个,我什至可以知道你从哪里得到这个代码:)

    那就去看看

    webRequest.Headers.Add("SOAPAction", action);
    

    是问题

    简单地使用

    webRequest.Headers.Add("SOAP:Action");
    

    【讨论】:

    • 这似乎与the spec 不匹配。我不是 SOAP 方面的专家,但看起来这实际上与删除该标头的结果相同。
    【解决方案3】:

    您真的应该尝试将您的代码包装在一个或多个 try-catch 块中,因为内部服务器错误很可能是未处理异常的结果。

    如果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>");
    

    这可能会产生 IOExceptions:

    soapEnvelopeXml.Save(stream);
    

    可能还有更多,但这应该会让你朝着正确的方向前进......

    【讨论】:

      【解决方案4】:

      您应该尝试使用反射来将数据发送到 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);
      

      我使用这段代码来分发数据,而不是插入到每个单独的数据库中。

      希望对你有帮助!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多