Need to display an image retrieved from WebApi call - image

I need to display an image as if using normal HTML, but I can't provide a normal url to the image for security reasons. Instead I need to retrieve the image from a WebApi service. I found this:
https://stackoverflow.com/a/24985886/1481314
And, I've looked at the links provided in the answers, but something isn't working. All I'm getting is a missing image placeholder.
This is my code - client-side:
angular.element('#' + imageType + '_' + itemID).html('<img src="/api/filemanagermaindata/getFile?systemName=' + baseData.CustomerData.SystemName + '&fileID=' + id + '" />')
This is my WebApi Controller Method
[HttpGet]
[Route("api/filemanagermaindata/getFile")]
public HttpResponseMessage GetFile(string systemName, int fileID)
{
var customerData = ValidateUser(systemName, 0);
var response = this.fileMover.GetFileDataHttpResponse(customerData.OrganizationID, fileID);
return response;
}
And my class method that gets and returns the image...
var response = new HttpResponseMessage();
try
{
FileManagerItem item = this.dataService.GetFileByID(fileID);
var fullPath = this.rootLocation + Path.Combine( item.PhysicalPath, item.Name);
if (!File.Exists(fullPath))
{
throw new Exception("Unable to locate the requested file");
}
var fileType = Path.GetExtension(item.Name).Replace(".", string.Empty);
if (ApplicationSettings.Instance.ImageFileExtensions.Contains(fileType))
{
fileType = string.Format("image/{0}", fileType);
}
using (FileStream fileStream = new FileStream(fullPath, FileMode.Open, FileAccess.Read))
{
response = new HttpResponseMessage { Content = new StreamContent(fileStream) };
response.Content.Headers.ContentType = new MediaTypeHeaderValue(fileType);
response.Content.Headers.ContentLength = fileStream.Length;
};
return response;
}

Dumb mistake. The using {} block was killing the FileStream before the data was loaded.

Related

How to download Image[Call API, API returns byte[] of image] from server and show it in contentpage in xamarin forms

Call Rest service
Rest service returns byte[] representation of image/audio/video
convert into byte[] to image and show in content page in xamarin
First of all, you can create a function that simply makes an API request and obtains the content in the form of byte array. A simple example of HTTP request:
public static byte[] GetImageByteArray(string url)
{
try
{
using (var client = new HttpClient())
{
var uri = new Uri(url);
var response = client.GetAsync(uri).Result;
if (response.IsSuccessStatusCode)
{
var content = response.Content.ReadAsByteArrayAsync();
return content.Result;
}
}
return null;
}
catch
{
return null;
}
}
Next, you can simply bind the output from your result into your image source and the image to your content:
var mainStack = new StackLayout();
var imageByteArray = GetImageByteArray("https://static.pexels.com/photos/34950/pexels-photo.jpg");
Image image;
if (imageByteArray != null)
{
image = new Image()
{
Source = ImageSource.FromStream(() => new MemoryStream(imageByteArray))
};
mainStack.Children.Add(image);
}
Content = mainStack;

How to use RESTful service in Xamarin.Forms to fetch JSON data

