I'm trying to down load the file(pdf,word,excel) which is saved as bytes[] in DB and below is my code. But getting error(Unexpected token error) when calling the method the method.
Please guide me to fix it.
Controller Code:
[HttpPost]
public async Task<FileResult> AttachmentById([FromBody]ReviewAttachmentModel attachmentRequest)
{
ReviewAttachmentModel model = new ReviewAttachmentModel();
try
{
ReviewAttachmentDto reviewAttachmentDto = new ReviewAttachmentDto
{
DocumentKey = attachmentRequest.DocumentKey,
ReviewKey = attachmentRequest.ReviewKey,
UserId = attachmentRequest.UserId,
};
ReviewAttachmentDto _attachmentDto = reviewAttachmentDto;
string requestBody = JsonConvert.SerializeObject(_attachmentDto);
//Call API
string _responseObj = await WebAPIHelper.PostDataToAPI(appSettings.ReviewAttachmentUrl, requestBody, this.loggedinUser.CookieCollection, accessToken);
model = JsonConvert.DeserializeObject<ReviewAttachmentModel>(_responseObj);
// model.Document - byte[]
return File(model.Document, model.DocumentType, model.DocumentName);
}
catch (Exception ex)
{
return null;
}
}
Service.ts:
public downloadReviewAttachment(reviewAttachmentModel: any): Observable<any> {
this._urlSurveillanceDetails = this.baseHref + "/ReviewProfile/AttachmentById";
const headers: HttpHeaders = new HttpHeaders();
headers.append('Content-Type', 'application/octet-stream');
return this.http.post<any>(this._urlSurveillanceDetails, reviewAttachmentModel, { headers: headers });
}
Component.ts:
onAttachmentDownload(documentKey: any, reviewKey: any) {
let reviewAttachmentModel: any = {
documentKey: documentKey,
reviewKey: reviewKey
};
this._surveillanceService.downloadReviewAttachment(reviewAttachmentModel).subscribe(data => {
if (data != undefined) {
}
})
}
Error:
Change this:
public downloadReviewAttachment(reviewAttachmentModel: any): Observable<any> {
this._urlSurveillanceDetails = this.baseHref + "/ReviewProfile/AttachmentById";
const headers: HttpHeaders = new HttpHeaders();
headers.append('Content-Type', 'application/octet-stream');
return this.http.post<any>(this._urlSurveillanceDetails, reviewAttachmentModel, { headers: headers });
}
To this:
public downloadReviewAttachment(reviewAttachmentModel: any): Observable<blob> {
this._urlSurveillanceDetails = this.baseHref + "/ReviewProfile/AttachmentById";
return this.http.post(this._urlSurveillanceDetails, reviewAttachmentModel, { responseType: 'blob'});
}
By removing the generic argument and add the responseType that you want. Angular knows what it has to be done.
Related
A method called GetFile is written to a WebApi project that returns HttpResponseMessage:
WebApi Controller I am using NReco.PdfGenerated library
[HttpGet]
[Route("GetFile")]
[NoCache]
public HttpResponseMessage GetFile()
{
try
{
var httpRequest = HttpContext.Current.Request;
var html = HttpUtility.UrlDecode(httpRequest.Headers["_GetFile"] ?? "");
if (string.IsNullOrWhiteSpace(html))
{
return null;
}
var response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StreamContent(new MemoryStream(new HtmlToPdfConverter().GeneratePdf(html)))
};
response.Content.Headers.ContentType =
new System.Net.Http.Headers.MediaTypeHeaderValue("application/pdf");
return response;
}
catch
{
}
return null;
}
In another project, I want to connect to the GetFile method via ActionResult and get that file. ActionResult is written as follows:
Request Class:
public class GeneratedHtmlToPdfRequest
{
[AllowHtml]
public string Html { get; set; }
}
Controller (Asp.net Mvc):
[HttpPost]
public ActionResult GeneratedHtmlToPdf(GeneratedHtmlToPdfRequest request)
{
var userData = CookieController.GetUserDataCookie(CookieController.SGP_PORTAL_ALL_USER);
string encodeText = HttpUtility.UrlEncode(request.Html);
var response = var response = WebController.CallApiWithHeader(
"http://baseUrlWebApi.com" , "GetFile",
"_GetFile",
encodeText).Result; //call web api method
var result = response.ReadAsByteArrayAsync().Result;
TempData[WebVariables.TEMP_DATA_FILE] = result;
return Json(new PostGeneratedHtmlToPdf()
{
RedirectUrl = WebController.GetCurrentWebsiteRoot() + "***/***/FileDownload/" + DateTime.Now.ToString("yyyyMMddHHmmss")
});
}
[HttpGet]
public virtual ActionResult FileDownload(string id)
{
var tempByte = (byte[]) TempData[WebVariables.TEMP_DATA_FILE];
TempData[WebVariables.TEMP_DATA_FILE] = tempByte;
return File(tempByte , "application/pdf" , id);
}
Function (Call web api)
public static async Task<HttpContent> CallApiWithHeader(string url ,string methodName , string headerName = "", string header = "")
{
try
{
HttpClient client = new HttpClient {BaseAddress = new Uri(url)};
client.DefaultRequestHeaders.Add(headerName , header);
return client.GetAsync(methodName).Result.Content;
}
catch (Exception ex)
{
return null;
}
}
jquery is written that calls the GeneratedHtmlToPdf method:
window.$('body').on('click',
'#bDownload',
function(event) {
event.preventDefault();
var html = window.$('#layoutLegalBill').html();
window.$('#layoutLegalBill').html(ShowLayoutLoading());
const formData = new FormData();
formData.append('request.Html', html);
var xmlHttpRequest = new XMLHttpRequest();
if (!window.XMLHttpRequest) {
xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlHttpRequest.open(
"POST",
'#Url.Action("GeneratedHtmlToPdf", "***", new {area = "***"})',
true);
xmlHttpRequest.onerror = function() {
ShowAlert(ErrorText(), 'dark', true);
};
xmlHttpRequest.onloadend = function() {
window.$('#layoutLegalBill').html(html);
var response = ParseJson(xmlHttpRequest.responseText);
window.location = response.RedirectUrl;
}
xmlHttpRequest.send(formData);
});
The problem is that the file is downloaded but does not open and gives an error.
(The file is 17kb in size)
I am using Angular 8.I sending image to my ApiController to save the image.
I have used before Angular 7 all was working,after upgrade to Angular 8 i dont receive the file.
I see the name and the length of the file in the console when i sendit,but i dont see it in Api.
What i am missing here?
My Angular ts
import { timeout } from 'rxjs/operators';
import { UserClaims } from './../../authentication/models/user-claims.model';
import { PrivateZoneLoginService } from './../private-zone-login.service';
import { Component, OnInit } from '#angular/core';
import { MatBottomSheetRef } from '#angular/material/bottom-sheet';
import { HttpClient } from '#angular/common/http';
import { LocalStorageService } from 'src/app/app-services/local-storage.service';
import { PrivateZoneConstants } from '../private-zone-constans';
#Component({
selector: 'app-bottom-sheet',
templateUrl: './bottom-sheet.component.html',
styleUrls: ['./bottom-sheet.component.css']
})
export class BottomSheetComponent implements OnInit {
token = this.pzLogin.userLoginAccessToken;
public imagePath;
imgURL: any = this.pzLogin.UserLoginClaims.ImageUrl;
public message: string;
fileData = new FileReader();
reader = new FileReader();
fileUploaded: boolean = false;
loading: boolean = false;
constructor(
private _bottomSheetRef: MatBottomSheetRef<BottomSheetComponent>,
private http: HttpClient, private pzLogin: PrivateZoneLoginService,
private localStorageService: LocalStorageService) { }
openLink(event: MouseEvent): void {
this._bottomSheetRef.dismiss();
event.preventDefault();
}
ngOnInit() {
}
preview(event) {
if (event.files.length === 0) {
return;
}
const mimeType = event.files[0].type;
if (mimeType.match(/image\/*/) == null) {
this.message = 'Only images are supported.';
return;
}
const fileSize = event.files[0].size;
if (fileSize > 500839) {
this.message = 'Maximum upload file size 200 kb.';
return;
}
this.reader.readAsDataURL(event.files[0]);
this.reader.onload = () => {
this.imgURL = this.reader.result;
this.fileData = event.files;
this._bottomSheetRef.containerInstance.enter();
};
}
onSubmit() {
this.loading = true;
const formData = new FormData();
formData.append('UploadedFile', this.fileData[0], this.fileData[0].name);
formData.append('token',this.token);
this.http.post(PrivateZoneConstants.UploadUserImage, formData)
.subscribe(res => {
this.localStorageService.setItem('UserLoginClaims', res);
this.fileUploaded = true;
this.loading = false;
this._bottomSheetRef.containerInstance.enter();
});
setTimeout(() => {
this._bottomSheetRef.dismiss();
}, 6000);
}
}
My Api
[HttpPost]
[AcceptVerbs("GET", "POST", "OPTIONS")]
[AllowAnonymous]
public IHttpActionResult UploadUserImage()
{
HttpRequest httpRequest = HttpContext.Current.Request;
int i = httpRequest.Files.Count; // here count is 0
HttpPostedFile postedFileTest = httpRequest.Files[0];
}
You need to add headers by your self.
And check that your HttpInterceptor does not overwriting your headers
This will fix the problem
const HttpUploadOptions = new HttpHeaders();
HttpUploadOptions.append('Content-Type', 'multipart/form-data');
HttpUploadOptions.append('Accept', 'image/x-png,image/gif,image/jpeg');
this.http.post(PrivateZoneConstants.UploadUserImage, formData,
{
headers: HttpUploadOptions,
reportProgress: true
}).subscribe(res => {
this.localStorageService.setItem('UserLoginClaims', res);
this.fileUploaded = true;
this.loading = false;
this._bottomSheetRef.containerInstance.enter();
});
I'm having a hard time calling a function within the same controller.
This is my function that calls the GetToken Function
[HttpPost]
public ActionResult FileLoad()
{
using (var reader = new StreamReader("C:\\somedirectory\\Payout.csv"))
using (var csv = new CsvReader(reader))
{
csv.Configuration.RegisterClassMap<FundTransferMap>();
var json = JsonConvert.SerializeObject(csv.GetRecords<FundTransfer>());
//Response.Write(json);
TempData["FileJson"] = json;
return RedirectToAction("GetToken");
}
}
This is the function that should be called by the first function
[HttpPost]
private async Task<ActionResult> GetToken()
{
var client = new HttpClient();
var httpRequestMessage = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri("https://some-url.com//token"),
Headers = {
//{ HttpRequestHeader.Authorization.ToString(), "Bearer xxxxxxxxxxxxxxxxxxxx" },
{ HttpRequestHeader.Accept.ToString(), "application/json" },
{ HttpRequestHeader.ContentType.ToString(), "application/x-www-form-urlencoded"},
{ "client-id", "client-id"},
{ "client-secret","client-secret"},
{ "partner-id","partner-id"},
{ "X-Version", "1" }
},
Content = new FormUrlEncodedContent(new Dictionary<string, string>
{
{ "client_id", "clientid" },
{ "grant_type", "password" },
{ "username", "username" },
{ "password", "p#ssw0rd" },
{ "scope", "scope" }
})
};
var response = client.SendAsync(httpRequestMessage).Result;
var payload = JObject.Parse(await response.Content.ReadAsStringAsync());
TempData["accessToken"] = payload.Value<string>("access_token");
}
return View();
But this code produces an error on runtime because it's an àsync function I also don't wanted the second function to return something.
I would suggest to rewrite your GetToken() method to return the token as a string.
private async Task<string> GetToken()
{
var client = new HttpClient();
// removed code for clarity
var response = client.SendAsync(httpRequestMessage).Result;
var payload = JObject.Parse(await response.Content.ReadAsStringAsync());
var token = payload.Value<string>("access_token");
return Task.FromResult(token);
}
Then you can easily call this method from any other controller method where you need to get the token:
[HttpPost]
public ActionResult FileLoad()
{
// removed code for clarity
// call method GetToken();
var token = await GetToken();
}
I have an ASP.NET Core 2.0 Web API Integrated with ionic 3.
I'm having problems receiving JSON data sent from ionic 3 App, Here is sample code:-
import { Injectable } from '#angular/core';
import { Http, Headers } from '#angular/http';
import 'rxjs/add/operator/map';
import { AlertController, LoadingController } from 'ionic-angular';
import { FCM } from '#ionic-native/fcm';
#Injectable()
export class ServerProvider {
private baseurl = "http://localhost:9681/api";
private api: String[] = new Array();
public loader: any;
constructor(public fcm: FCM, public http: Http, public alertCtrl:
AlertController, public loadingCtrl: LoadingController) {
this.api['auth'] = 'Authentication';
this.api['agency'] = 'Agencies';
this.api['user'] = 'Users';
this.api['route'] = 'Routes';
this.api['token'] = 'Tokens';
this.api['notification'] = 'Notifications';
this.api['salepoint'] = 'Salepoints';
}
ServerRequest(api, request, data) {
return new Promise((resolve) => {
let headers = new Headers();
headers.append('Content-Type', 'application/json; charset=UTF-8');
this.http.get(this.baseurl + "/" + this.api[api] + "/", {headers: headers}).map(res => res.json()).subscribe((result) => {
resolve(result);
console.log(result);
}, (error) => {
console.log(error); this.CreateAlert("Error", error, [
{
text: 'Close',
handler: () => {
this.loader.dismiss();
}
}
]);
}, () => {
this.loader.dismiss();
});
});
}
Backend:-
[Route("api/Authentication")]
public class AuthenticationController : Controller
{
IConfiguration _configuration;
public AuthenticationController(IConfiguration configuration)
{
_configuration = configuration;
}
[HttpGet]
public JsonResult GetUser(JsonResult json)
{
AgencyUsers agencyusers = new AgencyUsers(_configuration);
return Json(agencyusers.GetUser(json));
}
}
I receive the following error:-
An unhandled exception occurred while processing the request.
InvalidOperationException: Could not create an instance of type
'Microsoft.AspNetCore.Mvc.JsonResult'. Model bound complex types must
not be abstract or value types and must have a parameterless
constructor.
What is the correct way to receive (serialize and deserialize JSON) and send back JSON (data or errors)?
After a lot of digging and modifications, I have finally got the API to work fine.
In case someone ran into a problem similar to mine, Here what I did:-
At Ionic, I have changed the HTTP request from GET to POST.
ServerRequest(api, request, data) {
return new Promise((resolve) => {
let headers = new Headers();
headers.append('Content-Type', 'application/json; charset=UTF-8');
this.http.post(this.baseurl + "/" + this.api[api] + "/" + request, JSON.stringify(data),{headers:headers}).map(res => res.json()).subscribe((result) => { ... });}
At Backend, Used newtonsoft (JObject) Which saved me a lot of head that JsonResult causes, Then Changed Method type to IActionResult.
[HttpPost("GetAgencyUser")]
public IActionResult GetAgencyUser([FromBody]JObject request)
{
try
{
if (request["id"] == null)
{
return Ok("id is not defined or incorrect JSON format");
}
AgencyUsersMethods agencyusers = new AgencyUsersMethods(_configuration);
var result = agencyusers.GetAgencyUser(request);
if (result == null)
{
return Ok("User not Found");
}
else
{
return Ok(result);
}
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
I have an ASP.NET Core 1.0 Web API application and trying to figure out how to pass the exception message to the client if a function that my controller is calling errors out.
I have tried so many things, but nothing implements IActionResult.
I don't understand why this isn't a common thing that people need. If there truthfully is no solution can someone tell me why?
I do see some documentation out there using HttpResponseException(HttpResponseMessage), but in order to use this, I have to install the compat shim. Is there a new way of doing these things in Core 1.0?
Here is something I have been trying with the shim but it isn't working:
// GET: api/customers/{id}
[HttpGet("{id}", Name = "GetCustomer")]
public IActionResult GetById(int id)
{
Customer c = _customersService.GetCustomerById(id);
if (c == null)
{
var response = new HttpResponseMessage(HttpStatusCode.NotFound)
{
Content = new StringContent("Customer doesn't exist", System.Text.Encoding.UTF8, "text/plain"),
StatusCode = HttpStatusCode.NotFound
};
throw new HttpResponseException(response);
//return NotFound();
}
return new ObjectResult(c);
}
When the HttpResponseException is thrown, I look on the client and can't find the message I am sending anything in the content.
Here is an simple error DTO class
public class ErrorDto
{
public int Code {get;set;}
public string Message { get; set; }
// other fields
public override string ToString()
{
return JsonConvert.SerializeObject(this);
}
}
And then using the ExceptionHandler middleware:
app.UseExceptionHandler(errorApp =>
{
errorApp.Run(async context =>
{
context.Response.StatusCode = 500; // or another Status accordingly to Exception Type
context.Response.ContentType = "application/json";
var error = context.Features.Get<IExceptionHandlerFeature>();
if (error != null)
{
var ex = error.Error;
await context.Response.WriteAsync(new ErrorDto()
{
Code = <your custom code based on Exception Type>,
Message = ex.Message // or your custom message
// other custom data
}.ToString(), Encoding.UTF8);
}
});
});
Yes it is possible to change the status code to whatever you need:
In your CustomExceptionFilterAttribute.cs file modify the code as follows:
public class CustomExceptionFilterAttribute : ExceptionFilterAttribute
{
public override void OnException(ExceptionContext context)
{
var exception = context.Exception;
context.Result = new ContentResult
{
Content = $"Error: {exception.Message}",
ContentType = "text/plain",
// change to whatever status code you want to send out
StatusCode = (int?)HttpStatusCode.BadRequest
};
}
}
That's pretty much it.
If you have custom exceptions, then you can also check for them when grabbing the thrown exception from the context. Following on from that you can then send out different HTTP Status Codes depdending on what has happened in your code.
Hope that helps.
You can create a custom Exception Filter like below
public class CustomExceptionFilterAttribute : ExceptionFilterAttribute
{
public override void OnException(ExceptionContext context)
{
var exception = context.Exception;
context.Result = new JsonResult(exception.Message);
}
}
Then apply the above attribute to your controller.
[Route("api/[controller]")]
[CustomExceptionFilter]
public class ValuesController : Controller
{
// GET: api/values
[HttpGet]
public IEnumerable<string> Get()
{
throw new Exception("Suckers");
return new string[] { "value1", "value2" };
}
}
Rather than raising and catching an exception, how about you simplify your action to:
// GET: api/customers/{id}
[HttpGet("{id}", Name = "GetCustomer")]
public IActionResult GetById(int id)
{
var customer = _customersService.GetCustomerById(id);
if (customer == null)
{
return NotFound("Customer doesn't exist");
}
return Ok(customer);
}
I wrote a blog post with some more options such as returning a JSON object instead of text.
Maybe that is helpful. You can return just object and sent for example a BadRequest (HTTP CODE: 400) with your custom object as actual parameter (I just used an interpolated string here) but you can put in anything.
In your client side you can catch that error situation for example with an AJAX error handler.
// GET: api/TruckFahrerGeoData
[HttpGet]
public object GetTruckFahrerGeoData()
{
var truckFahrerGeoDataItems = new List<TruckFahrerGeoDataViewModel>();
var geodataItems = _context.TruckFahrerGeoData;
foreach (var truckFahrerGeoData in geodataItems)
{
GeoTelemetryData geoTelemetryData = JsonConvert.DeserializeObject<GeoTelemetryData>(truckFahrerGeoData.TelemetryData);
if (geoTelemetryData == null)
{
return BadRequest($"geoTelemetryData null for id: {truckFahrerGeoData.Id}");
}
TruckFahrerGeoDataViewModel truckFahrerGeoDataViewModel = new TruckFahrerGeoDataViewModel
{
Speed = geoTelemetryData.Speed,
Accuracy = geoTelemetryData.Accuracy,
TruckAppId = geoTelemetryData.Activity.TruckAppId,
TruckAuftragStatusId = geoTelemetryData.Activity.TruckAuftragStatusId,
ClId = geoTelemetryData.Activity.ClId,
TruckAuftragLaufStatusId = geoTelemetryData.Activity.TruckAuftragLaufStatusId,
TaskId = geoTelemetryData.Activity.TaskId,
TruckAuftragWorkflowStatusId = geoTelemetryData.Activity.TruckAuftragWorkflowStatusId
};
truckFahrerGeoDataItems.Add(truckFahrerGeoDataViewModel);
}
return truckFahrerGeoDataItems;
}
Or an even more cleaner way with IActionResult like that way:
// GET: api/TruckFahrerGeoData
[HttpGet]
public IActionResult GetTruckFahrerGeoData()
{
var truckFahrerGeoDataItems = new List<TruckFahrerGeoDataViewModel>();
var geodataItems = _context.TruckFahrerGeoData;
foreach (var truckFahrerGeoData in geodataItems)
{
GeoTelemetryData geoTelemetryData = JsonConvert.DeserializeObject<GeoTelemetryData>(truckFahrerGeoData.TelemetryData);
if (geoTelemetryData == null)
{
return BadRequest($"geoTelemetryData null for id: {truckFahrerGeoData.Id}");
}
TruckFahrerGeoDataViewModel truckFahrerGeoDataViewModel = new TruckFahrerGeoDataViewModel
{
Speed = geoTelemetryData.Speed,
Accuracy = geoTelemetryData.Accuracy,
TruckAppId = geoTelemetryData.Activity.TruckAppId,
TruckAuftragStatusId = geoTelemetryData.Activity.TruckAuftragStatusId,
ClId = geoTelemetryData.Activity.ClId,
TruckAuftragLaufStatusId = geoTelemetryData.Activity.TruckAuftragLaufStatusId,
TaskId = geoTelemetryData.Activity.TaskId,
TruckAuftragWorkflowStatusId = geoTelemetryData.Activity.TruckAuftragWorkflowStatusId
};
truckFahrerGeoDataItems.Add(truckFahrerGeoDataViewModel);
}
return Ok(truckFahrerGeoDataItems);
}
Late to the party but refining the answer .
Define your error response class with minimum below attributes
using Microsoft.AspNetCore.Http;
public class ErrorResponse
{
private readonly RequestDelegate next;
public ErrorResponse(RequestDelegate next)
{
this.next = next;
}
public async Task Invoke(HttpContext context )
{
try
{
await next(context);
}
catch (Exception ex)
{
await HandleExceptionAsync(context, ex);
}
}
private static Task HandleExceptionAsync(HttpContext context, Exception ex)
{
var code = HttpStatusCode.InternalServerError;
string result = string.Empty;
object data = new object();
if (ex is ForbiddenException)
{
code = HttpStatusCode.Forbidden;
result = JsonConvert.SerializeObject(new Response<object>(Status.Forbidden(ex.Message), data));
}
else if(ex is BadRequestException){
code = HttpStatusCode.BadRequest;
result = JsonConvert.SerializeObject(new Response<object>(Status.BadRequest(ex.Message), data));
}
else if (ex is NotFoundException)
{
code = HttpStatusCode.NotFound;
result = JsonConvert.SerializeObject(new Response<object>(Status.NotFound(ex.Message), data));
}
else if (ex is UnauthorizedException)
{
code = HttpStatusCode.Unauthorized;
result = JsonConvert.SerializeObject(new Response<object>(Status.Unauthorized(ex.Message), data));
}
else
{
result = JsonConvert.SerializeObject(new Response<object>(Status.InternalServerError(ex.Message), data));
}
context.Response.ContentType = "application/json";
context.Response.StatusCode = (int)code;
return context.Response.WriteAsync(result);
}
}
Next use this class as middleware in startup.cs class
app.UseHttpsRedirection();
app.UseMiddleware(typeof(ErrorResponse));
Now each request and response will go through this class,if an error occurs then error code will be set to true with error code. A sample response like below
data: {}
status: {
code: 404
error: true
message: "No employee data found"
type: "Not Found"
}
I had the same problem and after some research, I found out I could use HttpClient to call my API and read the response easily. HttpClient does not throw any error when the HTTP response contains an error code, but it sets the IsSuccessStatusCode property to false.
This is my function using the HttpClient. I call this from my controller.
public static async Task<HttpResponseMessage> HttpClientPost(string header, string postdata, string url)
{
string uri = apiUrl + url;
using (var client = new HttpClient())
{
//client.BaseAddress = new Uri(uri);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", header);
HttpResponseMessage response = await client.PostAsync(uri, new StringContent(postdata));
return response;
}
}
This is my controller code, where I call the function and read the response and determine whether I have an error or not and respond accordingly. Note that I am checking the IsSuccessStatusCode.
HttpResponseMessage response;
string url = $"Setup/AddDonor";
var postdata = JsonConvert.SerializeObject(donor);
response = await ApiHandler.HttpClientPost(HttpContext.Session.GetString(tokenName), postdata, url);
//var headers = response.Headers.Concat(response.Content.Headers);
var responseBody = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
tnxresult = JsonConvert.DeserializeObject<TnxResult>(AppFunctions.CleanResponse(responseBody));
return Json(new
{
ok = true,
message = tnxresult.Message,
statusCode = tnxresult.StatusCode
});
}
else
{
ApiError rs = JsonConvert.DeserializeObject<ApiError>(AppFunctions.CleanResponse(responseBody));
return Json(new
{
ok = false,
message = rs.Message,
statusCode = rs.StatusCode
});
}
My API returns error messages in JSON. If the call is successful, I am packing the response in JSON too.
The crucial line of code is this one...
var responseBody = await response.Content.ReadAsStringAsync();
It serializes the HTTP content to a string as an asynchronous operation.
After that I can convert my JSON string to an object and access the error/success message and the Status Code too.