Web API Serialize XML - c#

I am trying to serialize XML using the web API, but I receive a null result.
Here is my XML:
http://pastebin.com/RxBPaZF5
Using XSD, I generated a class in Visual Studio:
http://pastebin.com/kUca0whm
Here is the code I am using:
public COM_Order GetOrderById(string orderId)
{
HttpClientHandler handler = new HttpClientHandler();
handler.Credentials = new NetworkCredential(m_UserName, m_Password);
HttpClient client = new HttpClient(handler)
{
};
string url = m_BaseUrl + String.Format("/rest/ecommerce.order/{0}", orderId);
HttpResponseMessage response = client.GetAsync(url).Result;
if (response.IsSuccessStatusCode)
{
data result = response.Content.ReadAsAsync<data>().Result;
//result is null, even though valid JSON is returned
return result.Items.FirstOrDefault();
}
return null;
}
Is there a problem with my class? I can also return JSON.

It says response.Content.ReadAsAsync().Result;
Are your sure result is populated before you return it?
In the debugger you have one behaviour, outside another.
Try turning ReadAsAsync off to see if it is the culprit.

Related

How to check the rest empty response in dotnet

I am using RestSharp for API calling in dotnet core. I have one endpoint on which sometimes I am getting empty response {} and when there is data it returns me the data.
I want to add this empty {} response check so currently, I am doing so.
var request = new RestRequest($"endpoint", Method.Get);
request.AddHeader("Content-Type", "application/json");
var response = client.Execute<EmployeeDetails>(getRequest);
How to check the rest empty response in dotnet
Altough, your code snippet were incomplete to simulate your issue. However, you could check your response data collection by simply checking response.Data.Count == 0.
Here is the complete example.
Asp.net Core C# Example:
public IActionResult GetAll()
{
HttpClientHandler clientHandler = new HttpClientHandler();
clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };
HttpClient httpClient = new HttpClient(clientHandler);
httpClient.BaseAddress = new Uri("https://localhost:44361/");
var restClient = new RestClient(httpClient);
var request = new RestRequest("UserLog/GetData", Method.Get) { RequestFormat = DataFormat.Json };
var response = restClient.Execute<List<QueryExecutionModel>>(request);
if (response.Data.Count == 0)
{
var emptyObject = new QueryExecutionModel();
return Ok(emptyObject);
}
return Ok(response.Data);
}
Note: When I am getting qualified response I am directly returning the response as Ok(response.Data). While I am getting the response model count = 0 then I am returing the empty model by new QueryExecutionModel()
Output:
Why did not use http client?
Plese Check it out!
https://www.c-sharpcorner.com/article/calling-web-api-using-httpclient/

Is there another way to receive JSON posted data (files) on an API end point?

I am trying to store documents to the server and i am uploading them from the client side using a form as an array of IFormFiles and then hitting the client controller and from the client controller i am getting an array of those documents and then Serializing them and sending them to the API end point as below.
public IActionResult UploadDocuments(Documents obj)
{
using (var client = new HttpClient())
{
var requestContent = new MultipartFormDataContent();
var jsonData = JsonConvert.SerializeObject(obj);
var contentString = new StringContent(jsonData, Encoding.UTF8);
requestContent.Add(contentString);
client.BaseAddress = new Uri("http://localhost:59104/");
var response = client.PostAsJsonAsync("api/Document", requestContent).Result;
if (response.IsSuccessStatusCode)
{
TempData["success"] = "Documents added Successfully";
return RedirectToAction("Documents", "Documents");
}
TempData["error"] = "Failed to add a document";
return RedirectToAction("Upload", "Documents");
}
}
When i upload the documents to the above controller, i am getting them but now the problem is receiving them on the API end point. If i remove the [FromBody] or [FromForm] above the API Controller tag, the APi endpoint is being hit but if either of those tags are not present i am receiving a null Documents object and an internal server error. Below is my API end point
public async Task<ActionResult<Documents>> AddDocuments([FromBody] Documents obj)
{
var documentsobj = HttpContext.Request.Form.Files;
//Do something with the document object
}
Is there a way i can receive that Document object from my API end point?