Since I am new to Xamarin, I would really appreciate if someone could explain me how to consume RESTful service (returning JSON data) using Xamarin Forms with the simplest example.
You can use JSON.net and HTTP request, here is a quick example of how to use the movie database which is a free movie database GET and POST examples, hope this helps:
const string _baseUrl = "http://api.themoviedb.org/3/";
const string _pageString = "&page=";
//GET Example
public static async Task<ObservableCollection<Movie>> GetTopRatedMoviesAsync(int page = 1)
{
HttpClient client = new HttpClient();
//_apiKey = themoviedb api key, page = page size 1 = first 20 movies;
string topRatedUrl = _baseUrl + "movie/top_rated?" + _apiKey + _pageString + page;
HttpResponseMessage result = await client.GetAsync (topRatedUrl, CancellationToken.None);
if (result.IsSuccessStatusCode) {
try{
string content = await result.Content.ReadAsStringAsync ();
ObservableCollection<Movie> MovieList = GetJsonData(content);
//return a ObservableCollection to fill a list of top rated movies
return MovieList;
}catch(Exception ex){
//Model Error
Console.WriteLine (ex);
return null;
}
}
//Server Error or no internet connection.
return null;
}
static ObservableCollection<Movie> GetJsonData(string content){
JObject jresponse = JObject.Parse (content);
var jarray = jresponse ["results"];
ObservableCollection<Movie> movieList = new ObservableCollection<Movie> ();
foreach (var jObj in jarray) {
Movie newMovie = new Movie();
newMovie.Title = (string)jObj["title"];
newMovie.PosterPath = _baseImgUrl + (string)jObj["poster_path"];
newMovie.HighResPosterPath = _baseImgUrl + (string)jObj["poster_path"];
newMovie.Id = (int)jObj["id"];
newMovie.Overview = (string)jObj["overview"];
newMovie.VoteCount = (double)jObj["vote_count"];
newMovie.ReleaseDate = (DateTime)jObj["release_date"];
newMovie.VoteAverage = (float)jObj["vote_average"];
movieList.Add(newMovie);
}
return movieList;
}
//POST Example:
public static async Task<bool> PostFavoriteMovieAsync(Movie movie)
{
try
{
HttpClient client = new HttpClient();
//_sessionId = string with the movie database session.
string tokenUrl = _baseUrl + "account/id/favorite?" + _apiKey + _sessionId;
string postBody = JsonConvert.SerializeObject(new Favorite{
favorite = !movie.Favorite,
media_id = movie.Id,
});
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await client.PostAsync (tokenUrl,
new StringContent (postBody, Encoding.UTF8, "application/json"));
if(response.IsSuccessStatusCode)
return true;
else
return false;
}
catch(Exception ex){
Console.WriteLine (ex.Message);
return false;
}
}

HTTP Post Windows Phone

I'm making a call to an API that consists in a HTTP Post request. The data i want to post is an image, properly converted into a byte array.
The response is not as expected, and i want to know what is the error: is it my code or is it the API? This is the code that i'm using
Image i = new Image();
BitmapImage bi = new BitmapImage(new Uri("/Images/dmoc.jpeg", UriKind.Relative));
testImage.Source = bi;
byte[] rawimage = ImageConverter.ImageToBytes(bi);
try
{
var baseAddress = new Uri("http://private-anon-6cf48a749-yugiohprices.apiary-mock.com/");
using (var httpClient = new HttpClient { BaseAddress = baseAddress })
{
//HttpRequestHeader.ContentType
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("image/jpeg"));
using (var response = await httpClient.PostAsync("api/match_card_image", new ByteArrayContent(rawimage)))
{
string responseData = await response.Content.ReadAsStringAsync();
postTxt.Text = responseData;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
MessageBox.Show(ex.StackTrace);
}
where ImageConverter is my class.

How do we set content-type to "text/plain" in asp.net web api

We are using asp.net web api in our application, in that we are trying to return the response with content-type with text/plain format but We are unable to succeeded. Same thing we tried with ASP.NET MVC it is working fine could you please provide me equivalent solution in Web API.
Please find below for the function implemented in ASP.NET MVC
public JsonResult FileUpload(HttpPostedFileBase file)
{
string extension = System.IO.Path.GetExtension(file.FileName);
string bufferData = string.Empty;
if (file != null)
{
using (MemoryStream ms = new MemoryStream())
{
file.InputStream.CopyTo(ms);
byte[] array = ms.GetBuffer();
var appendInfo = "data:image/" + extension + ";base64,";
bufferData = appendInfo + Convert.ToBase64String(array);
}
}
var result = new
{
Data = bufferData
};
return Json(result,"text/plain");
}
Could you please suggest same implementation in WebAPI.
Thanks,
Bhagat
Web Api does the JSON work for you, so you can simplify your code handling on the endpoint. By default, you need to make changes in your WebApiConfig.cs for everything to work nicely. I've modified your method below:
public HttpResponseMessage FileUpload(HttpPostedFileBase file) {
var result = new HttpResponseMessage(HttpStatusCode.NotFound);
var bufferData = string.Empty;
try
{
if (file != null)
{
var extension = System.IO.Path.GetExtension(file.FileName);
using (MemoryStream ms = new MemoryStream())
{
file.InputStream.CopyTo(ms);
var array = ms.GetBuffer();
var appendInfo = "data:image/" + extension + ";base64,";
bufferData = appendInfo + Convert.ToBase64String(array);
result.StatusCode = HttpStatusCode.OK;
// Set Headers and Content here
result.Content = bufferData;
}
}
}
catch(IOException ex)
{
// Handle IO Exception
}
return result
}
The changes you need to make in your WebApiConfig.cs could look like this:
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}",
defaults: null,
constraints: new { action = #"\D+" }
);
// This makes the response default into JSON instead of XML
config.Formatters.Remove(config.Formatters.XmlFormatter);
}
As a note, the very fastest fix you can make to your code would be to do this, but I don't recommend returning strings.
public string FileUpload(HttpPostedFileBase file) {
var result = new HttpResponseMessage(HttpStatusCode.NotFound);
var bufferData = string.Empty;
if (file != null)
{
var extension = System.IO.Path.GetExtension(file.FileName);
using (MemoryStream ms = new MemoryStream())
{
file.InputStream.CopyTo(ms);
var array = ms.GetBuffer();
var appendInfo = "data:image/" + extension + ";base64,";
bufferData = appendInfo + Convert.ToBase64String(array);
return bufferData;
}
}
// If you get here and have not returned,
// something went wrong and you should return an Empty
return String.Empty;
}
Good luck - there's lots of ways of handling files and file returns, so I want to assume you don't have some special return value on your handling.

