I receive error emails from my website whenever an exception occurs. I am getting this error:
The remote host closed the connection. The error code is 0x800704CD
and don't know why. I get about 30 a day. I can't reproduce the error either so can't track down the issue.
Website is ASP.NET 2 running on IIS7.
Stack trace:
at
System.Web.Hosting.IIS7WorkerRequest.RaiseCommunicationError(Int32
result, Boolean throwOnDisconnect) at
System.Web.Hosting.IIS7WorkerRequest.ExplicitFlush()
at
System.Web.HttpResponse.Flush(Boolean
finalFlush) at
System.Web.HttpResponse.Flush() at
System.Web.HttpResponse.End() at
System.Web.UI.HttpResponseWrapper.System.Web.UI.IHttpResponse.End()
at
System.Web.UI.PageRequestManager.OnPageError(Object
sender, EventArgs e) at
System.Web.UI.TemplateControl.OnError(EventArgs
e) at
System.Web.UI.Page.HandleError(Exception
e) at
System.Web.UI.Page.ProcessRequestMain(Boolean
includeStagesBeforeAsyncPoint, Boolean
includeStagesAfterAsyncPoint) at
System.Web.UI.Page.ProcessRequest(Boolean
includeStagesBeforeAsyncPoint, Boolean
includeStagesAfterAsyncPoint) at
System.Web.UI.Page.ProcessRequest() at
System.Web.UI.Page.ProcessRequestWithNoAssert(HttpContext
context) at
System.Web.UI.Page.ProcessRequest(HttpContext
context) at
ASP.default_aspx.ProcessRequest(HttpContext
context) at
System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at
System.Web.HttpApplication.ExecuteStep(IExecutionStep
step, Boolean& completedSynchronously)
I get this one all the time. It means that the user started to download a file, and then it either failed, or they cancelled it.
To reproduce the exception try do this yourself - however I'm unaware of any ways to prevent it (except for handling this specific exception only).
You need to decide what the best way forward is depending on your app.
As m.edmondson mentioned, "The remote host closed the connection." occurs when a user or browser cancels something, or the network connection drops etc. It doesn't necessarily have to be a file download however, just any request for any resource that results in a response to the client. Basically the error means that the response could not be sent because the server can no longer talk to the client(browser).
There are a number of steps that you can take in order to stop it happening. If you are manually sending something in the response with a Response.Write, Response.Flush, returning data from a web servivce/page method or something similar, then you should consider checking Response.IsClientConnected before sending the response. Also, if the response is likely to take a long time or a lot of server-side processing is required, you should check this periodically until the response.end if called. See the following for details on this property:
http://msdn.microsoft.com/en-us/library/system.web.httpresponse.isclientconnected.aspx
Alternatively, which I believe is most likely in your case, the error is being caused by something inside the framework. The following link may by of use:
http://blog.whitesites.com/fixing-The-remote-host-closed-the-connection-The-error-code-is-0x80070057__633882307305519259_blog.htm
The following stack-overflow post might also be of interest:
"The remote host closed the connection" in Response.OutputStream.Write
One can reproduce the error with the code below:
public ActionResult ClosingTheConnectionAction(){
try
{
//we need to set buffer to false to
//make sure data is written in chunks
Response.Buffer = false;
var someText = "Some text here to make things happen ;-)";
var content = GetBytes( someText );
for(var i=0; i < 100; i++)
{
Response.OutputStream.Write(content, 0, content.Length);
}
return View();
}
catch(HttpException hex)
{
if (hex.Message.StartsWith("The remote host closed the connection. The error code is 0x800704CD."))
{
//react on remote host closed the connection exception.
var msg = hex.Message;
}
}
catch(Exception somethingElseHappened)
{
//handle it with some other code
}
return View();
}
Now run the website in debug mode. Put a breakpoint in the loop that writes to the output stream. Go to that action method and after the first iteration passed close the tab of the browser. Hit F10 to continue the loop. After it hit the next iteration you will see the exception. Enjoy your exception :-)
I was getting this on an asp.net 2.0 iis7 Windows2008 site. Same code on iis6 worked fine. It was causing an issue for me because it was messing up the login process. User would login and get a 302 to default.asxp, which would get through page_load, but not as far as pre-render before iis7 would send a 302 back to login.aspx without the auth cookie. I started playing with app pool settings, and for some reason 'enable 32 bit applications' seems to have fixed it. No idea why, since this site isn't doing anything special that should require any 32 bit drivers. We have some sites that still use Access that require 32bit, but not our straight SQL sites like this one.
I got this error when I dynamically read data from a WebRequest and never closed the Response.
protected System.IO.Stream GetStream(string url)
{
try
{
System.IO.Stream stream = null;
var request = System.Net.WebRequest.Create(url);
var response = request.GetResponse();
if (response != null) {
stream = response.GetResponseStream();
// I never closed the response thus resulting in the error
response.Close();
}
response = null;
request = null;
return stream;
}
catch (Exception) { }
return null;
}
I too got this same error on my image handler that I wrote. I got it like 30 times a day on site with heavy traffic, managed to reproduce it also. You get this when a user cancels the request (closes the page or his internet connection is interrupted for example), in my case in the following row:
myContext.Response.OutputStream.Write(buffer, 0, bytesRead);
I can’t think of any way to prevent it but maybe you can properly handle this. Ex:
try
{
…
myContext.Response.OutputStream.Write(buffer, 0, bytesRead);
…
}catch (HttpException ex)
{
if (ex.Message.StartsWith("The remote host closed the connection."))
;//do nothing
else
//handle other errors
}
catch (Exception e)
{
//handle other errors
}
finally
{//close streams etc..
}
Related
I'm implementing a Thrift client in order to make connection to a built-in scribe server.
Everything is going OK if I use a standard Log method, like this:
public boolean log(List<LogEntry> messages) {
boolean ret = false;
PooledClient client = borrowClient();
try {
if ((client != null) && (client.getClient() != null)) {
ResultCode result = client.getClient().Log(messages);
ret = (result != null && result.equals(ResultCode.OK));
returnClient(client);
}
} catch (Exception ex) {
logger.error(LogUtil.stackTrace(ex));
invalidClient(client);
}
return ret;
}
However, when I use send_Log instead:
public void send_Log(List<LogEntry> messages) {
PooledClient client = borrowClient();
try {
if ((client != null) && (client.getClient() != null)) {
client.getClient().send_Log(messages);
returnClient(client);
}
} catch (Exception ex) {
logger.error(LogUtil.stackTrace(ex));
invalidClient(client);
}
}
It acctually causes some problems:
Total network connection to port 1463 (default port for a scribe server) is going to increase so much, and always in a CLOSE_WAIT state.
Cause my application got stuck without throwing any error, I think it may be an issue with network connection.
what if send without recv
As this is clearly TCP, the sender will block (in blocking mode), or incur EAGAIN/EWOULDBLOCK in non-blocking mode. EDIT It is now clear that you want to send without receiving the reply. You can do that by just sending and then closing the socket, but that may cause the peer to incur ECONNRESET, which may upset it. You should really implement the application protocol correctly.
1/ Total network connection to port 1463 (default port for a scribe server) is going to increase so much, and always in a CLOSE_WAIT state.
Lots of ports in CLOSE_WAIT state indicates a socket leak on the part of the local application.
2/ Cause my application got stuck without throwing any error. I think it may be an issues with network connection.
It is an issue with sending and not receiving.
Since you labelled this as a Thrift related question, the answer is oneway.
service foo {
oneway void FireAndForget(1: some args)
}
The oneway keyword does exactly what the name suggests. You get a client implementation that only sends and does not wait for anything to be returned from the server. This rule also includes exceptions. Hence a oneway method must always be void and can't throw any exceptions.
However, when I use send_Log instead ...
client.getClient().send_Log(messages);
Neither one of the Thrift-generated send_Xxx and recv_Xxx methods are meant to be public. That's why they are usually either private or protected methods. They should not be called directly, unless you are sure that you know what you are doing (and very obviously the latter is not the case here).
And since the real question is about performance: Why don't you just delegate the call(s) into a secondary thread? That way the I/O will not block the UI.
I'm building an ASP.NET Web API endpoint that accepts 'multipart/form-data' requests. I implemented it as described in this article using .NET Framework 4.5 and Web API 2.1. A simplified version of the action method I created, looks like this:
public async Task<HttpResponseMessage> PostFile()
{
if (!Request.Content.IsMimeMultipartContent()) throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
var rootPath = System.Configuration.ConfigurationManager.AppSettings["StorageLocation"].ToString();
var provider = new MultipartFormDataStreamProvider(rootPath);
var response = Request.CreateResponse(HttpStatusCode.OK);
try
{
await Request.Content.ReadAsMultipartAsync(provider);
// Imagine awesome logic here, unicorns and rainbows! Instead of that, we do the following:
response.Content = new StringContent("You uploaded " + provider.FileData.Count.ToString() + " files.");
}
catch (Exception e) { throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e)); }
return response;
}
Because the uploaded files can be very big (up to 2GiB), I want my requests to not be buffered by ASP.NET, thus avoiding high memory usage. To realize this I told Web API to stream incoming requests, instead of buffering them, as described in this article. The custom WebHostBufferPolicySelector looks something like this:
public class CustomWebHostBufferPolicySelector : WebHostBufferPolicySelector
{
public override bool UseBufferedInputStream(object hostContext)
{
System.Web.HttpContextBase contextBase = hostContext as System.Web.HttpContextBase;
if (contextBase != null && contextBase.Request.ContentType != null && contextBase.Request.ContentType.Contains("multipart")) return false;
else return base.UseBufferedInputStream(hostContext);
}
public override bool UseBufferedOutputStream(System.Net.Http.HttpResponseMessage response)
{
return base.UseBufferedOutputStream(response);
}
}
I load this guy in the Global.asax, at application start, like this:
protected void Application_Start(object sender, EventArgs e)
{
// Here, other stuff got did.
GlobalConfiguration.Configuration.Services.Replace(typeof(IHostBufferPolicySelector), new CustomWebHostBufferPolicySelector());
}
Alright, the board is set, lets get the pieces moving. If I don't use my CustomWebHostBufferPolicySelector, everything works just fine. However, when its used, I get the following exception:
Message: "An error has occurred."
ExceptionMessage: "Error reading MIME multipart body part."
ExceptionType: "System.IO.IOException"
StackTrace: " at System.Net.Http.HttpContentMultipartExtensions.<ReadAsMultipartAsync>d__0`1.MoveNext()\ \ --- End of stack trace from previous location where exception was thrown ---\ \ at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\ \ at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\ \ at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\ \ at ..."
With the following inner exception:
Message: "An error has occurred."
ExceptionMessage: "Unable to read the entity body in Bufferless mode. The request stream has already been buffered."
ExceptionType: "System.InvalidOperationException"
StackTrace: " at System.Web.Http.WebHost.HttpControllerHandler.<>c__DisplayClass13.<GetStreamContent>b__10()\ \ at System.Web.Http.WebHost.HttpControllerHandler.LazyStreamContent.get_StreamContent()\ \ at System.Web.Http.WebHost.HttpControllerHandler.LazyStreamContent.CreateContentReadStreamAsync()\ \ at System.Net.Http.HttpContent.ReadAsStreamAsync()\ \ at System.Net.Http.HttpContentMultipartExtensions.<ReadAsMultipartAsync>d__0`1.MoveNext()"
It looks like the request is still buffered somehow, by something else. Is there another place in the ASP.NET pipeline I should be looking? Or even IIS maybe? What are the other places in this request's lifecycle where it can be buffered, and how do I control them?
In an attempt to make the problem more clear and shareable with others, I created a simple project to try and reproduce the problem. While doing this I found the answer: disable all kinds of tracing.
In my case I had ASP.NET's own tracing functionality enabled, and also Glimpse. Both of these buffer the request before it arrives at the Web API action.
For completeness' sake, here the proper way to turn them off in your Web.Config, while testing and in production.
<configuration>
<system.web>
<trace enabled="false" />
</system.web>
<glimpse defaultRuntimePolicy="Off">
</glimpse>
</configuration>
In my case, these two were the culprits, but I can imagine there may be others, so be wary of this.
I'm using ASP.NET 3.5 to build a website. One area of the website shows 28 video thumbnail images, which are jpeg's hosted on another webserver. If one or more of these jpegs do not exist, I want to display a locally hosted default image to the user, rather than a broken image link in the browser.
The approach I have taken to implement this is whenever the page is rendered it will perform an HTTP HEAD request to each of the images. If I get a 200 OK status code back, then the image is good and I can write out <img src="http://media.server.com/media/123456789.jpg" />. If I get a 404 Not Found, then I write out <img src="/images/defaultthumb.jpg" />.
If course I don't want to do this every time for all requests, and so I've implemented a list of cached image status objects stored at application level so that each image is only checked once every 5 minutes across all users, but this doesn't really have any bearing on my issue.
This seems to work very well. My problem is that for specific images, the HTTP HEAD request fails with Request Timed Out.
I have set my timeout value very low to only 200ms so that is doesn't delay the page rendering too much. This timeout seems to be fine for most of the images, and I've tried playing around and increasing this during debugging, but it makes no difference even if it's 10s or more.
I write out a log file to see whats happening, and this is what I get (edited for clarify and anonymity):
14:24:56.799|DEBUG|[HTTP HEAD CHECK OK [http://media.server.com/adpm/505C3080-EB4F-6CAE-60F8-B97F77A43A47/videothumb.jpg]]
14:24:57.356|DEBUG|[HTTP HEAD CHECK OK [http://media.server.com/adpm/66E2C916-EEB1-21D9-E7CB-08307CEF0C10/videothumb.jpg]]
14:24:57.914|DEBUG|[HTTP HEAD CHECK OK [http://media.server.com/adpm/905C3D99-C530-46D1-6B2B-63812680A884/videothumb.jpg]]
...
14:24:58.470|DEBUG|[HTTP HEAD CHECK OK [http://media.server.com/adpm/1CE0B04D-114A-911F-3833-D9E66FDF671F/videothumb.jpg]]
14:24:59.027|DEBUG|[HTTP HEAD CHECK OK [http://media.server.com/adpm/C3D7B5D7-85F2-BF12-E32E-368C1CB45F93/videothumb.jpg]]
14:25:11.852|ERROR|[HTTP HEAD CHECK ERROR [http://media.server.com/adpm/BED71AD0-2FA5-EA54-0B03-03D139E9242E/videothumb.jpg]] The operation has timed out
Source: System
Target Site: System.Net.WebResponse GetResponse()
Stack Trace: at System.Net.HttpWebRequest.GetResponse()
at MyProject.ApplicationCacheManager.ImageExists(String ImageURL, Boolean UseCache) in d:\Development\MyProject\trunk\src\Web\App_Code\Common\ApplicationCacheManager.cs:line 62
14:25:12.565|ERROR|[HTTP HEAD CHECK ERROR [http://media.server.com/adpm/92399E61-81A6-E7B3-4562-21793D193528/videothumb.jpg]] The operation has timed out
Source: System
Target Site: System.Net.WebResponse GetResponse()
Stack Trace: at System.Net.HttpWebRequest.GetResponse()
at MyProject.ApplicationCacheManager.ImageExists(String ImageURL, Boolean UseCache) in d:\Development\MyProject\trunk\src\Web\App_Code\Common\ApplicationCacheManager.cs:line 62
14:25:13.282|ERROR|[HTTP HEAD CHECK ERROR [http://media.server.com/adpm/7728C3B6-69C8-EFAA-FC9F-DAE70E1439F9/videothumb.jpg]] The operation has timed out
Source: System
Target Site: System.Net.WebResponse GetResponse()
Stack Trace: at System.Net.HttpWebRequest.GetResponse()
at MyProject.ApplicationCacheManager.ImageExists(String ImageURL, Boolean UseCache) in d:\Development\MyProject\trunk\src\Web\App_Code\Common\ApplicationCacheManager.cs:line 62
As you can see, the first 25 HEAD requests work, and the final 3 do not. It's always the last three.
If I paste one of the failed HEAD request URLs into a web browser: http://media.server.com/adpm/BED71AD0-2FA5-EA54-0B03-03D139E9242E/videothumb.jpg, it loads the image with no problems.
To try to work out what is happening here, I used Wireshark to capture all of the HTTP requests that are sent to the webserver hosting the images. For the log example I've given, I can see 25 HEAD requests for the 25 that were successful, but the 3 that failed do NOT appear in the wireshark trace.
Other than the images having different visual content, there is no difference from one image to the next.
To eliminate any problems with the URL itself (even though it works in a browser) I changed the order by switching one of the first images with one of the last failed three. When I do this, the problem goes away for the one that used to fail, and starts failing for the one that was bumped down to the end of the list.
So I think I can deduce from the above that when more than 25 HEAD requests occur in quick succession, subsequent HEAD requests fail regardless of the specific URL. I also know that the issue is on the IIS server rather than the remote image hosting server, due to the lack of requests in the Wireshark trace beyond the first 25.
The code snippet I'm using to perform the HEAD requests is shown below. Can anyone give me any suggestions as to what might be the problem? I've tried various different combinations of request header values, but none of them seem to make any difference. My gut feeling is there is some IIS setting somewhere that limits the number of concurrent HttpWebRequests's to 25 in any one request to an ASP.NET page.
try {
HttpWebRequest hwr = (HttpWebRequest)WebRequest.Create(ImageURL);
hwr.Method = "HEAD";
hwr.KeepAlive = false;
hwr.AllowAutoRedirect = false;
hwr.Accept = "image/jpeg";
hwr.Timeout = 200;
hwr.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.Reload);
//hwr.Connection = "close";
HttpWebResponse hwr_result = (HttpWebResponse)hwr.GetResponse();
if (hwr_result.StatusCode == HttpStatusCode.OK) {
Diagnostics.Diags.Debug("HTTP HEAD CHECK OK [" + ImageURL + "]", HttpContext.Current.Request);
// EXISTENCE CONFIRMED - ADD TO CACHE
if (UseCache) {
_ImageExists.Value.RemoveAll(ie => ie.ImageURL == ImageURL);
_ImageExists.Value.Add(new ImageExistenceCheck() { ImageURL = ImageURL, Found = true, CacheExpiry = DateTime.Now.AddMinutes(5) });
}
// RETURN TRUE
return true;
} else if (hwr_result.StatusCode == HttpStatusCode.NotFound) {
throw new WebException("404");
} else {
throw new WebException("ERROR");
}
} catch (WebException ex) {
if (ex.Message.Contains("404")) {
Diagnostics.Diags.Debug("HTTP HEAD CHECK NOT FOUND [" + ImageURL + "]", HttpContext.Current.Request);
// NON-EXISTENCE CONFIRMED - ADD TO CACHE
if (UseCache) {
_ImageExists.Value.RemoveAll(ie => ie.ImageURL == ImageURL);
_ImageExists.Value.Add(new ImageExistenceCheck() { ImageURL = ImageURL, Found = false, CacheExpiry = DateTime.Now.AddMinutes(5) });
}
return false;
} else {
Diagnostics.Diags.Error(HttpContext.Current.Request, "HTTP HEAD CHECK ERROR [" + ImageURL + "]", ex);
// ASSUME IMAGE IS OK
return true;
}
} catch (Exception ex) {
Diagnostics.Diags.Error(HttpContext.Current.Request, "GENERAL CHECK ERROR [" + ImageURL + "]", ex);
// ASSUME IMAGE IS OK
return true;
}
I have solved this myself. The problem was indeed the number of allowed connections, which was set to 24 by default.
In my case, I am going to only perform the image check if the MyHttpWebRequest.ServicePoint.CurrentConnections is less than 10.
To increase the max limit, just set ServicePointManager.DefaultConnectionLimit to the number of concurrent connections you require.
An alternative which may help some people would be to reduce the idle time that is the time a connection waits until it destroys itself. To change this, you need to set MyHttpWebRequest.ServicePoint.MaxIdleTime to the timeout value in milliseconds.
I have a web app that takes some client info and produces a letter for each client. Everything works good in my test environment, but on the production server I get an error that says the file is corrupt. I can open the .dotx file in word just fine on the server but not via code. Please help. Here is my code:
Object oMissing = System.Reflection.Missing.Value;
Object oTrue = true;
Object oFalse = false;
Word.Application oWord = new Word.Application();
Word.Document oWordDoc = new Word.Document();
oWord.Visible = false;
Object oTemplatePath = Request.PhysicalApplicationPath + "letters\\" + letter.letter_data; //samplehollisletter.dotx";
oWordDoc = oWord.Documents.Add(ref oTemplatePath, ref oMissing, ref oMissing, ref oMissing);
foreach (Word.Field myMergeField in oWordDoc.Fields)
{
iTotalFields++;
Word.Range rngFieldCode = myMergeField.Code;
String fieldText = rngFieldCode.Text;
if (fieldText.StartsWith(" MERGEFIELD"))
{
Int32 endMerge = fieldText.IndexOf("\\");
Int32 fieldNameLength = fieldText.Length - endMerge;
String fieldName = fieldText.Substring(11, endMerge - 11);
fieldName = fieldName.Trim();
if (fieldName == "letter_title")
{
myMergeField.Select();
oWord.Selection.TypeText(acct.letter_title);
}
if (fieldName == "account_id")
{
myMergeField.Select();
oWord.Selection.TypeText(acct.account_id);
}
if (fieldName == "address")
{
myMergeField.Select();
oWord.Selection.TypeText(acct.PEOPLE.home_address + "\r\n" + acct.PEOPLE.home_city + ", " + acct.PEOPLE.home_state + " " + acct.PEOPLE.home_zip);
}
if (fieldName == "greeting_title")
{
myMergeField.Select();
oWord.Selection.TypeText(acct.greeting_title);
}
if (fieldName == "service_name")
{
myMergeField.Select();
oWord.Selection.TypeText((acct.SERVICEs.FirstOrDefault()).service_name);
}
if (fieldName == "service_date")
{
myMergeField.Select();
oWord.Selection.TypeText((acct.SERVICEs.FirstOrDefault()).service_date.ToString());
}
}
}
oWordDoc.PrintOut();
oWordDoc.Close(Microsoft.Office.Interop.Word.WdSaveOptions.wdDoNotSaveChanges);
Thread.Sleep(2000);
oWord.Quit();
The Error is:
Server Error in '/Tracker2' Application.
Word was unable to read this document. It may be corrupt.
Try one or more of the following:
* Open and Repair the file.
* Open the file with the Text Recovery converter.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Runtime.InteropServices.COMException: Word was unable to read this document. It may be corrupt.
Try one or more of the following:
* Open and Repair the file.
* Open the file with the Text Recovery converter.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[COMException (0x800a141f): Word was unable to read this document. It may be corrupt.
Try one or more of the following:
* Open and Repair the file.
* Open the file with the Text Recovery converter.]
Microsoft.Office.Interop.Word.Documents.Add(Object& Template, Object& NewTemplate, Object& DocumentType, Object& Visible) +0
Tracker.RunLetter2.Button1_Click(Object sender, EventArgs e) in C:\Users\Ethan\Documents\Visual Studio 2010\Projects\EstateTracker\Tracker\RunLetter2.aspx.cs:52
System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +154
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3691
I know it is time that this item has been opened, but as I had not found the answer anywhere, following solution for those who need it.
1 - In IIS, the application pool used by the application, change the Identity attribute to LocalSystem
2 - Create a folder called Desktop within the following directories on the server:
C:\Windows\System32\config\systemprofile
and
C:\Windows\SysWOW64\config\systemprofile
After that, give full permission for these two folders to the user group IIS: IIS_IUSRS
This will cause this user to have a "desktop" to work, thereby achieving the IIS Word use the library.
I rough it helps someone.
I have discovered that the issue stems from permissions of a WCF call using BasicHTTPBinding endpoints. When a call is made using this type of endpoint, the service assumes the use of an IIS account which does not have a desktop to open word. This is a requirement of the account to automate word. Even when you have a service, that launches a windows application, that launches word, the entire set of events will be given the privilage of the original WCF call and will result in this error.
My solution, while not great, nor what I really want, does work for the time being. I created a Queue table in the database. I then have the web app insert a request for a task to be completed. then on the server I have a standalone application that checks the queue for requests every 60 seconds and processes the request. Its not the best method boe like I said, it does work.
We have a very simple ASP.Net page for uploading a file to our webserver. The page has no controls - a client uses it to automatically send us a file each night.
On occasion, the file seems to not get to us, but the client reports that they have sent it.
We added some logging statements to the page, and discovered something quite odd. The page ceases to execute right in the middle of a log statement. No exceptions, just up and dies.
Here is the code-behind:
protected void Page_Load(object sender, EventArgs e) {
try {
// record that request came in at all
log.Debug("Update Inventory page requested through HTTP {2} on {0} {1}", DateTime.Now.ToShortDateString(), DateTime.Now.ToLongTimeString(), IsPostBack ? "POST" : "GET");
// make sure directory exists
string basePath = Server.MapPath("~/admin/uploads/");
log.Debug("Saving to folder {0}", basePath);
if (!Directory.Exists(basePath)) {
log.Debug("Creating folder {0}", basePath);
Directory.CreateDirectory(basePath);
}
// generate a unique file name
string fileName = DateTime.Now.Ticks.ToString() + ".dat";
string path = basePath + fileName;
log.Debug("Filename to save is {0}", fileName);
// record initial bytes of stream/file
StreamReader reader = new StreamReader(stream);
string fileContents = reader.ReadToEnd();
log.Debug("File received by GET is " + fileContents.Length + " characters long and begins with: "
+ Environment.NewLine + fileContents.Substring(0, Math.Min(fileContents.Length, 1000)));
// write out file
File.WriteAllText(path, fileContents);
log.Debug("Update Inventory page processing finished.");
// trap for and record any and all exceptions
}
catch (Exception ex) {
log.Debug(ex);
}
}
The processing seems to die in the middle of the log statement that outputs the length and first portion of the fileContents variable. The logging that occurs when the process fails looks like this:
2010-08-02 02:46:01.7342|DEBUG|UpdateInventory|Update Inventory page requested through HTTP GET on 8/2/2010 2:46:01 AM
2010-08-02 02:46:01.7655|DEBUG|UpdateInventory|Saving to folder c:\hosting\sites\musicgoround.com\wwwroot\admin\uploads\
2010-08-02 02:46:01.7811|DEBUG|UpdateInventory|Filename to save is 634163139617811250.dat
2010-08-02 02:48:02.3905|DEBUG|UpdateInventory|
I really don't understand what to make of this.
I assume if there was a error in the transmission of the file that either an exception would be thrown from the reader.ReadToEnd() line. And if not an exception, I would expect the page processing to continue but that I may only receive part of the file (in which case it should log something).
The logging statement is only accessing a string variable, and it's inside a try-catch. NLog is the logging component we use, and we access that through the facade provided by the Simple Logging Facade project on Codeplex. So, we trust the logging component to be more or less bulletproof - we certainly don't see anything in our usage of it here that should be causing problems.
So, what's the deal? Why on earth could this page just up and stop processing like this?
The fact that we get a half-finished logging statement seems to point towards an error being swallowed in the logging system - but that just seems so unlikely - and we have NLog's internal logging on and it is not reporting any problems.
The most likely candidate is that this line:
2010-08-02 02:48:02.3905|DEBUG|UpdateInventory|
Is caused by this:
log.Debug(ex);
I.e. it is throwing an exception, but the logger is not recording anything useful. Why don't you try switching about the log levels a bit, e.g. change the exception logging level to error:
log.Error(ex);
That way you can see if it is actually throwing an exception and it is just the logger not recording the exception string properly.