How to Display byte image on the asp.net page dynamically? - asp.net

I have loaded an byte array image from a web service to my asp.net website.
I need to display it on the web page as soon as execute the web service.
I have tried using generic handler, but i could not do it since there wasn't way to pass byte[] image into the generic handler
void Button2_Click1(object sender, EventArgs e)
{
this.verifyTemplates();
byte[] userImg;
try
{
matchTemp.templateService hs = new matchTemp.templateService();
bool s1 = hs.matchTemplates(template, out userID, out userName, out userImg);
// userImg is the byte image i need to display
}
catch(Exception exc)
{
// vLabel.Text = exc.Message;
}
}

What you're looking for is a Data URL. You can get the base64 of a byte array like this (change the image type as required)
string imageBase64 = Convert.ToBase64String(userImg);
string imageSrc = string.Format("data:image/gif;base64,{0}", imageBase64);
In the view:
<img src='"<%=imageSrc%>"' />
This won't work in IE 7 or earlier, if you need to support those then you'll want to look at MHTML.

Related

Importing a asp.net webPart in WebForm website from .Webpart file programmatically (Not a sharePoint Project)

We have created several user Controls (Ascx) that we render to a webpart zone. Similarly, we have a control containing WebPartManager which is implemented in all the .aspx pages.
I am working on a feature where it is required to Import generated .webpart file on any page using a file upload control.
I am Using devExpress fileUpload control and upon FileUploadComplete Event executing the below-mentioned code.
The code Runs without any error but also doesn't display any web-part in the specified zone. Which is the problem.
protected void WebPartUploadControl_FileUploadComplete(object sender, FileUploadCompleteEventArgs e)
{
string ErrorMessge = string.Empty;
if (e.UploadedFile.IsValid)
{
var xmlReader = XmlReader.Create(e.UploadedFile.FileContent);
xmlReader.Read();
System.Web.UI.WebControls.WebParts.WebPart webPart = wpManager.ImportWebPart(xmlReader, out ErrorMessge);
wpManager.AddWebPart(webPart, wpManager.Zones["Zone5"], 1);
}
}
I might be missing some fundamental code. If anybody knows the answer kindly help. Thanks .
I finally figured out the issue. Just in case if someone in future come across a similar problem, this will help.
So, The problem here is the Devexpress File-Upload control is an ajax control, making partial postback thus not updating the CatalogZone of the page which is out of its scope.
The way to deal with it is :
Create a new .WebPart file and clone the content of the uploaded file.
Re-direct to the same page which fires Page_Load event
Execute the above code in the page_Load Event in order to import.
Below is the code to explain just that :
WebPartUploadControl_FileUploadComplete
protected void WebPartUploadControl_FileUploadComplete(object sender, FileUploadCompleteEventArgs e)
{
String WebPartFilePath = Server.MapPath("DirectoryWhereYouWantTosaveCloneFile");
String WebPartFileName = "NameOfYourCloneFile.WebPart";
string FileContent = string.Empty;
Creating Directory to store data of uploaded file(.webPart).
Session["ImportWebPartFilePath"] = $"{WebPartFilePath}/{WebPartFileName}";
if (!Directory.Exists(WebPartFilePath))
{
Directory.CreateDirectory(WebPartFilePath);
}
Reading Uploaded file Data
using (StreamReader sr = new StreamReader(e.UploadedFile.FileContent))
{
FileContent = sr.ReadToEnd();
}
//Copying File Data to the newly Created file
if (!File.Exists(Session["ImportWebPartFilePath"].ToString()))
{
File.AppendAllText(WebPartFilePath + "/" + WebPartFileName, FileContent);
}
e.CallbackData = "Page Settings Imported Successfully.";
// Response.Redirect(Request.RawUrl) does not work in while ajax callback in
devexpress
// Creating a callback to current page to trigger Page_Load event.
DevExpress.Web.ASPxWebControl.RedirectOnCallback(this.Request.Path);
}
Page_Load
if (Session["ImportWebPartFilePath"] != null)
{
//Import Webpart Settings
ImportWebPartsToCurrentPage(Session["ImportWebPartFilePath"].ToString());
File.Delete(Session["ImportWebPartFilePath"].ToString());
Session["ImportWebPartFilePath"] = null;
}
ImportWebPartsToCurrentPage
private void ImportWebPartsToCurrentPage(String FilePath)
{
string ErrorMessge = string.Empty;
//Extracting All WebParts in the file
XDocument WebPartXml = XDocument.Load(FilePath);
//Spliting the each webpart.
var WebPartDescriptions = WebPartXml.Root.Elements();
try
{
foreach (var WebPartDescription in WebPartDescriptions)
{
var xmlReader = XmlReader.Create(new StringReader(WebPartDescription.ToString()));
xmlReader.Read();
// Adding Webpart to page Catalog.
System.Web.UI.WebControls.WebParts.WebPart webPart = wpManager.ImportWebPart(xmlReader, out ErrorMessge);
//Adding webpart to the page.
if (!wpManager.WebParts.Contains(webPart))
{
wpManager.AddWebPart(webPart, wpManager.Zones["ZoneName"], 0);
}
}
}
catch (Exception ex)
{
Response.Write(ex);
}
}

