Limitations retrieving JSON String from web service using MonoTouch - json

I am developing an iOS Application using MonoTouch. The application collects its data from a web service, using this code:
private static string getResult (string url)
{
string result;
var request = HttpWebRequest.Create (url);
request.ContentType = "application/json";
request.Method = "POST";
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
if (response.StatusCode != HttpStatusCode.OK)
Console.Out.WriteLine("Error fetching data. Server returned status code: {0}", response.StatusCode);
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
result = reader.ReadToEnd();
}
}
return result;
}
And this works fine, BUT when the json string returned from the Web Service reaches a certain size, the request returns with Internal server error 500. I have tried to invoke the service method directly in a web browser, and this returns a json string as expected. Why will it not work with my code, and is there a way to fix this?
Update:
I think this might solve my problem: http://forums.iis.net/t/1176077.aspx/1

Try Increasing Time Out for your service request. Your service must be timing out resulting 500 error
Also check this http://www.checkupdown.com/status/E500.html

Related

POST json to external API in .NET Core - Unsupported Media Type

I'm trying to code a middleman API that logs calls and other details from internal users to an external API.
When I try to POST to the external API from my Controller, I get 415 unsupported media type.
I set up my client in the controller constructor like this:
client.BaseAddress = new Uri("https://restapi.***.com/customers/");
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("X-AppSecretToken", Auth.APPSECRETTOKEN);
client.DefaultRequestHeaders.Add("X-AgreementGrantToken", Auth.AGREEMENTGRANTTOKEN);
My POST method looks like this:
var json = JsonConvert.SerializeObject(customer, Formatting.Indented);
using (var stringContent = new StringContent(json))
{
stringContent.Headers.ContentType.CharSet = "";
HttpResponseMessage response = await client.PostAsync(client.BaseAddress, stringContent);
if (!response.IsSuccessStatusCode)
{
return StatusCode((int)response.StatusCode);
}
}
return CreatedAtAction("GetCustomer", new { id = customer.ID }, customer);
I've been looking around and found a lot of comments telling me to use Stringcontent, but I also found a couple of responses saying ByteArrayContent - none of them work.
Can anyone help me?
EDIT: When I run the code with breakpoints it seems like some of the properties in the incoming customer object are set even though I didn't set them in my Postman call.
Example; the external API returns a customernumber when I give it the 5 properties that are obligatory. But when I call my internal API from Postman, sending only those 5 obligatory properties, it autopopulates the customernumber with a 0.
Could this be the source of the error? and how do I tell .net core to not autopopulate the customernumber?
EDIT2: I changed my stringContent to include encoding and used a different overload, so the using line now says
using (var stringContent = new StringContent(json, Encoding.UTF8, "application/json"))
And I removed
stringContent.Headers.ContentType.Charset = "";
to reflect the fact that I tried setting the encoding.
The return code changed from 415 to 400 Bad Request when I changed that.
EDIT3:
Tried NOT serializing with Json.Net, and instead used JObjects and Jproperties;
public async Task<ActionResult<Customer>> PostCustomer([FromBody]Customer customer)
{
JObject payload = new JObject(
new JProperty("currency", customer.Currency),
new JProperty("name", customer.Name),
new JProperty("customergroup",
new JObject(new JProperty("customergroupNumber",
customer.CustomerGroup.CustomerGroupNumber)
)),
new JProperty("paymentTerms",
new JObject(new JProperty("paymentTermsNumber",
customer.PaymentTerms.PaymentTermsNumber)
)),
new JProperty("vatZone",
new JObject(new JProperty("vatZoneNumber",
customer.VatZone.VatZoneNumber)
))
);
using (var stringContent = new StringContent(payload.ToString(), Encoding.UTF8, "application/json"))
{
HttpResponseMessage response = await client.PostAsync(client.BaseAddress, stringContent);
if (!response.IsSuccessStatusCode)
{
return StatusCode((int)response.StatusCode);
}
}
return CreatedAtAction("GetCustomer", new { id = customer.CustomerNumber }, customer);
}
Still 400 Bad Request
This is a case of capitalizing - simple really.
My POST request JSON had an object named customergroup - changed it to customerGroup, and it worked.

Xamarin.Forms problems sending large picture over HttpClient SendAsync in Json format

