I have a fairly simple Action in an MVC3 application that should render an image...
public FileStreamResult Photo(int id)
{
//get the raw bytes for the photo
var qry = from p in db.Photos
where p.PhotoID == id
select p.PhotoData;
var data = qry.FirstOrDefault();
var mem = new MemoryStream(data);
var fs = new FileStreamResult(mem, "image/jpeg");
return fs;
}
When i run this i get a blank document in Chrome, Firefox displays the URL in the actual document area and IE renders the raw bytes.
Chrome gives me a message: Resource interpreted as Document but transferred with MIME type image/jpeg
This suggests to me that the stream data is not being sent to the browser and it is in fact receiving an empty document, but IE suggests the opposite.
Anyone come across this before, or know how to get around it?
You don't need a stream if you already have a byte array of the photo:
public ActionResult Photo(int id)
{
var data = db.Photos.FirstOrDefault(p => p.PhotoID == id);
if (data == null)
{
return HttpNotFound();
}
return File(data.PhotoData, "image/jpeg");
}
The problem with your code is that you need to reset the memory stream at the beginning but as I said you don't need all this.
Related
I need to use PushStreamContent because of the source of my data (effectively have to concatenate blobs), but I also have to support requests for multiple byte ranges (arbitrary ranges not aligned to the stored blobs). What is not clear to me is if I can use PushStreamContent to generate a multipart/byteranges response, if each range needs to be separated in the response, and if so, how to do it, and how it relates to the chunked transfer encoding which PushStreamContent invokes.
You can do it using MultipartContent like this:
public class MyRangeController : ApiController
{
[HttpGet]
public HttpResponseMessage Get()
{
// Create a multi-part content object for the response; note that per RFC spec, subtype must be "byteranges"
// Note that the content type of the over-all response will be "multipart/byteranges"
// We choose to use a GUID string for the separator; it could be anything suitable.
var multipartContent = new MultipartContent("byteranges", Guid.NewGuid().ToString("D"));
// Create the response object and set its content
var response = new HttpResponseMessage(HttpStatusCode.PartialContent) { Content = multipartContent };
foreach (var rangeItemHeaderValue in Request.Headers.Range.Ranges)
{
// Create PushStreamContent object for our current byte range...
var pushStreamContent = new PushStreamContent((stream1, content, arg3) =>
{
// Write to stream1
stream1.Close();
});
// We need to add certain headers to each part of the response
pushStreamContent.Headers.ContentRange = new ContentRangeHeaderValue(rangeItemHeaderValue.From.Value, rangeItemHeaderValue.To.Value, /* total size of the resource */);
pushStreamContent.Headers.ContentType = new MediaTypeHeaderValue(/* Set a content type for each part of the response */);
// Add the part to the multi-part content response
multipartContent.Add(pushStreamContent);
}
return response;
}
}
I have a url that when paste it into browser address display an image.This url call a method of webapi that return an image.I need to get image code by string format and save into database .
I use this code :
var client = new HttpClient();
var barcode = client.GetAsync("https://store.zirbana.com/v2/barcode/render?text=234501").Result;
This code has result but How can i get image from this?
You can extract the content of the response as a byte array and convert that to a base64 string to be saved in the database.
public async Task<string> GetBarCode(string attachmentUrl) {
using (var client = new HttpClient()) {
using (var response = await client.GetAsync(attachmentUrl)) {
var bytes = await response.Content.ReadAsByteArrayAsync();
var base64String = Convert.ToBase64String(bytes);
return base64String;
}
}
}
If you meant interpreting the image to then you need to use a barcode reader to scan the image and get the actual code stored in the image.
I have looked at other similar questions (such as this one Is there a way to force ASP.NET Web API to return plain text?) on SO but they all seem to address WebAPI 1 or 2, not the latest version you use with MVC6.
I need to return plain text on one of my Web API controllers. Only one - the others should keep returning JSON. This controller is used for dev purposes to output a list of records in a database, which will be imported into a traffic load generator. This tool takes CSV as input so I'm trying to output that (users will only have to save the content of the page).
[HttpGet]
public HttpResponseMessage AllProductsCsv()
{
IList<Product> products = productService.GetAllProducts();
var sb = new StringBuilder();
sb.Append("Id,PartNumber");
foreach(var product in products)
{
sb.AppendFormat("{0},{1}", product.Id, product.PartNumber);
}
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new StringContent(sb.ToString(), System.Text.Encoding.UTF8, "text/plain");
return result;
}
Based on various searches this seems like the simplest way to proceed since I'll need this only for this one action. However when I request this, I get the following output:
{
"Version": {
"Major": 1,
"Minor": 1,
"Build": -1,
"Revision": -1,
"MajorRevision": -1,
"MinorRevision": -1
},
"Content": {
"Headers": [
{
"Key": "Content-Type",
"Value": [
"text/plain; charset=utf-8"
]
}
]
},
"StatusCode": 200,
"ReasonPhrase": "OK",
"Headers": [],
"RequestMessage": null,
"IsSuccessStatusCode": true
}
So it seems that MVC still tries to output JSON, and I have no idea why they'd output these values. When I debug the code step by step I can see that the content of the StringBuilder is okay and what I want to output.
Is there any easy way to just output a string with MVC6?
Have a go with this:
var httpResponseMessage = new HttpResponseMessage();
httpResponseMessage.Content = new StringContent(stringBuilder.ToString());
httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("text/plain");
return httpResponseMessage;
The solution was to return a FileContentResult. This seems to bypass the built-in formatters:
[HttpGet]
public FileContentResult AllProductsCsv()
{
IList<Product> products = productService.GetAllProducts();
var sb = new StringBuilder();
sb.Append("Id,PartNumber\n");
foreach(var product in products)
{
sb.AppendFormat("{0},{1}\n", product.Id, product.PartNumber);
}
return File(Encoding.UTF8.GetBytes(sb.ToString()), "text/csv");
}
This might be a bit too specific for here and I may need to contact redactor support but i've seen other questions about redactor here so i figured i'd give it a shot ...
Ok ...
So i'm trying to get get image uploading to work following the example here ...
http://imperavi.com/redactor/docs/images/
My client side code ...
$("textarea").redactor({
focus: true,
imageUpload: '/MyController/UploadImage'
});
My MVC controller action looks like this ...
public JsonResult UploadImage(object image)
{
// Do something with whatever that was i got from redactor
var result = new { filelink = "" };
return Json(result);
}
The problem is ... what did redactor actually give me?
Was it the whole file? a chunk? i can't seem to tell because the object has no type information at all and the raw post information seems way too little to actually be a whole image file.
Has anyone had any experience with this / actually done it before?
I don't really want to setup php on my server for this 1 function.
EDIT:
Ok a bit more digging reveals that if i pull the underlying Request object it has a files property which apparently contains my posted image file.
I think i might be able to figure it out from here.
Where I get a code block in place i'll post it as an answer.
You are receiving a HttpPostedFileBase object. Here is my implementation:
jQuery:
$('#blog-post').redactor(
{
imageUpload: '/blog/images/',
imageGetJson: '/images/locations/blogs/'
});
Then in the controller:
public ActionResult Images(HttpPostedFileBase file)
{
// Verify that the user selected a file
if( file != null && file.ContentLength > 0 )
{
// extract only the fielname
var fileName = Path.GetFileName( file.FileName );
// store the file
var path = Path.Combine( ImageLocation.BlogPicturePath, fileName );
file.SaveAs( path );
}
return Json( new { filelink = ImageLocation.BlogPictureUrl + "/" + file.FileName } );
}
ok um ... i think im there ...
This needs a bit of cleaning up and I don't expect you guys to understand what goes on under the bonnet of my custom DMS code but just assume it takes the stream and returns a FileInfo object and in theory this should work for you too ...
public ActionResult Upload()
{
// this object is specific to my system but all it does is
// stream the file to a path on the server (code not needed for this Q)
var dmsService = _kernel.Get<IDMSFileSystemService>();
List<FileInfo> savedFiles = new List<FileInfo>();
for (int i = 0; i < Request.Files.Count; i++)
{
var file = Request.Files[i];
using (file.InputStream)
{
savedFiles.Add(dmsService.AddFromStream(file.InputStream, file.FileName);
}
}
var result = savedFiles.Select(f => new { filelink = f.Path}).ToArray();
return Json(result);
}
Suprisingly simple right ... :)
Is it possible to integrate SSRS reports to the webforms..an example will be enough to keep me moving.
Absolutely it is.
What you are looking for is the ReportViewer control, located in the Microsoft.Reporting.WebForms assembly. It will allow you to place a control right on your web form that will give people an interface for setting report parameters and getting the report.
Alternatively you can set all the parameters yourself and output the report in whatever format you need. We use it in our application to output PDF.
For instance - this is how we setup a reportviewer object for one of our reports and get the PDF, and then send it back to the user. The particular code block is a web handler.
public void ProcessRequest(HttpContext context)
{
string report = null;
int managerId = -1;
int planId = -1;
GetParametersFromSession(context.Session, out report, out managerId, out planId);
if (report == null || managerId == -1 || planId == -1)
{
return;
}
CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture;
List<ReportParameter> parameters = new List<ReportParameter>();
parameters.Add(new ReportParameter("Prefix", report));
parameters.Add(new ReportParameter("ManagerId", managerId.ToString()));
parameters.Add(new ReportParameter("ActionPlanId", planId.ToString()));
string language = Thread.CurrentThread.CurrentCulture.Name;
language = String.Format("{0}_{1}", language.Substring(0, 2), language.Substring(3, 2).ToLower());
parameters.Add(new ReportParameter("Lang", language));
ReportViewer rv = new ReportViewer();
rv.ProcessingMode = ProcessingMode.Remote;
rv.ServerReport.ReportServerUrl = new Uri(ConfigurationManager.AppSettings["ReportServer"]);
if (ConfigurationManager.AppSettings["DbYear"] == "2007")
{
rv.ServerReport.ReportPath = "/ActionPlanning/Plan";
}
else
{
rv.ServerReport.ReportPath = String.Format("/ActionPlanning{0}/Plan", ConfigurationManager.AppSettings["DbYear"]);
}
rv.ServerReport.SetParameters(parameters);
string mimeType = null;
string encoding = null;
string extension = null;
string[] streamIds = null;
Warning[] warnings = null;
byte[] output = rv.ServerReport.Render("pdf", null, out mimeType, out encoding, out extension, out streamIds, out warnings);
context.Response.ContentType = mimeType;
context.Response.BinaryWrite(output);
}
this is a knowledge base article which describes how to render report output to an aspx page in a particular file format.
http://support.microsoft.com/kb/875447/en-us
Be warned that you will lose some functionality such as the parameter selection stuff when you do not use the URL Access method.
Report server URL access supports HTML Viewer and the extended functionality of the report toolbar. The SOAP API does not support this type of rendered report. You need to design and develop your own report toolbar, if you render reports using SOAP.
http://msdn.microsoft.com/en-us/library/ms155089.aspx