Microsoft Custom Speech Service issue when using web socket url

so recently for a work project I've been playing around with speech to text models and in particular custom speech to text models. With a bit of mixing and matching examples I've managed to get a test application to talk to the normal Bing speech to text API. But when I attempt to use it with a custom speech instance only the HTTPS URL works. When I use any of the available long form web socket URLS the error An unhandled exception of type 'System.NullReferenceException' occurred in SpeechClient.dll occurs. This is a bit of a problem as that endpoint only supports 2 minutes of transcription, where as the websocket endpoint supports up to 10 minutes.
This https://learn.microsoft.com/en-us/azure/cognitive-services/custom-speech-service/customspeech-how-to-topics/cognitive-services-custom-speech-use-endpoint page here is what I'm going off of. It says that I should use a web socket url when creating the service, but that leads to the error above.
Here my test bed code for trying it out:
using System;
using Microsoft.CognitiveServices.SpeechRecognition;
using System.IO;
namespace ConsoleApp1
{
class Program
{
DataRecognitionClient dataClient;
static void Main(string[] args)
{
Program p = new Program();
p.Run(args);
}
void Run(string[] args)
{
try
{
// Works
//this.dataClient = SpeechRecognitionServiceFactory.CreateDataClient(SpeechRecognitionMode.LongDictation, "en-US", "Key");
// Works
//this.dataClient = SpeechRecognitionServiceFactory.CreateDataClient(SpeechRecognitionMode.LongDictation, "en-US",
// "Key", "Key",
// "https://Id.api.cris.ai/ws/cris/speech/recognize/continuous");
// Doesn't work
this.dataClient = SpeechRecognitionServiceFactory.CreateDataClient(SpeechRecognitionMode.LongDictation, "en-US",
"Key", "Key",
"wss://Id.api.cris.ai/ws/cris/speech/recognize/continuous");
this.dataClient.AuthenticationUri = "https://westus.api.cognitive.microsoft.com/sts/v1.0/issueToken";
this.dataClient.OnResponseReceived += this.ResponseHandler;
this.dataClient.OnConversationError += this.ErrorHandler;
this.dataClient.OnPartialResponseReceived += this.PartialHandler;
Console.WriteLine("Starting Transcription");
this.SendAudioHelper("Audio file path");
(new System.Threading.ManualResetEvent(false)).WaitOne();
} catch(Exception e)
{
Console.WriteLine(e);
}
}
private void SendAudioHelper(string wavFileName)
{
using (FileStream fileStream = new FileStream(wavFileName, FileMode.Open, FileAccess.Read))
{
// Note for wave files, we can just send data from the file right to the server.
// In the case you are not an audio file in wave format, and instead you have just
// raw data (for example audio coming over bluetooth), then before sending up any
// audio data, you must first send up an SpeechAudioFormat descriptor to describe
// the layout and format of your raw audio data via DataRecognitionClient's sendAudioFormat() method.
int bytesRead = 0;
byte[] buffer = new byte[1024];
try
{
do
{
// Get more Audio data to send into byte buffer.
bytesRead = fileStream.Read(buffer, 0, buffer.Length);
// Send of audio data to service.
this.dataClient.SendAudio(buffer, bytesRead);
}
while (bytesRead > 0);
}
finally
{
// We are done sending audio. Final recognition results will arrive in OnResponseReceived event call.
this.dataClient.EndAudio();
}
}
}
void ErrorHandler(object sender, SpeechErrorEventArgs e)
{
Console.WriteLine(e.SpeechErrorText);
}
void ResponseHandler(object sender, SpeechResponseEventArgs e)
{
if(e.PhraseResponse.RecognitionStatus == RecognitionStatus.EndOfDictation || e.PhraseResponse.RecognitionStatus == RecognitionStatus.DictationEndSilenceTimeout)
{
Console.WriteLine("Trnascription Over");
Console.ReadKey();
Environment.Exit(0);
}
for(int i = 0; i < e.PhraseResponse.Results.Length; i++)
{
Console.Write(e.PhraseResponse.Results[i].DisplayText);
}
Console.WriteLine();
}
void PartialHandler(object sender, PartialSpeechResponseEventArgs e)
{
}
}
}
Thanks in advance for any help.
so you are probably ok with using https ...
we are revisiting the SDKs right now (restructuring/reorganizing). I expect updates in the next couple of months.
Wolfgang
The new speech service SDK supports Custom Speech Service out-of-box. Please also check the samples RecognitionUsingCustomizedModelAsync() here for details.