from my Xamarin.Forms app I'm sending a picture and other fields to the server using HttpClient in Json format.
If I send a little picture I've got with my front camera it's working fine, if I send a larger picture I've got with the rear camera it doesn't work and I always get an exception: "Excepional error".
I tried to create the same code in a windows form application and it's working fine also with large images, but not from my App.
I have already modified on the server web.config to increase json content size:
<jsonSerialization maxJsonLength="50000000"/>
Can someone help ?! Thanks!!
This is the code on my app:
public async static Task<MyAppDataModels.Common.WsResponse> PostPhotoFromUser(int catalogItemId, int objReferenceId, int languageId, byte[] fileContent)
{
MyAppDataModels.Common.WsResponse MyResponse = new MyAppDataModels.Common.WsResponse();
try
{
HttpClient MyHttpClient = new HttpClient();
MyHttpClient.Timeout = TimeSpan.FromSeconds(520);
MyHttpClient.BaseAddress = new Uri(string.Format("{0}/Application/ApplicationPostPhotoFromUser", MyAppSettings.ServerApiUrl));
MyHttpClient.DefaultRequestHeaders.Accept.Clear();
MyHttpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
MyHttpClient.DefaultRequestHeaders.AcceptCharset.Clear();
MyHttpClient.DefaultRequestHeaders.AcceptCharset.Add(new StringWithQualityHeaderValue("utf-8"));
HttpRequestMessage MyWsRequest = new HttpRequestMessage(HttpMethod.Post, MyHttpClient.BaseAddress);
dynamic MyObjData = new JObject();
MyObjData["CatalogItemId"] = catalogItemId;
MyObjData["ObjReferenceId"] = objReferenceId;
MyObjData["UserId"] = string.Empty;
MyObjData["LanguageId"] = languageId;
MyObjData["Picture"] = fileContent;
string MySerializedPostedData = JsonConvert.SerializeObject(MyObjData);
MyWsRequest.Content = new StringContent(MySerializedPostedData, Encoding.UTF8, "application/json");
HttpResponseMessage MyWsResponse = await MyHttpClient.SendAsync(MyWsRequest, HttpCompletionOption.ResponseHeadersRead);
MyWsResponse.EnsureSuccessStatusCode();
var MyContentResponse = await MyWsResponse.Content.ReadAsStringAsync();
MyResponse.ResponseId = MyAppConstants.Constants.ResponseCode.Successfull;
}
catch (Exception ex)
{
MyResponse.ResponseId = MyAppConstants.Constants.ResponseCode.ErrorWhileProcessingRequest;
MyResponse.ResponseErrorMessage = ex.Message;
}
return MyResponse;
}
From the stacktrace,
System.Net.WebExceptionStatus.ProtocolError
means that the server responded with some 40x error, maybe 401 (Acess Denied) or something similar.
you can wrap your call in a:
try
{
}
catch(WebException ex){
}
then check the exceptions Status and cast the exception's response like that:
((HttpWebResponse)e.Response).StatusDescription
to get more info about what has gone wrong on the server.
EDIT:
Because you're uploading large files, you can resolve the "maximum request length exceeded exception", you need to modify your server's (ASP.NET for example) web.config file to accept large request size:
<configuration>
<system.web>
<httpRuntime maxRequestLength="50000" />
</system.web>
</configuration>

My Windows Phone app Get empty response (404 Not Found) Scond time, work's great first time;And always work fine if without SSL

I am building my first windowsPhone 8.1 application ,the role of my application is to create connection with server to get information from it, so I am writing the code to do this process by sending json-rpc request to server to get some information ,I am successful to get it in first time but when I send the second request I am receiving an empty response with 404 error (page not found).
But when I call the service without https (http only) it works fine regardless how many time I call it !
public async Task<string> GetDataFromServer(string urlToCall, string JSONData,string RR)
{
string UserName = “XXXXXXX”
string Password = "XXX";
using ( var handler = new HttpClientHandler())
{
handler.Credentials = new NetworkCredential(UserName, Password);
HttpClient client = new HttpClient(handler);
HttpResponseMessage response = null;
try
{
response = await client.PostAsync(urlToCall, new StringContent(JSONData.ToString(), Encoding.UTF8, " application/json"));
string res = response.Content.ReadAsStringAsync().Result;
Windows.UI.Popups.MessageDialog g = new Windows.UI.Popups.MessageDialog(res);
await g.ShowAsync();
return res;
}
catch (Exception ex)
{
Windows.UI.Popups.MessageDialog g = new Windows.UI.Popups.MessageDialog("Error is : " + ex.Message);
g.ShowAsync();
return "Error";
}
finally
{
response.Dispose();
client.CancelPendingRequests();
client.Dispose();
handler.Dispose();
}
}
}
Again, when call the URL of service (start with https) on first time I got response with seeked data, but second time I receive an empty response with 404 error (page not found) !!
Any help please
Please try to use this solution.
public async Task<string> SendJSONData3(string urlToCall, string JSONData)
{
string UserName = "XXXXXXXXX";
string Password = "XXXXXXXXX";
var httpWebRequest = (HttpWebRequest)WebRequest.Create(urlToCall);
httpWebRequest.Credentials = new NetworkCredential(UserName, Password);
httpWebRequest.ContentType = "text/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(await httpWebRequest.GetRequestStreamAsync()))
{
string json = JSONData;
streamWriter.Write(json);
streamWriter.Flush();
}
var httpResponse = (HttpWebResponse)await httpWebRequest.GetResponseAsync();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
return result;
}
}
A couple of ideas:
Do not use the .Result property. Just use await instead to avoid deadlocks.
Remove the additional space in front of the media type parameter " application/json"
Enable logging on the webserver and see if the second request arrives on the server.
Get a network trace, for example with Wireshark or Fiddler.
Try puting WebRequest.RegisterPrefix("https://", WebRequestCreator.ClientHttp); in your initialization code, as proposed in this answer.

