Need Help Getting HTML out of Razor View in ASP.NET Core With Action Result Filter - asp.net-core

I'm following Steve Smith's article on how to use Filters in ASP.NET Core. Specifically, I want to get the HTML after it has been processed by the razor view engine. I've created an action filter and decorated my controller as follows yet I still get an empty html string from the stream. I think it has something to do with using the Result and not the Context but I'm not sure. Here is my code:
[AppendToHtmlBodyFilter]
public IActionResult Videos()
{
return View();
}
public void OnResultExecuted(ResultExecutedContext context)
{
Stream originalStream = context.HttpContext.Response.Body;
using (MemoryStream newStream = new MemoryStream())
{
context.HttpContext.Response.Body = newStream;
context.HttpContext.Response.Body = originalStream;
newStream.Seek(0, SeekOrigin.Begin);
StreamReader reader = new StreamReader(newStream);
var htmlData = reader.ReadToEnd();
}

Related

Consume API into aspnet core 2.2

I have a web API which returns about 1000 records into json. Now I want to get all those records from json response and deserialize into a model
The code i have written so far is like following:
public async Task<IActionResult> GetList()
{
Facility facilityInfo = new Facility();
using (var httpClient = new HttpClient())
{
using (var response = await httpClient.GetAsync("http://localhost:55555/api/Facilities"))
{
string apiResponse = await response.Content.ReadAsStringAsync();
facilityInfo = JsonConvert.DeserializeObject<Facility>(apiResponse);
}
}
//-----------other parts of code-----------------
return View();
}
The problem is that it returns null facilityInfo
Thank you
You're deserializing something that has a property called items which is a list of Facilities. So if you have the following structure:
public class Facilities
{
public List<Facility> items;
}
And then
Facilities facilities = JsonConvert.DeserializeObject<Facilities>(apiResponse);
The facilities.items property will contain the data.

asp.net core render a view into stringwriter

So I want to build an Html custom builder which passes a model object to a partial view and renders the page into a StringWriter
public static class HtmlExtensions
{
public static HtmlString BuildTextboxFor(this IHtmlHelper helper, object model)
{
//Find the partial view and pass the Model through it.
//Render the page into a StringWriter
//return new HtmlString(StringWriter object);
}
}
The models name will be the name of the partial. I can't seem to find a solution for .NET CORE. All the resources seem to be for ASP.NET Framework.
IHtmlHelper.Partial returns IHtmlContent, HtmlString is just another implementation of the same abstraction. Looking at your sample code this is the desired result (not a StringWriter)
public static HtmlString BuildTextboxFor(this IHtmlHelper helper, object model) {
return helper.Partial($"~/Views/{model.GetType().Name}.cshtml", model)
}
If you still want to write the view to a StringWriter its not a problem:
var content = helper.Partial($"~/Views/{model.GetType().Name}.cshtml", model);
using(var writer = new StringWriter()) {
content.WriteTo(writer, HtmlEncoder.Default);
}

How to create an ASP.NET Core API controller action for HttpPost that can accept a request that has content of type MultipartFormDataContent

I am working on an ASP.NET Core 2.0 API in VS2017.
I want to create a controller action for an HTTP Post method that accept string and byte[] values that I will then use to create records in my SQL database.
From what I understand, if I want to post both string data and a byte[] that represents a file, I have to use MultipartFormDataContent as the type of content in the request from my client.
So, on the API controller action, how is that mapped? Can I have a DTO class in the API that has properties for both the string values and the byte[] value and have it passed into the API controller action via the [FromBody]UploadsDto dto
For example, have a DTO class like this...
public class UploadFileRecordForCreationDto
{
public int LocationId { get; set; }
public string FileName { get; set; }
public byte[] UploadedFile { get; set; }
}
Then have a controller action with this signature...
[HttpPost(Name = "CreateUploadFileRecord")]
public IActionResult CreateUploadFileRecord([FromBody]UploadFileRecordForCreationDto dto)
{
...
...
...
return CreatedAtRoute("GetUploadedFileFile", new { id = linkedResourceToReturn["Id"] }, linkedResourceToReturn);
}
And then have that API action accept a request created using something similar to what I am doing with this test console application on the client side;
static async Task CreateUploadFileRecordAsync()
{
httpClient.BaseAddress = new Uri("https://localhost:44369");
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
string relativeUrl = "/api/UploadFilesManager";
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, relativeUrl);
HttpResponseMessage response = new HttpResponseMessage();
using (var content = new MultipartFormDataContent("--UploadTest"))
{
var values = new[]
{
new KeyValuePair<string,string>("LocationId","1"),
new KeyValuePair<string,string>("FileName","TestFile-01.txt"),
};
foreach (var keyvaluepair in values)
{
content.Add(new StringContent(keyvaluepair.Value, Encoding.UTF8, "application/json"), keyvaluepair.Key);
}
var fileContent = new ByteArrayContent(File.ReadAllBytes(#"C:\testfile-01.txt"));
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue(DispositionTypeNames.Attachment)
{
Name = "UploadedFile",
FileName = "testfile-01.txt"
};
content.Add(fileContent);
request.Content = content;
response = await httpClient.SendAsync(request);
}
if (response.IsSuccessStatusCode)
{
string result = response.Headers.Location.ToString();
Console.WriteLine("Success:\n");
Console.WriteLine($"New Record Link: [{result}]\n");
}
else
{
Console.WriteLine($"Failed to create new UploadFile record. Error: {0}\n", response.ReasonPhrase);
}
}
If it doesn't just map to a DTO in the FromBody, can anyone provide an example of how to deal with this use case?

Return an image from asp.net web api core as IActionResult

What is the best way to return an image file as IActionResult while using asp.net web api core?
I tried returning a base64 string and it works fine. But not considered as efficient.
Is there a way using which we can return an image file object itself as IActionResult.
You can use the various overloads of the File() function in controllers that inherit from Controller or ControllerBase.
For example, you can do:
return File("~/Images/photo.jpg", "image/jpeg");
This uses a virtual path, other options include giving it a byte array or a Stream. You can also give a download file name as a third argument if that is needed.
[Route("getProductImage/v1")]
[HttpGet]
public async Task<IActionResult> getProductImage(GetProductImageQueryParam parammodel)
{
using (HttpClient client = new HttpClient())
{
MNimg_URL = MNimg_URL + parammodel.modelname;
HttpResponseMessage response = await client.GetAsync(MNimg_URL);
byte[] content = await response.Content.ReadAsByteArrayAsync();
//return "data:image/png;base64," + Convert.ToBase64String(content);
return File(content, "image/png", parammodel.modelname);
}
}
In .net core web api you can use the above code
here GetProductImageQueryParam is a class with input parameters
A File result is called FileContentResult in NET Core 3.x.
You can return image using return file with stream or bytes format or using its image path.
There are few overloaded methods for return File(//parameters); which you can use it in mvc controller's action method.
API Controller
[Route("api/[controller]")]
public class FileController : Controller {
//GET api/file/id
[HttpGet("{id}"]
public async Task<IActionResult> GetFile(string id) {
var stream = await {{//__get_stream_here__//}};
var response = File(stream, "application/octet-stream"); // FileStreamResult
return response;
}
}
or
var imageFileStream = System.IO.File.OpenRead("// image path");
return File(imageFileStream, "image/jpeg");
Hope this will help you.

Return Image using IHttpActionResult

I have a requirement to return an image from a WebApi using IHttpActionResult instead of HttpResponseMessage. How this can be achieved & what are the accept & content type headers need to be passed?
Thanks!!
I was actually looking for a solution to send an image resides on internet from web api but I am returning local thumbnail images from my web api with the following code;
[HttpGet]
[Route("thumbnail/{userId}/{fileName}")]
public IHttpActionResult GetThumbnail()
{
var mediaRoot = System.Web.HttpContext.Current.Server.MapPath("~/media");
var imgPath = Path.Combine(mediaRoot, "images", userId, "thumbnail", fileName);
var fileInfo = new FileInfo(imgPath);
return !fileInfo.Exists
? (IHttpActionResult)NotFound()
: new FileResult(fileInfo.FullName);
}
Hope this helps
Edit: You should create a custom IHttpActionResult to retun images,
It seems i have created a custom IHttpActionResult to return images and here is the post that i got this code from > Custom IHttpActionResult
This would be a basic way:
[HttpGet]
[Route("test")]
public IHttpActionResult GetImageTest()
{
var stream = File.OpenRead(#"C:\picture.jpg");
var response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content = new StreamContent(stream);
response.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpg");
response.Content.Headers.ContentLength = stream.Length;
return ResponseMessage(response);
}