write source files to output in custom asp.net server control

I am writing own server-side control.I need to use some images in this control.How can I write to output image file [or any other file] and then access it?
protected override void RenderContents(HtmlTextWriter output)
{
.......
output.Write("some file");
string endResult = "<img src= how to access this file? />"
output.Write(endResult);
}
Option 1: Embed It Directly
You can embed images (and other files) directly into webpages using a data URI. Something like:
protected override void RenderContents(HtmlTextWriter output)
{
............
byte[] rawImgData = []; //add your data here, maybe from a FileStream
String imgMimeType = "[img mime type, eg image/png]";
String encodedImgData = Convert.ToBase64String(rawImageData);
output.Write(String.Format("<img src=\"data:{0},{1}\" />", imageMimeType, encodedImageData))
}
As outlined in the link, this approach has lots of disadvantages. If you'll be serving the same images with every request to your control, you should really use static files.
Option 2: Save to the server and map it
Assuming your IIS worker account (normally called IUSR) has write access to some location on the server, you can save it with Server.MapPath and send the actual link out.
protected override void RenderContents(HtmlTextWriter output)
{
............
byte[] rawImgData = []; //add your data here, maybe from a FileStream
FileStream fileStream = System.IO.File.Create(Server.MapPath(virtualPath))
fileStream.Write(rawImgData, 0, rawImgData.Length)
fileStream.Close()
output.Write(String.Format("<img src=\"{0}\" />", virtualPath))
}
For repetitive requests, this definitely the best option.
Option 3: Store it in memory and serve via a second page
You can store the raw data in Session (or another temporary in-memory storage of your choice), send a link with an identifier, and server it from another page. Something like:
protected override void RenderContents(HtmlTextWriter output)
{
............
byte[] rawImgData = []; //add your data here, maybe from a FileStream
Session["MyImgTempStorage"] = rawImgData;
output.Write("<img src=\"ServeImgTempStorage.ashx?file=MyImgTempStorage\");
}
and make a generic handler called ServeImgTempStorage.ashx like this:
public class ServeImgTempStorage : System.Web.IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
string fileKey = context.Request.QueryString("file");
if (string.IsNullOrEmpty(fileKey)) {
return;
}
byte[] rawData = context.Session(fileKey);
context.Response.Write(rawData);
context.Response.ContentType = "[your mime type. you can force a download with attachment;]";
context.Response.End();
}
public bool IsReusable {
get { return false; }
}
}
You'll need to make sure you use session unique identifiers for every file served in this way, or you will overwrite data.
NOTE: My C# syntax may be off, I normally write in VB.

Capturing SOAP requests to an ASP.NET ASMX web service