Passing cookies to Image.GetInstance

Using image handler to convert relative path to absolute.
protected byte[] ConvertHTMLToPDF(string HTMLCode)
{
if (Request.Url == null)
throw new Exception();
var doc = new Document(PageSize.A4);
doc.Open();
var interfaceProps = new Hashtable();
var ih = new ImageHander {BaseUri = Request.Url.ToString()};
interfaceProps.Add("img_provider", ih);
foreach (IElement element in HTMLWorker.ParseToList(new StringReader(HTMLCode), null, interfaceProps))
{
doc.Add(element);
}
var _xmlr = new XmlTextReader(new StringReader(HTMLCode));
HtmlParser.Parse(doc, _xmlr);
var stream = new MemoryStream();
PdfWriter.GetInstance(doc, stream);
doc.Close();
return stream.ToArray();
}
class:
public class ImageHander : IImageProvider
{
public string BaseUri;
public Image GetImage(string src, Hashtable h, ChainedProperties cprops, IDocListener doc)
{
string imgPath;
if (src.ToLower().Contains("http://") == false)
imgPath = HttpContext.Current.Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Authority + src;
else
imgPath = src;
return Image.GetInstance(imgPath);
}
}
imgPath at the end is correct. But it's not static file, it's url of action that returns image, so I need to pass cookies when requesting image. Is it possible?
Yes, it is possible, but you're gonna have to send the request yourself and not rely on the Image.GetInstance method. For example using the HttpClient you could send cookies along with the request:
var imageUrl = new Uri(imagePath);
var cookieContainer = new CookieContainer();
using (var handler = new HttpClientHandler { CookieContainer = cookieContainer })
using (var client = new HttpClient(handler))
{
cookieContainer.Add(
new Uri(imageUrl.GetLeftPart(UriPartial.Authority)),
new Cookie("CookieName", "cookie_value")
);
var response = client.GetAsync(imageUrl).Result;
response.EnsureSuccessStatusCode();
Stream imageStream = response.Content.ReadAsStreamAsync().Result;
// You've got the Stream here, read the documentation of iTextSharp
// how to create an Image instance from a Stream:
return Image.FromStream(imageStream); // ?????
// or maybe there's a method allowing you to create an Image from byte[]
byte[] imageData = new byte[imageStream.Length];
imageStream.Read(imageData, 0, imageData.Length);
return Image.FromByteArray(imageData); // ?????
}

Resources