1

You would think with all the posts here that this would be easy to figure out. :| Well here is what should be a simple example. NOTE The web service is VB and the client is c#. The wb service sends and receives fine when called from JQuery. From .NET There is a problem, If the service asks for a parameter as show below then the client's getresponse method gets error 500 Internal server error

The Web Service

<WebMethod()> _
<ScriptMethod(ResponseFormat:=ResponseFormat.Json, XmlSerializeString:=False)> _
Public Function Test(WebInfo As GetUserID) As Person
    Dim Someone As New Person
    Someone.Name = "Bob"
    Someone.FavoriteColor = "Green"
    Someone.ID = WebInfo.WebUserID.ToString()
    Return Someone
End Function

The Web Client (set up to be send and receive JSON)

    public Person Test(int UserID, string url) {
        HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url + "test.asmx/Test");
        webRequest.Method = "POST";
        webRequest.ContentType = "application/json; charset=utf-8";
        StreamWriter sw = new StreamWriter(webRequest.GetRequestStream());
        sw.Write("{'WebInfo':{'WebUserID':1}}");  // this works from JQuery
        HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
        Stream responseStream = webResponse.GetResponseStream();
        DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(Person));
        Person someone = (Person)jsonSerializer.ReadObject(responseStream);
        return someone;
    }

Has anyone out there done this successfully? Thanks

nuander
  • 1,319
  • 1
  • 19
  • 33
  • I have a solution to this which I will post later. The solution constist of 1) using DatacontractJsonSerializer to serialize the json 2) in the WCF service using the WebMessageBodyStyle.Bare body style to avoid having to wrap the json. 3) user JavaScriptSerializer to deserialize the response string – nuander May 09 '12 at 21:32
  • OH, I guess item 4) switch to WCF service from web service, which is why item 2 is in there – nuander May 09 '12 at 22:45

1 Answers1

3

Here is a method that makes calls to a JSON web service, allowing the developer to both send and receive complext data types. The object passed in can be any data type or class. The result is a JSON string, and or any error message the methods type is shown below

public class WebServiceCallReturn {
    public string JSONResponse { get; set; }
    public string SimpleResponse { get; set; }
    public string Error { get; set; }
}

public WebServiceCallReturn WebServiceJSONCall(string uri, string requestType, object postData = null) {
    WebServiceCallReturn result = new WebServiceCallReturn();

    // create request
    HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri);
    webRequest.ContentType = "application/json; charset=utf-8";
    webRequest.Method = requestType;
    webRequest.Accept = "application/json; charset=utf-8";
    // add json data object to send
    if (requestType == "POST") {
        string json = "{ }";
        if (postData != null) {
            try {   // the serializer is fairly robust when used this way
                DataContractJsonSerializer ser = new DataContractJsonSerializer(postData.GetType());
                MemoryStream ms = new MemoryStream();
                ser.WriteObject(ms, postData);
                json = Encoding.UTF8.GetString(ms.ToArray());
            } catch {
                result.Error = "Error serializing post";
            }
        }
        webRequest.ContentLength = json.Length;
        StreamWriter sw;
        try {
            sw = new StreamWriter(webRequest.GetRequestStream());
        } catch (Exception ex) {
            // the remote name could not be resolved
            result.Error = ex.Message;
            return result;
        }
        sw.Write(json);
        sw.Close();
    }

    // read response
    HttpWebResponse webResponse;
    try {
        webResponse = (HttpWebResponse)webRequest.GetResponse();
    } catch (Exception ex) {
        // The remote server returned an error...
        // (400) Bad Request
        // (403) Access forbidden   (check the application pool)
        // (404) Not Found
        // (405) Method not allowed
        // (415) ...not the expected type
        // (500) Internal Server Error   (problem with IIS or unhandled error in web service)
        result.Error = ex.Message;
        return result;
    }
    Stream responseStream = webResponse.GetResponseStream();
    StreamReader sr = new StreamReader(responseStream, Encoding.UTF8);
    string resultString = sr.ReadToEnd();
    sr.Close();
    responseStream.Close();
    result.JSONResponse = resultString;
    return result;
}

This method could be used as follows

public SomeCustomDataClass Getsomeinformation(int userID) {

    UserInfoClass postData = new UserInfoClass();
    postData.WebUserID = userID;
    SomeCustomDataClass result = new SomeCustomDataClass();

    string uri = URL + "SomeServices.svc/GetSomething";
    WebServiceCallReturn webReturn = WebServiceJSONCall(uri, "POST", postData);
    if (webReturn.Error == null) {
        //resultString = CleanJSON(resultString);
        JavaScriptSerializer serializer = new JavaScriptSerializer();
        try {
            result = serializer.Deserialize<SomeCustomDataClass>(webReturn.JSONResponse);
        } catch {
            result.Error = "Error deserializing";
        }
    } else {
        result.Error = webReturn.Error;
    }
    return result;
}

Hope that helps someone

nuander
  • 1,319
  • 1
  • 19
  • 33