HttpClient dosen't get data after update WP8

I have this code to get JSON data from an API for WP8:
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(mainURL.ToString());
HttpResponseMessage response = await client.GetAsync("");
string res = await response.Content.ReadAsStringAsync();
var root = await JsonConvert.DeserializeObjectAsync<Rootobject>(res);
Everything works perfectly, but when I update data on the web API from the web site and try to retrieve data again using this code it gets the old data even though accessing the URL in a browser it gets the new data.
When I debug line by line, I see that the "response" object contains the old data.
The only way I have found to fix this is to rebuild the project in this way it works.
How can I properly get the updated data?
There may be some caching involved. Tried adding some random string to the URL, like
client.BaseAddress = new Uri(mainURL.ToString()+"&random="+DateTime.Now.Ticks);
I have same kind of problem. I tried this this may be help you.
HttpWebRequest request = HttpWebRequest.CreateHttp(mainURL.ToString());
request.Method = "GET or Post";
request.BeginGetResponse(ResponseCallBack, request);
void ResponseCallBack(IAsyncResult asyncResult)
{
HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult);
using (Stream data = response.GetResponseStream())
{
using (var reader = new StreamReader(data))
{
string jsonString = reader.ReadToEnd();
MemoryStream memoryStream = new MemoryStream(Encoding.Unicode.GetBytes(jsonString));
DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(typeof(Rootobject));
Rootobject yourdata= dataContractJsonSerializer.ReadObject(memoryStream) as Rootobject;
}
}
}

Seeing the Http Response content in ServiceStack

I am using ServiceStack to create a C# client to a JSON RESTful service. I have this code that returns my DTO:
Search result = restClient.Get (search);
This works fine, but in order to effectively debug the search results coming back I need to output the text content from the underlying HTTP Response object. (I don't know all the elements in the response yet in order to add them to the DTO).
Is there any way I can get hold of the underlying HTTP response, and thus the full text content, from my result object?
Thanks in advance.
#adamfowleruk
When inheriting from ServiceStack's built-in Service you can access the underlying Request and Response directly from the Response class with:
public class MyService : Service
{
public object Get(Request request)
{
base.Request ...
base.Response ...
}
}
You won't see the response output in your service or filters since it writes directly to the response stream and is the last thing that ServiceStack does after executing your service and all response filters.
For diagnosing HTTP I recommend using Fiddler or WebInspector also ServiceStack's built-in Request Logger might help as well.
Consuming a ServiceStack service
If you're using the C# Service Clients you can simply ask for what you want, e.g. you can access the returned response as a raw string:
string responseJson = client.Get<string>("/poco/World");
Or as raw bytes:
byte[] responseBytes = client.Get<byte[]>("/poco/World");
Or as a Stream:
using (Stream responseStream = client.Get<Stream>("/poco/World")) {
var dto = responseStream.ReadFully().FromUtf8Bytes().FromJson<PocoResponse>();
}
Or even access the populated HttpWebResponse object:
HttpWebResponse webResponse = client.Get<HttpWebResponse>("/poco/World");
webResponse.Headers["X-Response"] //World
using (webResponse)
using (var stream = webResponse.GetResponseStream())
using (var sr = new StreamReader(stream)) {
string response = sr.ReadToEnd();
}
You can also introspect the HttpWebResponse by using Global and Local Response filters, e.g:
JsonServiceClient.HttpWebResponseFilter = httpRes => { .. };
Or using a Local filter:
var client = new JsonServiceClient(baseUrl) {
ResponseFilter = httpRes => { .. }
};
Consuming a 3rd Party Service
If you're consuming a 3rd Party REST/HTTP API you can use a responseFilter: in ServiceStack's HTTP Util extensions:
List<GithubRepo> repos = "https://api.github.com/users/{0}/repos".Fmt(user)
.GetJsonFromUrl(responseFilter: httpRes => {
var remaining = httpRes.Headers["X-Api-Remaining"];
})
.FromJson<List<GithubRepo>>();
I use Fiddler to debug my services. It gives you all sorts of cool HTTP debugging facilities.
http://www.fiddler2.com/fiddler2/
I like to use RestConsole. It is a Chrome Extension and you can easily submit POST requests and see the response. It is also handy to create sample data and then step into the ServiceStack code and see what's happening. The ServiceStack PluralSight course has a nice demo of how to use them together.
Thanks to the above help I found the right answer. Documenting here for others:-
SearchResponse result = null; // my ServiceStack DTO
HttpWebResponse webResponse = restClient.Get<HttpWebResponse>(
completePath("/v1/search",qp)); // builds the URL with parameters
using (var stream = webResponse.GetResponseStream())
using (var sr = new StreamReader(stream)) {
var text = sr.ReadToEnd();
log.log ("response text: " + text); // *** PRINTING STRING VALUE HERE FOR DEBUG
result = text.FromJson<SearchResponse>();
}
// Now do something useful with the result DTO object
log.log ("RESULT: " + result.ToString ());
for (int i = 0; i < result.Results.Length; i++) {
log.log ("Result " + i + ": " + result.Results[i].ToString());
}