How to return whatever is returned from remote server?

I have the following WebClient code that is supposed my code acts as a proxy, and link to remote server, I would like to throw up whatever response that is returned from the remote server, how can I do so? I do not want to handle exceptions or anything, just merely throwing responses.
using (var client = new WebClient())
{
client.Headers[HttpRequestHeader.ContentType] = "application/json";
Uri NODE_LOGIN_PATH = new Uri(URI_Combine(NodeAPI, "auth/login"));
string jsonString = JsonConvert.SerializeObject(login_details);
JObject data = JObject.Parse(await client.UploadStringTaskAsync(NODE_LOGIN_PATH, jsonString));
return data;
}
You appear to be using WebClient in an MVC 4 project, so you're on old stuff. Consider upgrading to HttpClient and ASP.NET Core.
The principle that you want goes something like this:
public class FooController : ApiController
{
public HttpResponseMessage Get()
{
// Do the HTTP call
var httpResponse = client.DoSomeRequest();
// Translate
var apiResponse = new HttpResponseMessage
{
StatusCode = httpResponse.StatusCode.Map(...),
Headers = httpResponse.Headers.Map(...),
Body = httpResponse.Body.Map(...),
};
// Return
return apiResponse;
}
}
So: do the request, and translate (map) it to the HttpResponseMessage (or IHttpActionResult, or ...) that your Web API platform requires.

RestSharp "Error getting response stream (ReadAsync): ReceiveFailure Value cannot be null. Parameter name: src"

