I'm currently developing a BizTalk Custom Send Pipeline that accepts an xml file and converts it to Excel. Unfortunately, after deploying the pipeline, I'm receiving a System.OutOfMemoryException. I've included the code for Execute Method of IComponent interface. All suggestions are welcome.
public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(IPipelineContext pContext, Microsoft.BizTalk.Message.Interop.IBaseMessage inmsg)
{
MemoryStream outMemStream = new MemoryStream();
try
{
if (inmsg.BodyPart.Data != null)
{
// Read the source message coming from the messaging engine and convert it to memory stream
byte[] buffer = new byte[16 * 1024];
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = inmsg.BodyPart.Data.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
buffer = ms.ToArray();
}
if (buffer != null)
{
var binaryWriter = new BinaryWriter(outMemStream);
binaryWriter.Write(buffer);
}
OpenXMLOffice oOffice = new OpenXMLOffice();
outMemStream.Position = 0;
oOffice.XMLToExcel(outMemStream, TemporaryFileLocation);
inmsg.BodyPart.Data.Position = 0;
inmsg.BodyPart.Data = outMemStream;
pContext.ResourceTracker.AddResource(outMemStream);
}
return inmsg;
}
catch (Exception ex)
{
throw new ApplicationException(String.Format("Error converting XML to Excel:{0} - Stack Trace: {1}", ex.Message, ex.StackTrace));
}
}
Here is the most recent error received:
Log Name: Application
Source: BizTalk Server
Date: 2/14/2012 9:29:00 AM
Event ID: 5754
Task Category: BizTalk Server
Level: Error
Keywords: Classic
User: N/A
Computer: IASDev-PC
Description:
A message sent to adapter "FILE" on send port "ExcelSendPort" with URI "C:\SeleneFTPFile\Excel\%MessageID%.xml" is suspended.
Error details: There was a failure executing the send pipeline: "IAS.SeleneFTPFile.ExcelEncodePipeline, IAS.SeleneFTPFile, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2add433e7764165f" Source: "Excel File Encoder" Send Port: "ExcelSendPort" URI: "C:\SeleneFTPFile\Excel\%MessageID%.xml" Reason: Error converting XML to Excel:Exception of type 'System.OutOfMemoryException' was thrown. - Stack Trace: at System.IO.MemoryStream.set_Capacity(Int32 value)
at System.IO.MemoryStream.EnsureCapacity(Int32 value)
at System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count)
at IAS.SeleneFTPFile.Components.ExcelPipeline.EncodeExcel.Execute(IPipelineContext pContext, IBaseMessage inmsg)
MessageId: {ED37CDD1-EF0C-46E7-9519-061AF3D4F8A4}
InstanceID: {B0E448B3-3DAD-4E52-8F87-07C5D5AA5224}
You could try pre-allocating the MemoryStream buffer (as suggested here). The error message states that it can't allocate enough memory for the line when performing the buffered write (ms.Write(buffer, 0, read);).
using (MemoryStream ms = new MemoryStream(buffer.Length))
The other issue you have is that your buffer could overflow - producing this exact error when the MemoryStream is written to (ms.Write(buffer, 0, read)).
byte[] buffer = new byte[2 * 1024 * 1024]; // try increasing to 2MB buffer
Even I face the same issue. I can find that the reason is the stream position does not advance and remains at 0 for the inmsg.BodyPart.Data stream, even after the below statement executes:
read = inmsg.BodyPart.Data.Read(buffer, 0, buffer.Length)
Related
I am trying to upload files using Renci.SshNet, but the connection times out each time, although i can connect successfully using SFTP client (filezilla).
I have used the below code and each time I get exception in the line (sftp.Connect). I get an exception "An exception of type 'Renci.SshNet.Common.SshOperationTimeoutException' occurred in Renci.SshNet.dll"
{"Socket read operation has timed out"}
ConnectionInfo connectionInfo = new PasswordConnectionInfo(host, port, username, password);
using (var client = new SftpClient(host, port, username, password))
{
client.Connect();
//Log.Info("Connected to SFTP", this);
// byte[] byteArray = Encoding.UTF8.GetBytes(csv);
FileStream streams = File.OpenRead(#"c:\sftp\Test.csv");
byte[] fileBytes = new byte[streams.Length];
streams.Read(fileBytes, 0, fileBytes.Length);
MemoryStream stream = new MemoryStream(fileBytes);
using (var file = stream)
{
// sftp.BufferSize = 4 * 1024;
client.UploadFile(file, uploadFile + "/" + Path.GetFileName(path));
// Log.Info("Upload to SFTP success", this);
}
streams.Close();
client.Disconnect();
// Log.Info("Disconnected from SFTP", this);
}
I'm trying to find a way to avoid the IOException related to the fact that I read on a closed stream.
I'm calling a webservice method that returns a Stream:
InputStream stream = callRestWebService();
try {
parkingState = objectMapper.readValue(stream, ParkingState.class);
} catch (IOException e) {
throw new ParkingMeasurementProviderException("Could not retrieve data.", e);
}
Then, I have my Web Service method where I close the get connection:
public InputStream callRestWebService() {
int parkingId = 2803;
String endpointURL = REST_ENDPOINT + URI_INFO_PATH + parkingId + "/parkingState";
InputStream inputStream = null;
// Create an instance of HttpClient.
HttpClient httpclient = new HttpClient();
// Create a method instance.
GetMethod getMethod = new GetMethod(endpointURL);
getMethod.addRequestHeader("accept", "application/json");
try {
// Execute the method.
int statusCode = httpclient.executeMethod(getMethod);
inputStream = getMethod.getResponseBodyAsStream();
} catch (IOException e) {
e.printStackTrace();
} finally {
// Release the connection.
getMethod.releaseConnection();
}
return inputStream;
}
Is there a way to avoid having this exception without removing the : getMethod.releaseConnection();
The stack trace:
Disconnected from the target VM, address: '127.0.0.1:62152', transport: 'socket'
at be.ixor.itg.server.service.parking.hermesWS.HermesWSParkingControllerMeasurementProvider.getHermesMechelenData(HermesWSParkingControllerMeasurementProvider.java:126)
at be.ixor.itg.server.service.parking.hermesWS.Main.main(Main.java:14)
Caused by: java.io.IOException: Attempted read on closed stream.
at org.apache.commons.httpclient.AutoCloseInputStream.isReadAllowed(AutoCloseInputStream.java:183)
at org.apache.commons.httpclient.AutoCloseInputStream.read(AutoCloseInputStream.java:86)
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager$RewindableInputStream.read(XMLEntityManager.java:2977)
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:702)
at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(XMLVersionDetector.java:186)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:772)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:119)
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:232)
at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:284)
at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:124)
at be.ixor.itg.server.service.parking.hermesWS.HermesWSParkingControllerMeasurementProvider.getHermesMechelenData(HermesWSParkingControllerMeasurementProvider.java:116)
... 1 more
Because you are calling releaseConnection() in your finally block, the input stream will no longer be available.
If you do not expect the content to be large, you could read the data from the input stream into a buffer and return the buffer instead of the input stream. Otherwise, you will need to change your code to allow the called to process the data from the input stream before releasing the connection.
BufferedReader br = new BufferedReader(new
InputStreamReader((response.getEntity().getContent())));
String response = br.readLine();
System.out.println("response" + response );
This code is working for me.
I am trying to deploy my ASP.NET Application which is currently running on Windows Server 2003 32bit and IIS6 to a new Server running Windows Server 2008 R2 and IIS7.
My application uses ASP.NET version 4.0 and is working fine on 2003 machine.
My problem is:
I have deployed the application and it is working fine except that the .flv video is not playing in browser
I have added all required mime settings but still no luck
when i try to run the video i don't get any error just a blank screen showing no video.
Same configuration is working on previous machine and the new server is also able to play the video when run from the earlier machine.
Please if you have any solution help me out.
I have just found an Event Error entry that gets logged when i try to run the video. It is as follows:
Event code: 3005
Event message: An unhandled exception has occurred.
Event time: 10/9/2012 1:07:14 PM
Event time (UTC): 10/9/2012 8:07:14 PM
Event ID: 09303bdb94d64235a5ab118955416895
Event sequence: 12
Event occurrence: 1
Event detail code: 0
Application information:
Application domain: /LM/W3SVC/1/ROOT/BYPL-1-129942868205521131
Trust level: Full
Application Virtual Path: /BYPL
Application Path: F:\BYPL_Simulator_26_Sept_2012\
Machine name: BYPL-APP-SERVER
Process information:
Process ID: 2536
Process name: w3wp.exe
Account name: BYPL-APP-SERVER\Administrator
Exception information:
Exception type: HttpException
Exception message: Could not load type 'FLVStreaming'.
at System.Web.Compilation.BuildManager.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase)
at System.Web.Configuration.HandlerFactoryCache.GetTypeWithAssert(String type)
at System.Web.Configuration.HandlerFactoryCache.GetHandlerType(String type)
at System.Web.Configuration.HandlerFactoryCache..ctor(String type)
at System.Web.HttpApplication.GetFactory(String type)
at System.Web.HttpApplication.MaterializeHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
Request information:
Request URL: http://localhost/BYPL/Administrator/MeterManagement/Installation/video/634655271233125000.flv
Request path: /BYPL/Administrator/MeterManagement/Installation/video/634655271233125000.flv
User host address: 127.0.0.1
User: bypl
Is authenticated: True
Authentication Type: Forms
Thread account name: BYPL-APP-SERVER\Administrator
Thread information:
Thread ID: 5
Thread account name: BYPL-APP-SERVER\Administrator
Is impersonating: False
Stack trace: at System.Web.Compilation.BuildManager.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase)
at System.Web.Configuration.HandlerFactoryCache.GetTypeWithAssert(String type)
at System.Web.Configuration.HandlerFactoryCache.GetHandlerType(String type)
at System.Web.Configuration.HandlerFactoryCache..ctor(String type)
at System.Web.HttpApplication.GetFactory(String type)
at System.Web.HttpApplication.MaterializeHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
I found the answer myself.
I added a file named FLVStreaming.cs in the app_code folder and then re-published the application and the file contained the following code:
using System.Web;
public class FLVStreaming : IHttpHandler
{ // FLV header
public FLVStreaming()
{}
public void ProcessRequest(HttpContext context)
{ try{
int pos;
int length;
// Check start parameter if present
string filename = Path.GetFileName(context.Request.FilePath);
using (FileStream fs = new FileStream(context.Server.MapPath(filename), FileMode.Open, FileAccess.Read, FileShare.Read))
{
string qs = context.Request.Params["start"];
if (string.IsNullOrEmpty(qs))
{
pos = 0;
length = Convert.ToInt32(fs.Length);
}
else
{
pos = Convert.ToInt32(qs);
length = Convert.ToInt32(fs.Length - pos) + _flvheader.Length;
}
// Add HTTP header stuff: cache, content type and length
context.Response.Cache.SetCacheability(HttpCacheability.Public);
context.Response.Cache.SetLastModified(DateTime.Now);
context.Response.AppendHeader("Content-Type", "video/x-flv");
context.Response.AppendHeader("Content-Length", length.ToString());
// Append FLV header when sending partial file
if (pos > 0)
{
context.Response.OutputStream.Write(_flvheader, 0, _flvheader.Length);
fs.Position = pos;
}
// Read buffer and write stream to the response stream
const int buffersize = 16384;
byte[] buffer = new byte[buffersize];
int count = fs.Read(buffer, 0, buffersize);
while (count > 0)
{
if (context.Response.IsClientConnected)
{
context.Response.OutputStream.Write(buffer, 0, count);
count = fs.Read(buffer, 0, buffersize);
}
else
{
count = -1;
}
}
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
}
}
public bool IsReusable
{ get { return true; }
}
private static byte[] HexToByte(string hexString)
{
byte[] returnBytes = new byte[hexString.Length / 2];
for (int i = 0; i < returnBytes.Length; i++)
returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
return returnBytes;
}
}
It appears like this file gets converted into a .ddl file and this dll file version was not matching according to the Machine architecture.
I'm using an app_offline.htm file as described here : http://weblogs.asp.net/scottgu/archive/2005/10/06/426755.aspx to take an old asmx web service offline.
All works fine, and the client end gets a HTTP 503 exception like :
Exception : System.Net.WebException
The request failed with HTTP status 503: Service Unavailable.
Source : System.Web.Services
Stack trace :
at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
My question : is it possible for the client application to read the contents of the app_offline.htm file which would have been returned ? The basic HTML in that file has helpful text like : "The application is currently undergoing maintenance". I can see the contents of this file being returned in the response using Fiddler.
It would be useful to be able to parse this html response to provide more info to the user. (i.e. so it is possible to distinguish between a 503 error due to system maintenance, and other 503s due to system being overloaded etc).
EDIT : BluesRockAddict's response sounded good, but the stream seems to be unavailable at this time. e.g. :
// wex is the caught System.Net.WebException
System.Net.WebResponse resp = wex.Response;
byte[] buff = new byte[512];
Stream st = resp.GetResponseStream();
int count = st.Read(buff, 0, 512);
The last line above which attempts to read the stream gives :
Exception : System.ObjectDisposedException
Cannot access a closed Stream.
Source : mscorlib
Stack trace :
at System.IO.__Error.StreamIsClosed()
at System.IO.MemoryStream.Read(Byte[] buffer, Int32 offset, Int32 count)
credit goes to BluesRockAddict, adding to his answer, this is how you can read the content of html page.
catch (WebException ex)
{
if (((HttpWebResponse)ex.Response).StatusCode == HttpStatusCode.ServiceUnavailable)
{
using (Stream stream = ex.Response.GetResponseStream())
{
using(StreamReader reader = new StreamReader(stream))
{
var message = reader.ReadToEnd();
}
}
}
}
You should use WebException.Response to retrieve the message:
using (WebClient wc = new WebClient())
{
try
{
string content = wc.DownloadString(url);
}
catch (WebException ex)
{
if (((HttpWebResponse)ex.Response).StatusCode == HttpStatusCode.ServiceUnavailable)
{
message = ex.Response
}
}
}
i have a web service which contains a method like the following
[WebMethod]
public string UploadFile(byte[] bytes, string file_name)
{
}
i want to invoke this web service method using HttpWebRequest so that i can stream the file without buffering in memory. How can do it... i tried to invoke it as follows
HttpWebRequest hw = HttpWebRequest.Create("http://localhost/xxx/xxx.asmx/Upload") as HttpWebRequest;
hw.ContentType = "application/x-www-form-urlencoded";
hw.AllowWriteStreamBuffering = false;
hw.Method = "POST";
hw.UnsafeAuthenticatedConnectionSharing = true;
hw.UserAgent = "test type";
hw.Credentials = CredentialCache.DefaultCredentials;
FileInfo fi = new FileInfo("C:/Documents and Settings/Administrator/Desktop/a.txt");
string bytes = "bytes=";
byte[] by = UTF8Encoding.UTF8.GetBytes(bytes);
byte[] fn = UTF8Encoding.UTF8.GetBytes("&file_name=a.txt");
hw.ContentLength = by.Length+fi.Length+fn.Length;
using (Stream postStream = hw.GetRequestStream())
{
FileStream br = new FileStream("C:/Documents and Settings/Administrator/Desktop/a.txt", FileMode.Open, FileAccess.Read);
postStream.Write(by, 0, by.Length);
byte[] buffer = new byte[1024];
int bytesRead = 0;
while (true)
{
bytesRead = br.Read(buffer, 0, buffer.Length);
if (bytesRead == 0)
break;
postStream.Write(buffer, 0, bytesRead);
}
br.Close();
postStream.Write(fn, 0, fn.Length);
postStream.Write(ct, 0, ct.Length);
}
// HERE :
using (HttpWebResponse response = hw.GetResponse() as HttpWebResponse)
{
StreamReader reader = new StreamReader(response.GetResponseStream());
string sssdd = reader.ReadToEnd();
}
but it show a message "The remote server returned an error: (500) Internal Server Error." while executing **// HERE : ** marked line.
btw: i am using asp.net 2.0 and i am not allowed to use proxy class as my requirement is to stream the data for large file. Thanks in advance
Open up http://localhost/xxx/xxx.asmx/Upload in your browser and ASP.NET will give you an example POST requrest you'll need to send in order to invoke the method. Start from there on.
It's been a while since I messed with this stuff, but I think you can get at the underlying HttpRequest in the proxy class. Probably alot easier than ginning up your own SOAP to POST.
If it says that the remote server returned an error, then you should look on the remote server to see what the error was. Look in the Event Log on the server for events at around the time you received the error.
Remove these lines:
postStream.Write(by, 0, by.Length);
.
.
.
postStream.Write(fn, 0, fn.Length);
postStream.Write(ct, 0, ct.Length);