How to download file from WebApi in ActionResult Asp.net Mvc C# - c#

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

How to get specific data from external API in ASP.Net

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

Download FileResult not working with Angular

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.

How to call a Function Task within the same controller using ASP.net MVC?

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();
}

asp.net core web api cant send object from client side

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");
}

Load JSON string to HttpRequestMessage

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<EventSyn‌​cResponse>> ;
//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<EventSyn‌​cResponse>> ;;
//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/

Categories

Resources