Consider the requirement to log incoming SOAP requests to an ASP.NET ASMX web service. The task is to capture the raw XML being sent to the web service.
The incoming message needs to be logged for debug inspection. The application already has its own logging library in use, so the ideal usage would be something like this:
//string or XML, it doesn't matter.
string incomingSoapRequest = GetSoapRequest();
Logger.LogMessage(incomingSoapRequest);
Are there any easy solutions to capture the raw XML of the incoming SOAP requests?
Which events would you handle to get access to this object and the relevant properties?
Is there anyway IIS can capture the incoming request and push to a log?
You can also implement by placing the code in Global.asax.cs
protected void Application_BeginRequest(object sender, EventArgs e)
{
// Create byte array to hold request bytes
byte[] inputStream = new byte[HttpContext.Current.Request.ContentLength];
// Read entire request inputstream
HttpContext.Current.Request.InputStream.Read(inputStream, 0, inputStream.Length);
//Set stream back to beginning
HttpContext.Current.Request.InputStream.Position = 0;
//Get XML request
string requestString = ASCIIEncoding.ASCII.GetString(inputStream);
}
I have a Utility method in my web service that I use to capture the request when something happens that I am not expecting like a unhandled exception.
/// <summary>
/// Captures raw XML request and writes to FailedSubmission folder.
/// </summary>
internal static void CaptureRequest()
{
const string procName = "CaptureRequest";
try
{
log.WarnFormat("{0} - Writing XML request to FailedSubmission folder", procName);
byte[] inputStream = new byte[HttpContext.Current.Request.ContentLength];
//Get current stream position so we can set it back to that after logging
Int64 currentStreamPosition = HttpContext.Current.Request.InputStream.Position;
HttpContext.Current.Request.InputStream.Position = 0;
HttpContext.Current.Request.InputStream.Read(inputStream, 0, HttpContext.Current.Request.ContentLength);
//Set back stream position to original position
HttpContext.Current.Request.InputStream.Position = currentStreamPosition;
string xml = ASCIIEncoding.ASCII.GetString(inputStream);
string fileName = Guid.NewGuid().ToString() + ".xml";
log.WarnFormat("{0} - Request being written to filename: {1}", procName, fileName);
File.WriteAllText(Configuration.FailedSubmissionsFolder + fileName, xml);
}
catch
{
}
}
Then in web.config I store several AppSetting values that define what level I want to use to capture the request.
<!-- true/false - If true will write to an XML file the raw request when any Unhandled exception occurrs -->
<add key="CaptureRequestOnUnhandledException" value="true"/>
<!-- true/false - If true will write to an XML file the raw request when any type of error is returned to the client-->
<add key="CaptureRequestOnAllFailures" value="false"/>
<!-- true/false - If true will write to an XML file the raw request for every request to the web service -->
<add key="CaptureAllRequests" value="false"/>
Then in my Application_BeginRequest I have it modified like so. Note that Configuration is a static class I create to read properties from web.config and other areas.
protected void Application_BeginRequest(object sender, EventArgs e)
{
if(Configuration.CaptureAllRequests)
{
Utility.CaptureRequest();
}
}
One way to capture the raw message is to use SoapExtensions.
An alternative to SoapExtensions is to implement IHttpModule and grab the input stream as it's coming in.
public class LogModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.BeginRequest += this.OnBegin;
}
private void OnBegin(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication)sender;
HttpContext context = app.Context;
byte[] buffer = new byte[context.Request.InputStream.Length];
context.Request.InputStream.Read(buffer, 0, buffer.Length);
context.Request.InputStream.Position = 0;
string soapMessage = Encoding.ASCII.GetString(buffer);
// Do something with soapMessage
}
public void Dispose()
{
throw new NotImplementedException();
}
}
You know that you dont actually need to create a HttpModule right?
You can also read the contents of the Request.InputStream from within your asmx WebMethod.
Here is an article I wrote on this approach.
Code is as follows:
using System;
using System.Collections.Generic;
using System.Web;
using System.Xml;
using System.IO;
using System.Text;
using System.Web.Services;
using System.Web.Services.Protocols;
namespace SoapRequestEcho
{
[WebService(
Namespace = "http://soap.request.echo.com/",
Name = "SoapRequestEcho")]
public class EchoWebService : WebService
{
[WebMethod(Description = "Echo Soap Request")]
public XmlDocument EchoSoapRequest(int input)
{
// Initialize soap request XML
XmlDocument xmlSoapRequest = new XmlDocument();
// Get raw request body
Stream receiveStream = HttpContext.Current.Request.InputStream;
// Move to beginning of input stream and read
receiveStream.Position = 0;
using (StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8))
{
// Load into XML document
xmlSoapRequest.Load(readStream);
}
// Return
return xmlSoapRequest;
}
}
}
There are no easy ways to do this. You will have to implement a SoapExtension. The example at the previous link shows an extension that can be used to log the data.
If you had been using WCF, then you could simply set the configuration to produce message logs.
According to Steven de Salas, you can use the Request.InputStream property within the webmethod. I have not tried this, but he says that it works.
I would want to test this with both http and https, and with and without other SoapExtensions running at the same time. These are things that might affect what kind of stream the InputStream is set to. Some streams cannot seek, for instance, which might leave you with a stream positioned after the end of the data, and which you cannot move to the beginning.