Hello all am trying to do a login to my xamarin api using RestSharp, the API ought to return status code 200 OK if the authentication works and status code 415 if the authentication fails(wrong password) and other codes depending on what the case scenario, but instead i get a status code 0 on all other case asides when the authentication pass(status code 200 ok), the source code below is how i implement
//payload am sending to the api
RequestPayload res = new RequestPayload();
res.appid = appid;
res.data = data;
res.method = "Login";
//convert to json object
var MySerializedObject = JsonConvert.SerializeObject(res);
string APIUrl = ""http://142.168.20.15:8021/RouteTask";
//create client
RestClient client = new RestClient(APIUrl);
//create request
RestRequest request = new RestRequest(Method.POST);
// set request headeer
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
//request.AddJsonBody(MySerializedObject); --i have also tried this
request.AddParameter("application/json", MySerializedObject, ParameterType.RequestBody);
request.JsonSerializer.ContentType = "application/json; charset=utf-8";
request.AddParameter("RequestSource", "Web", "application/json", ParameterType.QueryString);
client.Timeout = 2000000;
var response = client.Execute(request); // where the issue appears
//RestResponse response = client.Execute(request); // i have tried this
//IRestResponse response = client.Execute(request); // i have tried this
if (response.IsSuccessful)
{
//use response data
}
on all scenerio it comes back with a StatusCode: 0, Content-Type: , Content-Length: 0) and errorMessage
"Error getting response stream (ReadAsync): ReceiveFailure Value
cannot be null. Parameter name: src"
screenshot below indicate when the api call fails
Response receieved when the authentication is valid
I was finally able to find a workaround for this. Bear with the long-winded response.
The tags mention Xamarin, which is what I am working in as well - specifically with iOS. I think it may actually be a bug with Mono, but I didn't take it that far to confirm.
The problem lies with the default way of copying the response buffer. In the RestSharp code, this is done by an extension method in MiscExtensions.cs called ReadAsBytes. It appears that with certain response buffers, the call to the Stream.Read method is failing. When this happens, the exception causes RestSharp to "shortcut" the rest of the processing on the response, hence the status code never gets filled in since it happens after the call to ReadAsBytes.
The good news is RestSharp does give a way to replace this call to ReadAsBytes with one of your own. This is done via the ResponseWriter property on the IRestRequest object. If it has a function defined, it will bypass the ReadAsBytes call and call the function you gave it instead. The problem is, this is defined as an Action and you don't get a copy of the full response object, so it's somewhat useless. Instead you have to use the AdvancedResponseWriter property. This one includes both the response object and the response stream. But you still have to set the ResponseWriter property or it won't bypass the default handler and you'll still get the error.
Ok, so how do you make this work? I ended up implementing it as a wrapper to RestClient so I wouldn't have to implement the code all over the place. Here's the basic setup:
public class MyRestClient : RestClient
{
public MyRestClient(string baseUrl) : base(baseUrl)
{ }
public override IRestResponse Execute(IRestRequest request)
{
request.ResponseWriter = s => { };
request.AdvancedResponseWriter = (input, response) => response.RawBytes = ReadAsBytes(input);
return base.Execute(request);
}
private static byte[] ReadAsBytes(Stream input)
{
var buffer = new byte[16 * 1024];
using (var ms = new MemoryStream())
{
int read;
try
{
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{ ms.Write(buffer, 0, read); }
return ms.ToArray();
}
catch (WebException ex)
{ return Encoding.UTF8.GetBytes(ex.Message); }
};
}
}
The ReadAsBytes method is actually just a copy/paste of the RestSharp ReadAsBytes method with the addition of a try/catch. If it fails, it returns the exception reason in to the response buffer. This may or may not be what you want, so modify as needed. You may also need to override other methods for Execute, but in my case this is the only one we're using so it was enough.
So far this seems to be doing the trick for me. Perhaps if someone got ambitious they could trace it all the way in to Mono to try and see what it doesn't like about the stream, but I don't have the time for it at the moment.
Good luck!
OK so after toying around with RestSharp for a bit, i realize just as #steve_In_Co mentioned earlier there were compatibility issues with MONO (we presume this is a bug) so i did it in a basic way using the .Net HTTP library and it works for me, so in case someone is still looking for a way out, find the working .net http implementation code below.
//payload am sending to the api
RequestPayload res = new RequestPayload();
res.appid = appid;
res.data = data;
res.method = "Login";
//convert to json object
var MySerializedObject = JsonConvert.SerializeObject(res);
string APIUrl = ""http://142.168.20.15:8021/RouteTask";
//create basic .net http client
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(APIUrl);
// this was required in the header of my request,
// you may not need this, or you may need to adjust parameter
//("RequestSource","Web") or you own custom headers
client.DefaultRequestHeaders.Add("RequestSource", "Web");
// this class is custom, you can leave it out
connectionService = new ConnectionService();
//check for internet connection on users device before making the call
if (connectionService.IsConnected)
{
//make the call to the api
HttpResponseMessage response = await
client.PostAsJsonAsync(ApiConstants.APIDefault, res);
if (response.IsSuccessStatusCode)
{
string o = response.Content.ReadAsStringAsync().Result;
dynamic payload = JsonConvert.DeserializeObject(o);
string msg = payload["valMessage"];
resp.a = true;
resp.msg = payload["responseDescription"];
}
else
{
string o = response.Content.ReadAsStringAsync().Result;
dynamic payload = JsonConvert.DeserializeObject(o);
resp.a = false;
resp.msg = payload["response"];
}
}

Why Httpclient returns always the same result C# PCL?

I am using HttpClient PCL Class library. But When First Time I Get the JSON result It return correct data. After that HttpClient returns the same JSON result again and again for one URL till I close the application and start it again. My code looks like that
public class HttpService : IHttpService
{
public async Task<TResponseType> GetAsync<TResponseType>(string method, string parameters = null) where TResponseType : class
{
var uri = new Uri(string.Format(Constants.ServerUrl + method + parameters));
using (var client=new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
"c2Rzb2w6c2Rzb2w5OQ==");
var response = await client.GetAsync(uri);
var result = response.Content.ReadAsStringAsync().Result;
return JsonConvert.DeserializeObject<TResponseType>(result);
}
}
}
As stated in an answer for a different question, the solution is to set the IfModifiedSince property to prevent the default caching behaviour like this:
httpClient.DefaultRequestHeaders.IfModifiedSince = DateTime.Now;
You could also check on MSDN for more information.

Categories

Resources