iOS:从ASP .Net Web服务接收JSON响应

时间:2014-04-29 12:22:53

标签: ios asp.net json web-services http-headers

我正在尝试从我的ASP .Net网络服务器获得JSON响应。我已经阅读了类似的问题并应用了我的案例的答案,但我仍然无法从服务器获得JSON响应。它总是返回XML。

这是我的网络服务代码:

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文件:

<?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请求代码:

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];

我在这里缺少什么?

更新

当我按建议更改内容类型时:

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

并将我的参数转换为JSON消息:

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

最终成功接收JSON响应:

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

此外,我发现将接受类型设置为JSON不是必需的:

[request addRequestHeader:@"Accept" value:@"application/json"];

2 个答案:

答案 0 :(得分:1)

我之前遇到过同样的问题。作为参考,根据thisthis,如果您希望从.ASMX中使用JSON,则需要:

  • Content-Type标题设置为application/json
  • 将HTTP方法设置为POST

答案 1 :(得分:0)

我的登录代码中的代码段。基本上我正在做的是创建一个授权字符串。并使用base64对其进行编码。之后,我将授权作为http标头添加,并告诉服务器我想要以JSON格式存储数据。当我这样做时,我在会话中填写它并调用Asynchronus数据任务。完成后,您将获得一个NSdata对象,您需要使用正确的反序列化来填充JSON数组。

在我的情况下,我获得了一个用户令牌,我需要每次都进行验证,以便每当我需要api的内容时,我都不需要输入用户名和密码。

查看代码,您将看到每个步骤会发生什么:)

        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];