Using ASP.NET AJAX UpdatePanel with Handlers

Im using UpdatePanel for some controls specially for captchas so, when a AsyncPostBack is performed triggered by a button "btnQuery", How can I tell to the .ashx (Handler for Captcha) to refresh it self?
Im using session to validate the Image on Captcha to the Num on the input below the image
this is the Handler :
<%# WebHandler Language="C#" Class="captcha" %>
using System;
using System.Web;
using System.Web.SessionState;
using System.Drawing;
public class captcha : IHttpHandler, IRequiresSessionState
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "image/GIF";
Bitmap imagen_GIF = new System.Drawing.Bitmap(80, 30);
Graphics grafico = System.Drawing.Graphics.FromImage(imagen_GIF);
grafico.Clear(Color.Gainsboro);
Font tipo_fuente = new Font("Comic Sans", 12, FontStyle.Bold);
string randomNum = string.Empty;
Random autoRand = new Random();
for (int x = 0; x < 5; x++)
{
randomNum += System.Convert.ToInt32(autoRand.Next(0, 9)).ToString();
}
int i_letra = System.Convert.ToInt32(autoRand.Next(65, 90));
string letra = ((char)i_letra).ToString();
randomNum += letra;
context.Session["RandomNumero"] = randomNum;
grafico.DrawString(randomNum, tipo_fuente, Brushes.Black, 5, 5);
imagen_GIF.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Gif);
tipo_fuente.Dispose();
grafico.Dispose();
imagen_GIF.Dispose();
}
public bool IsReusable { get { return false; } }
}
I want to refresh the image.. not just doing this :
public void postbackear()
{
string script = string.Format("Sys.WebForms.PageRequestManager.getInstance()._doPostBack('{0}', '');",
btnConsulta.ID);
ScriptManager.RegisterStartupScript(this.Page, typeof(string), "Refresh", script, true);
}
Try caching options for handlers such as
context.Response.Cache.SetExpires(DateTime.Now);
context.Response.Cache.SetCacheability(HttpCacheability.Public);
context.Response.Cache.SetValidUntilExpires(false);
If above not works only idea I got left is calling handler with queryString so that image source is not same any time you call
Image1.ImageUrl = "Handler.aspx?guid=" + Guid.NewGuid();
Is the image inside the UpdatePanel? I'd put it there if it isn't. Also, each time the panel updates, make sure the url for the image unique so that clients (browsers) or proxies won't use a cached image. A Guid tacked on as a querystring parameter should do the trick (e.g. YourImageHandler.ashx?xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).
Angel,
The image is not being requested again from the server, so there is no opportunity for the handler to execute. To get that to execute again, you must make the browser retrieve the image again.
That said, in your async postback, if nothing about the image is updated, the browser will have no reason to fetch it again regardless of cache settings, etc.
You could solve this with script, but an easier way is to take Myra's advice and append a GUID to the query string of the image and change that GUID as part of your async postback. This will update URL of the image needed on the client and force it to go back to the server to get the new image.
If this does not solve the problem, please post the section of your web.config that maps requests to the image handler as well as the code you use to add the image to the page.

Resources