简体   繁体   中英

Error Calling ASP.NET Web Service Using POST and JSON

I'm pulling my hair out on this one. I am unable to successfully call a .NET web service using POST and JSON ("The remote server returned an error: (500) Internal Server Error."). I can make it work if I don't insist on JSON or if I use GET. I am doing this all in Xamarin Studio, so the web server is XSP and not IIS, if that makes a difference.

Any help is much appreciated.

Here is the code for my web service:

using System;
using System.Web;
using System.Web.Services;
using System.Web.Script.Services;
using System.Web.Script.Serialization;

namespace WebServiceTest
{
    [WebService (Namespace = "http://tempuri.org/WebServiceTest")]
    [ScriptService]
    public class API : System.Web.Services.WebService
    {

        [WebMethod]
        [ScriptMethod (UseHttpGet=true, ResponseFormat=ResponseFormat.Json)]
        public string About() {
            return "About WebServiceTest";
        }

    }
}

... here is my web.config ...

<?xml version="1.0"?>
<!--
Web.config file for WebServiceTest.

The settings that can be used in this file are documented at 
http://www.mono-project.com/Config_system.web and 
http://msdn2.microsoft.com/en-us/library/b5ysx397.aspx
-->
<configuration>
  <system.web>
    <webServices>
      <protocols>
        <add name="HttpGet" />
        <add name="HttpPost" />
      </protocols>
    </webServices>
    <compilation defaultLanguage="C#" debug="true">
      <assemblies>
      </assemblies>
    </compilation>
    <customErrors mode="RemoteOnly">
    </customErrors>
    <authentication mode="None">
    </authentication>
    <authorization>
      <allow users="*" />
    </authorization>
    <httpHandlers>
    </httpHandlers>
    <trace enabled="false" localOnly="true" pageOutput="false" requestLimit="10" traceMode="SortByTime" />
    <sessionState mode="InProc" cookieless="false" timeout="20" />
    <globalization requestEncoding="utf-8" responseEncoding="utf-8" />
    <pages>
    </pages>
  </system.web>
</configuration>

... and here is my application test code ...

using System;
using System.IO;
using System.Net;
using System.Text;

namespace WebServiceTestApp
{
    class MainClass
    {
        public static void Main (string[] args)
        {
            Console.WriteLine ("Starting...");

            Console.WriteLine ("Making API call...");
            string url = "http://127.0.0.1:8080/API.asmx/About";
            HttpWebRequest request;

            // Test 1: Use GET, don't set content type or content
            // Works, returns XML
            Console.WriteLine ("Test 1");
            request = (HttpWebRequest)WebRequest.Create (url);
            GetResponse (request);

            // Test 2: Use GET, set content type but no content
            // Works, returns JSON
            Console.WriteLine ("Test 2");
            request = (HttpWebRequest)WebRequest.Create (url);
            request.ContentType = "application/json; charset=utf-8";
            GetResponse (request);

            // Test 3: Use POST, don't set content type or content
            // Works, returns XML
            Console.WriteLine ("Test 3");
            request = (HttpWebRequest)WebRequest.Create (url);
            request.Method = "POST";
            GetResponse (request);

            // Test 4: Use POST, set content type but no content
            // *** Fails: 500 Internal Server Error
            Console.WriteLine ("Test 4");
            request = (HttpWebRequest)WebRequest.Create (url);
            request.ContentType = "application/json; charset=utf-8";
            request.Method = "POST";
            GetResponse (request);

            // Done.
            Console.WriteLine ("Done!");

        }

        public static void GetResponse(HttpWebRequest request)
        {
            try {
                using (var response = (HttpWebResponse)request.GetResponse ()) {
                    var stream = response.GetResponseStream ();
                    var reader = new StreamReader (stream);
                    var result = reader.ReadToEnd ();
                    Console.WriteLine (result);
                    reader.Close ();
                    reader.Dispose ();
                    response.Close ();
                }
            } catch (Exception e) {
                Console.WriteLine ("*** Failed: Error '" + e.Message + "'.");
            }
        }

    }
}

The test also fails if I try to add any content to the POST, request, ie replacing the Test 4 code with ...

    // Test 4: Use POST, set content type and content
    // *** Fails: 500 Internal Server Error
    Console.WriteLine ("Test 4");
    request = (HttpWebRequest)WebRequest.Create (url);
    request.Method = "POST";
    request.ContentType = "application/json; charset=utf-8";
    var paramData = ""; // also fails with "{}"
    request.ContentLength = paramData.Length;
    using (var writer = new StreamWriter (request.GetRequestStream ())) {
        writer.Write (paramData);
    }
    GetResponse (request);

It also fails if I change "UseHttpGet=false" in ScriptMethod.

I solved my own problem. With both XSP and IISExpress (I haven't tried any other web servers), you cannot do both a GET and a POST to the same WebMethod with contentType = "application/json". (Yeah, I know, I shouldn't even be trying...) That is, if you include "(UseHttpGet=true" you can GET the method but not POST, and if you don't include the parameter you can POST but not GET. Interestingly, both GET and POST work if you don't set the content type (ie you are willing to use XML).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM