IOS5开发-http get/post调用mvc4 webapi互操作(图片上传)
目前最流行的跨平台交互是采用http协议通过JSON对象进行互操作。这种方式最简单,也很高效。webservice+xml的方式似乎已经过时。
下面是我做的一个例子
webapi的代码
public IEnumerable<Product> GetAllProducts()
{
Console.WriteLine(DateTime.Now.ToLongTimeString() + " : receive request.");
return new List<Product>
{
new Product() { Id = 1, Name = "Gizmo 1", Price = 1.99M },
new Product() { Id = 2, Name = "Gizmo 2", Price = 2.99M },
new Product() { Id = 3, Name = "Gizmo 3", Price = 3.99M },
new Product() { Id = 4, Name = "TShirt 3", Price = 5.99M },
new Product() { Id = 5, Name = "SOFT TSHIRT", Price = 34.99M },
};
}
public Product GetProductById(int id)
{
if (id < 1 || id > 3)
{
throw new HttpResponseException(System.Net.HttpStatusCode.NotFound);
}
return new Product()
{
Id = id,
Name = "Gizmo " + id.ToString(),
Price = id + 0.99M
};
}
// POST /api/Products
public Product Post(Product p)
{
Console.WriteLine(string.Format("submit Name:{0},Price:{1}",p.Name,p.Price));
return p;
}
// POST /api/Upload
public string Post()
{
Console.WriteLine(DateTime.Now.ToLongTimeString() + " : receive upload request.");
if (!Request.Content.IsMimeMultipartContent("form-data"))
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
MultipartFormDataStreamProvider streamProvider = new MultipartFormDataStreamProvider();
// Read the MIME multipart content using the stream provider we just created.
IEnumerable<HttpContent> bodyparts = Request.Content.ReadAsMultipartAsync(streamProvider).Result;
// The submitter field is the entity with a Content-Disposition header field with a "name" parameter with value "submitter"
//string submitter = "submitter";
//if (!bodyparts.TryGetFormFieldValue("submitter", out submitter))
//{
// submitter = "unknown";
//}
// Get a dictionary of local file names from stream provider.
// The filename parameters provided in Content-Disposition header fields are the keys.
// The local file names where the files are stored are the values.
IDictionary<string, string> bodyPartFileNames = streamProvider.BodyPartFileNames;
// Create response containing information about the stored files.
return bodyPartFileNames.Select(kv =>
{
FileInfo fileinfo = new FileInfo(kv.Value);
Console.WriteLine("receive file name:" + fileinfo.FullName + " Size:" + fileinfo.Length.ToString());
return new FileResult
{
FileName = kv.Key,
// LocalPath = fileinfo.FullName,
// LastModifiedTime = fileinfo.LastWriteTimeUtc,
// Length = fileinfo.Length,
// Submitter = submitter
};
//return FileResult;
}).ToList()[0].FileName;
{
Console.WriteLine(DateTime.Now.ToLongTimeString() + " : receive request.");
return new List<Product>
{
new Product() { Id = 1, Name = "Gizmo 1", Price = 1.99M },
new Product() { Id = 2, Name = "Gizmo 2", Price = 2.99M },
new Product() { Id = 3, Name = "Gizmo 3", Price = 3.99M },
new Product() { Id = 4, Name = "TShirt 3", Price = 5.99M },
new Product() { Id = 5, Name = "SOFT TSHIRT", Price = 34.99M },
};
}
public Product GetProductById(int id)
{
if (id < 1 || id > 3)
{
throw new HttpResponseException(System.Net.HttpStatusCode.NotFound);
}
return new Product()
{
Id = id,
Name = "Gizmo " + id.ToString(),
Price = id + 0.99M
};
}
// POST /api/Products
public Product Post(Product p)
{
Console.WriteLine(string.Format("submit Name:{0},Price:{1}",p.Name,p.Price));
return p;
}
// POST /api/Upload
public string Post()
{
Console.WriteLine(DateTime.Now.ToLongTimeString() + " : receive upload request.");
if (!Request.Content.IsMimeMultipartContent("form-data"))
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
MultipartFormDataStreamProvider streamProvider = new MultipartFormDataStreamProvider();
// Read the MIME multipart content using the stream provider we just created.
IEnumerable<HttpContent> bodyparts = Request.Content.ReadAsMultipartAsync(streamProvider).Result;
// The submitter field is the entity with a Content-Disposition header field with a "name" parameter with value "submitter"
//string submitter = "submitter";
//if (!bodyparts.TryGetFormFieldValue("submitter", out submitter))
//{
// submitter = "unknown";
//}
// Get a dictionary of local file names from stream provider.
// The filename parameters provided in Content-Disposition header fields are the keys.
// The local file names where the files are stored are the values.
IDictionary<string, string> bodyPartFileNames = streamProvider.BodyPartFileNames;
// Create response containing information about the stored files.
return bodyPartFileNames.Select(kv =>
{
FileInfo fileinfo = new FileInfo(kv.Value);
Console.WriteLine("receive file name:" + fileinfo.FullName + " Size:" + fileinfo.Length.ToString());
return new FileResult
{
FileName = kv.Key,
// LocalPath = fileinfo.FullName,
// LastModifiedTime = fileinfo.LastWriteTimeUtc,
// Length = fileinfo.Length,
// Submitter = submitter
};
//return FileResult;
}).ToList()[0].FileName;
webapi 返回的IEnumerable<Product> 或 IQueryable<Product> 支持odata协议,odata协议功能很强大,查询很方便。可以关注。
第一个是通过http get/post获取服务端数据和更新服务端数据。
代码获取数据代码
NSString *urlstring=self.urlTextField.text;
NSURL *url=[NSURL URLWithString:urlstring];
//NSData *jsondata=[[NSData alloc]initWithContentsOfURL:url];
//NSLog(@"data:%@",[[NSString alloc] initWithData:jsondata encoding:NSUTF8StringEncoding]);
NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url];
NSOperationQueue *queue=[[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:request queue:queue
completionHandler:^(NSURLResponse *respone,
NSData *data,
NSError *error)
{
if ([data length]>0 && error==nil) {
NSString *jsonstring=[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
//[self.respondTextView setText:jsonstring];
NSLog(@"data:%@",jsonstring);
//[self performSelectorOnMainThread:@selector(setRespondtext:)withObject:jsonstring waitUntilDone:YES modes:nil];
[self performSelectorOnMainThread:@selector(setRespondtext:) withObject:data waitUntilDone:NO];
}
}
];
}
post数据代码如下
NSString *urlstring=self.urlTextField.text;
NSString *poststr=self.requestTextView.text;
NSURL *url=[NSURL URLWithString:urlstring];
NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url];
[request addValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setHTTPMethod:@"POST"];
[request setHTTPBody:[poststr dataUsingEncoding:NSUTF8StringEncoding]];
NSOperationQueue *queue=[[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:request queue:queue
completionHandler:^(NSURLResponse *respone,
NSData *data,
NSError *error)
{
if ([data length]>0 && error==nil) {
NSString *jsonstring=[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
//[self.respondTextView setText:jsonstring];
NSLog(@"data:%@",jsonstring);
//[self performSelectorOnMainThread:@selector(setRespondtext:)withObject:jsonstring waitUntilDone:YES modes:nil];
[self performSelectorOnMainThread:@selector(setRespondtext:) withObject:data waitUntilDone:NO];
}
}
];
}
解析获取的JSON字符串
NSString *text=[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
id jsonObject=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
if (jsonObject !=nil) {
NSLog(@"Successfully deserialized...");
if ([jsonObject isKindOfClass:[NSDictionary class]]) {
NSDictionary *deserializedDic=(NSDictionary *)jsonObject;
NSLog(@"Dersialized Json dictionary =%@",deserializedDic);
}
else if([jsonObject isKindOfClass:[NSArray class]]){
NSArray *deserializedArray=(NSArray *)jsonObject;
NSLog(@"Derialized json array = %@",deserializedArray);
for (NSDictionary *item in deserializedArray) {
NSLog(@"Id : %@ Name: %@ Price : %@",[item objectForKey:@"Id"],[item objectForKey:@"Name"],[item objectForKey:@"Price"]);
}
}else{
}
}
[self.respondTextView setText:text];
}
图片上传的代码
NSString *urlstring=self.urlTextField.text;
//NSString *poststr=@"";
NSData *imgData=UIImageJPEGRepresentation(self.previewImageView.image, 0.9f);
NSString *boundary = @"0xKhTmLbOuNdArY";
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary, nil];
NSURL *url=[NSURL URLWithString:urlstring];
NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url];
[request addValue:contentType forHTTPHeaderField:@"Content-Type"];
[request setHTTPMethod:@"POST"];
NSMutableData *body = [NSMutableData data];
[body appendData:[[NSString stringWithFormat:@" --%@ ", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:@"Content-Disposition: form-data; name="userfile"; filename="iphonefile.jpg" "] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:@"Content-Type: application/octet-stream "] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:imgData]];
[body appendData:[[NSString stringWithFormat:@" --%@-- ", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:body];
NSOperationQueue *queue=[[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:request queue:queue
completionHandler:^(NSURLResponse *respone,
NSData *data,
NSError *error)
{
if ([data length]>0 && error==nil) {
NSString *jsonstring=[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
//[self.respondTextView setText:jsonstring];
NSLog(@"data:%@",jsonstring);
//[self performSelectorOnMainThread:@selector(setRespondtext:)withObject:jsonstring waitUntilDone:YES modes:nil];
//[self performSelectorOnMainThread:@selector(setRespondtext:) withObject:data waitUntilDone:NO];
}
}
];
}
我感觉使用ios sdk自带的NSMutableURLRequest,NSURLConnection, NSJSONSerialization,也非常方便,似乎没有必要去使用第三方的类库。