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)
Related
I am trying to fetch the holiday data from an external API in asp.net. The fetch works, but I'd like to use it as a reference on the annual date.
cspublic string Get()
{
HttpClient http = new HttpClient();
http.DefaultRequestHeaders.Add("APIKey", "Application/Json");
var data = http.GetAsync(url).Result.Content.ReadAsStringAsync().Result;
return data;
}
i have this code in my repository file to get external api
i want to get is_national_holiday == true
https://api-harilibur.vercel.app/api
[
{
"holiday_date": "2021-01-1",
"holiday_name": "Tahun Baru Masehi",
"is_national_holiday": true
},
{
"holiday_date": "2021-01-12",
"holiday_name": "Hari Siwa Ratri",
"is_national_holiday": false
},
{
"holiday_date": "2021-01-30",
"holiday_name": "Hari Saraswati",
"is_national_holiday": false
},
{
"holiday_date": "2021-02-12",
"holiday_name": "Tahun Baru Imlek 2572 Kongzili",
"is_national_holiday": true
}
]
Update :
Repository
public async Task<HoliDate> GetHolidaysAsync()
{
var client = new RestClient($"https://api-harilibur.vercel.app/api");
var request = new RestRequest(Method.GET);
IRestResponse response = await client.ExecuteAsync(request);
if (response.IsSuccessful)
{
var content = JsonConvert.DeserializeObject<JToken>(response.Content);
var holidayCaption = content["holiday_date"].Value<DateTime>();
var holidays = content.SelectTokens("aa")
.Select(team => new Holiday
{
holiday_date = (DateTime)team["holiday_date"],
holiday_name = (string)team["holiday_name"],
is_national_holiday = (bool)team["is_national_holiday"]
})
.ToList();
//return the model to my caller.
return new HoliDate
{
HolidayCaption = holidayCaption,
Holiday = holidays
};
}
Console.WriteLine(response.Content);
return null;
}
Controller
[Route("Holiday")]
[HttpGet]
public async Task<IActionResult> GetByIdAsync() {
var model = await repository.GetHolidaysAsync();
if (model == null)
return NotFound();
return Ok(model);
}
Model Holiday
public class HoliDate
{
public DateTime HolidayCaption { get; set; }
public IEnumerable<Holiday> Holiday { get; set; }
}
}
An unhandled exception occurred while processing the request.
ArgumentException: Accessed JArray values with invalid key value: "HolidayCaption". Int32 array index expected.
Newtonsoft.Json.Linq.JArray.get_Item(object key)
LeaveAPI.Repository.Data.LeaveDetailRepository.GetHolidaysAsync() in LeaveDetailRepository.cs
+
var holidayCaption = content["HolidayCaption"].Value();
LeaveAPI.Controllers.LeaveDetailsController.GetByIdAsync() in LeaveDetailsController.cs
+
var model = await repository.GetHolidaysAsync();
enter image description here
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.
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();
}
this is server code who cath the request from client side
[HttpPost("Add")]
public async Task<IActionResult> Add([FromBody]RequestAdd person)
{
if(person != null){
return Ok("good");
}
return Ok("false");
}
this is code is client post there i add to multipart json and image bytes
public Task<HttpResponseMessage> Uploads(Person person, List<FileInfo> files)
{
try
{
var jsonToSend = JsonConvert.SerializeObject(person, Formatting.None);
var multipart = new MultipartFormDataContent();
var body = new StringContent(jsonToSend, Encoding.UTF8, "application/json");
multipart.Add(body, "JsonDetails");
foreach (var item in files)
{
var fileContent = new ByteArrayContent(System.IO.File.ReadAllBytes(item.FullName));
multipart.Add(fileContent, item.FullName);
}
var client = new HttpClient();
client.BaseAddress = new Uri(BASE_URL);
return client.PostAsync("Add", multipart);
}
catch
{
return null;
}
}
code where i use this method there i have error
static void Main(string[] args)
{
Method2();
Console.ReadLine();
}
static void Method2()
{
UploadMultiPart uploadMultiPart = new UploadMultiPart();
List<FileInfo> fileInfos = new List<FileInfo>()
{
new FileInfo(#"C:\asd\full-metal-jacket.png"),
new FileInfo(#"C:\asd\full-metal-jacket.png"),
new FileInfo(#"C:\asd\full-metal-jacket.png")
};
Person person = new Person
{
Name = "Adilbek",
SureName = "Ramazanov",
Position = "God",
Group = "heaven",
Phone = 123123
};
var result = loadMultiPart.Uploads(person,fileInfos).Result;
Console.WriteLine("Status is " + result.StatusCode);
}
error code is Status is UnsupportedMediaType
i dont have idea how to send to server, please help me sorry my bad english
Use the [FromForm] attribute, not [FromBody] attribute.
[HttpPost("Add")]
public async Task<IActionResult> Add([FromForm]RequestAdd person)
{
if(person != null){
return Ok("good");
}
return Ok("false");
}
I'm writing some tests for my WebAPI web service and cannot figure out how to send JSON to my service method in the test.
ScheduleRequest sr = new ScheduleRequest();
sr.Months = null;
sr.States = null;
sr.Zip = null;
sr.Miles = null;
sr.PCodes = null;
sr.PageStart = 1;
sr.PageLimit = 10;
HttpRequestMessage m = new HttpRequestMessage();
string sr_ = JsonConvert.SerializeObject(sr);
// How do I load it into the HttpRequestMessage???
// m.Content. = sr_;
var controller = new ShoppingCartController();
// Call the controlelr method and test if the return data is correct.
EventSyncResponse res = (EventSyncResponse)controller.CourseSchedule(m);
Am I doing this correctly, too?
Controller Code:
public object CourseSchedule(ScheduleRequest request)
{
try
{
var result = cart.GetCourseSchedule(request);
return Ok(result);
}
catch (Exception ex)
{
if (ex.Message.StartsWith(#"ORA-20001"))
{
return Ok(new ParticipantResponse { FirstName = "No record found" });
}
throw ex;
}
}
[TestClass]
public class ShoppingCartControllerTests {
[TestMethod]
public void TestCourseSchedule() {
//Arrange
var sr = new ScheduleRequest();
sr.Months = null;
sr.States = null;
sr.Zip = null;
sr.Miles = null;
sr.PCodes = null;
sr.PageStart = 1;
sr.PageLimit = 10;
var json = JsonConvert.SerializeObject(sr);
//construct content to send
var content = new System.Net.Http.StringContent(json, Encoding.UTF8, "application/json");
var request = new HttpRequestMessage {
RequestUri = new Uri("http://localhost/api/shoppingcart"),
Content = content
};
var controller = new ShoppingCartController();
//Set a fake request. If your controller creates responses you will need this
controller.Request = request;
//Act
// Call the controller method and test if the return data is correct.
var response = controller.CourseSchedule(request) as OkNegotiatedContentResult<List<EventSyncResponse>> ;
//Assert
//...other asserts
}
}
But I get the impression that your Action should actually be refactored like this in your controller
public class ShoppingCartController : ApiController {
public IHttpActionResult CourseSchedule(ScheduleRequest model) { ... }
}
which would mean that your isolated unit test should be refactored to...
[TestClass]
public class ShoppingCartControllerTests {
[TestMethod]
public void TestCourseSchedule() {
//Arrange
var sr = new ScheduleRequest();
sr.Months = null;
sr.States = null;
sr.Zip = null;
sr.Miles = null;
sr.PCodes = null;
sr.PageStart = 1;
sr.PageLimit = 10;
var controller = new ShoppingCartController();
//Set a fake request. If your controller creates responses you will need this
controller.Request = new HttpRequestMessage {
RequestUri = new Uri("http://localhost/api/shoppingcart"),
};
//Act
// Call the controller method and test if the return data is correct.
var response = controller.CourseSchedule(sr) as OkNegotiatedContentResult<List<EventSyncResponse>> ;;
//Assert
//...
}
}
MB34.
You need to add in your method, a ScheduleRequest parameter too.
Check this link:
http://www.lybecker.com/blog/2013/06/26/accessing-http-request-from-asp-net-web-api/