5

I'm trying to call a web service (.asmx) from a c# application, in json format.

When I specify request method as GET, and don't specify contentType.

(req is HttpWebRequest)

req.Method = "GET";

Everything works well, but I get XML response.
When I specify content Type:

req.ContentType = "application/json; charset=utf-8";  

I get

500 internal server error.

When I change request method:

req.Method = "POST";  

I can call parameterless methods only, which returns correctly json, but if I try calling a method with parameters, I get 500 error again.

The web service code:

    [WebMethod(EnableSession =true)]
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public string SimplestWebService()
    {         
        return "hello";
    }  

And With parameters:

    [WebMethod(EnableSession = true)]
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public string Echo(string aString)
    {       
        return aString;
    }

Any ideas will be much appreciated.

Added: Maybe I'm not writing the POST request right (now I'm sending it in the header, just like a GET request). Can someone please guide me on that?

Mode added: The web site is indeed marked as script:

[ScriptService]
public class MyAPI : System.Web.Services.WebService  

And here is how I build my POST request (I really tend to believe that's the problem):

HttpWebRequest req = (HttpWebRequest)WebRequest.Create(methodUrl.ToString());
req.Method = "POST";
req.Headers.Add("aString","oren");
req.ContentLength = 0;    
...
req.ContentType = "application/json; charset=utf-8";
req.Accept = "application/json; charset=utf-8";
using (HttpWebResponse res = (HttpWebResponse)req.GetResponse())
{
  StreamReader sr = new StreamReader(res.GetResponseStream());
  result.Append(sr.ReadToEnd());
}  
...

Also tried:

req.Method = "POST";          
string postData = "aString=kjkjk";
req.ContentType = @"application/json; charset=utf-8";
req.Accept = @"application/json; charset=utf-8";   
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] byte1 = encoding.GetBytes(postData);
req.ContentLength = byte1.Length;
Stream newStream = req.GetRequestStream();
newStream.Write(byte1, 0, byte1.Length);
newStream.Close();           

Two last notes:
1. This web service works in XML using the browser.
2. Asking for json, the code never reaches a break point at the web service. So this is possibly a IIS (I'm using IIS 6.1) issue. I've tried the MIME type recommendation here.

Thanks a lot.

Community
  • 1
  • 1
Oren A
  • 5,870
  • 6
  • 43
  • 64
  • Can you include the code where you configure the outgoing request? Specifically, how you're adding the "aString" parameter? That might help debug the issue. – mikemanne Oct 06 '10 at 19:42
  • Also, is the ASMX class itself tagged as: [ScriptService]? I think (not 100% sure) that is necessary to access the webservice using POST-mode requests and JSON-formatted data. – mikemanne Oct 06 '10 at 19:45
  • @mikemanne: Thanks a lot for the input. Updated. – Oren A Oct 06 '10 at 20:07

2 Answers2

5

Update 2:

I'm using fiddler2 to look at a successful POST request (from jquery to my asmx service), and I see a difference that might be worth checking:

Accept: application/json, text/javascript, */*

There's some other differences as well, but that one is the only one that leaps out as a possible smoking gun.

Updated Answer (in response to updated question):

It looks like you're using the contentStream correctly. However, the data you're pushing onto it ("aString=kjkjk") isn't valid JSON. As noted below, your data will likely need to be in valid JSON format:

{'aString':'kjkjk'}

Original Answer:

I believe you're setting the "aString" content incorrectly. For POST-method requests, the "payload" data isn't applied to the header, it is the content of the request itself. Therefore, you need to stream it onto the request object; see this MSDN reference for an example. Don't forget to also set the request's content-length.

Since you're implementing the service via JSON (and have specified JSON as the content-type), I believe you'll need to convert a JSON string to raw bytes, and that's what you'll push it onto the stream. Your JSON string should look something like this:

{'aString':'This is the text I want to echo.'}

You might need to do some fine-tuning (I'm not at a place where I can easily put together an exact code sample), but this should get you going in the right direction.

mikemanne
  • 3,535
  • 1
  • 22
  • 30
  • Still no luck.. Need a more specific answer – Oren A Oct 07 '10 at 17:32
  • One silly thing: make sure your URL (methodUrl) is targeting the correct webservice (htp://yourmachine/MyAPI.asmx/Echo). (deliberately misspelled 'http' so it would show up correctly in this comment) – mikemanne Oct 07 '10 at 17:46
  • Should be ashamed of myself (-:. Can't give you the bounty yet, only in 22 hours (SO rules). Thanks. – Oren A Oct 07 '10 at 17:54
  • The URL was the issue? That happens to every developer I've ever known (myself included) - you get so focused on the details and possible deeper causes, that it takes a fresh set of eyes to point out the obvious. :) – mikemanne Oct 07 '10 at 18:01
  • (-: No, the json was the issue, I was so sure ASP.NET will take care of that for me, I ignored it. – Oren A Oct 07 '10 at 20:03
0

ContentType seems to me to be the content-type of the request, not the response. What happens if you send an Accept header instead (informing the server of the content-types you're willing to accept).

Wrikken
  • 69,272
  • 8
  • 97
  • 136
  • Exactly the same results as before, both with GET and POST. – Oren A Oct 05 '10 at 13:40
  • Checked it in Fiddler, and I'm getting a json response: {"Message":"There was an error processing the request.","StackTrace":"","ExceptionType":""} (and 500 internal server error at the header) – Oren A Oct 05 '10 at 13:42
  • Moreover, if I try omitting the contentType, I get an XML response. – Oren A Oct 05 '10 at 13:44
  • Are you still setting the ContentType header? And if so, are you sending JSON? If not, remove that header, as the service probably fails on trying to parse the input. – Wrikken Oct 05 '10 at 13:45
  • Hmm, if omitting content-type, and setting accept, still results in XML, I'd say there's a problem in the core of the webservice, but as I don't know ASP.NET, I couldn't tell you what or where unfortunately. – Wrikken Oct 05 '10 at 13:47
  • This is an old thread and not sure if resolved but I've just had this **exact** same problem - webmethod parameter responds with error while webmethod without parameter works fine - for hours and finally looking at the MSN link in the Update2 section above, used this content type: 'request_auth.ContentType = @"application/x-www-form-urlencoded";' and my response was what I was expecting. Haven't had time to study it all out as to why that made the difference. – Jerry Of Perth Oct 30 '13 at 17:56