Pergunta

I am trying to get a JSON response from my ASP .Net web server. I have read similar questions and applied given answers to my case but still I am not able to get a JSON response from server. It always returns XML.

Here is my web service code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Script.Services;
using System.Web.Services;

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] 
[System.Web.Script.Services.ScriptService]
public class TLogin : System.Web.Services.WebService {

    static string LOGIN_STATUS_OK = "OK";
    static string LOGIN_STATUS_FAILD = "FAILED";

    public class LoginStatus {
        public string status;

        public LoginStatus() {
            this.status = LOGIN_STATUS_FAILD;
        }

        public LoginStatus(string status){
            this.status = status;
        }
    }

    public TLogin () {
        //Uncomment the following line if using designed components
        //InitializeComponent();
    }

    [WebMethod]
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public LoginStatus Login(string username, string password) {
        return new LoginStatus(LOGIN_STATUS_OK);
    }
}

Web.config file:

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" strict="false" explicit="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" requestPathInvalidCharacters="&lt;,&gt;,*,%,:,\,?" />
    <customErrors mode="Off"/>
    <webServices>
      <protocols>
        <add name="HttpGet"/>
        <add name="HttpPost"/>
      </protocols>
    </webServices>
  </system.web>
</configuration>

iOS HTTP request code:

NSURL *url = [NSURL URLWithString:@"http://192.168.1.20:8090/MyApplication/TuprasLogin.asmx/Login"];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setRequestMethod:@"POST"];
[request addRequestHeader:@"Content-Type" value:@"application/x-www-form-urlencoded"];
[request appendPostData:[post dataUsingEncoding:NSUTF8StringEncoding]];
[request setDelegate:self];
[request startAsynchronous];

What am I missing here?

UPDATE

When I change the content type as suggested:

[request addRequestHeader:@"Content-Type" value:@"application/json"];

and converted my parameters to JSON message as:

NSString *post = [[NSString alloc]
                initWithFormat:@"{ \"username\" : \"%@\" , \"password\" : \"%@\" }",
                self.textFieldUserName.text, self.textFieldPassword.text];

finally managed to receive JSON response as:

{"d":{"__type":"TLogin+LoginStatus","status":"OK"}}

Also I have found that setting accep type to JSON is not necessary as:

[request addRequestHeader:@"Accept" value:@"application/json"];
Foi útil?

Solução

I have faced same issue earlier. For reference, according to this and this, if you wish to consume JSON from an .ASMX it's necessary to :

  • Set the Content-Type header to application/json
  • Set the HTTP method to POST

Outras dicas

A code snippet from my login code. Basicly what im doing is that im creating a authorisation string. and encode it with base64. after that i'm adding the authorisation as a http header and tell the server that i want to have data in a JSON format. When i did that im filling it in the session and call a Asynchronus data task. When its complete you will get an NSdata object that you need to fill in an JSON array with the proper deserialisation.

In my case i get a user token which i need to verify each time so that i don't need to push the username and password each time when i need something from my api.

Look trough the code, and you will see what happens each step:)

        NSString *userPasswordString = [NSString stringWithFormat:@"%@:%@", user.Username, user.Password];
        NSData * userPasswordData = [userPasswordString dataUsingEncoding:NSUTF8StringEncoding];
        NSString *base64EncodedCredential = [userPasswordData base64EncodedStringWithOptions:0];
        NSString *authString = [NSString stringWithFormat:@"Basic %@", base64EncodedCredential];

        NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];

        // The headers, the authstring is a base64 encoded hash of the password and username.
        [sessionConfig setHTTPAdditionalHeaders: @{@"Accept": @"application/json", @"Authorization": authString}];

        NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig];
        // Get the serverDNS
        NSString *tmpServerDNS = [userDefault valueForKey:@"serverDNS"];
        // Request a datatask, this will execute the request.
        NSURLSessionDataTask *dataTask = [session dataTaskWithURL:[NSURL URLWithString: [NSString stringWithFormat:@"%@/api/token",tmpServerDNS]] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
        {                                         
                NSHTTPURLResponse *HTTPResponse = (NSHTTPURLResponse *)response;
                NSInteger statusCode = [HTTPResponse statusCode];
                // If the statuscode is 200 then the username and password has been accepted by the server.
                if(statusCode == 200)
                {
                    NSError *error = nil;
                    NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];

                    user.token = [crypt EncryptString:[jsonArray valueForKey:@"TokenId"]];
                    // Encrypt the password for inserting in the local database.
                    user.Password = [crypt EncryptString:user.Password];
                    // Insert the user.
                    [core insertUser:user];

                }
            });
        // Tell the data task to execute the call and go on with other code below.
       [dataTask resume];
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top