Unknown Error.

Dec 20, 2012 at 11:14 AM

Hello! I used your control in Silverlight 4, and now I decided to switch to the new version.
I downloaded the source code (I have a task to translate it into Russian), the test application starts and runs perfectly. I FileUploader integrating into my project, but when I try to upload a file, I get Unknown Error. I tried to use your test xap application - the same problem, it means that the problem in my server, but I can not find it. In UploadHandler triggered CreateNewFile, then CancelUpload, OnError not called.
How can I find this? I'm using Visual Studio Development Server. My web.config:

<configuration>
	<appSettings>
		<!-- This value must match the Full TypeName including the namespace of your UploadHandler -->
		<!-- <add key="UploadHandler" value="Showcase.ContentManager.Web.Services.UploadHandler, Showcase.ContentManager.Web"/>-->
		<add key="UploadHandler" value="Showcase.ContentManager.Web.UploadHandler, Showcase.ContentManager.Web"/>
	</appSettings>
	<system.web>
		<compilation debug="true" targetFramework="4.0" />
		<httpHandlers>
			<add verb="GET,POST" path="FileUpload.ashx" type="HSS.Interlink.Web.FileUpload, HSS.Interlink.Web" />
		</httpHandlers>
		<httpRuntime maxQueryStringLength="2097151" maxRequestLength="2147483647"/>

	</system.web>
	<system.webServer>
		<security>
			<requestFiltering>
				<requestLimits maxQueryString="2147483647"></requestLimits>
			</requestFiltering>
		</security>
	</system.webServer>
 <system.serviceModel>
  <bindings>
   <netTcpBinding>
    <binding name="NetTcpBinding_IShowcaseService">
     <security mode="None" />
    </binding>
   </netTcpBinding>
  </bindings>
  <client>
   <endpoint address="net.tcp://localhost:4604/ShowcaseService"
    binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IShowcaseService"
    contract="MainServiceReference.IShowcaseService" name="NetTcpBinding_IShowcaseService" />
  </client>
 </system.serviceModel>
</configuration>


Thanks in advance!

Coordinator
Dec 21, 2012 at 1:34 PM

Hello,

Given the fact that it called CreateNewFile, there is probably a restriction for creating a new folder or file on your server.

Be sure the app pool your site is running under has permissions to create folders and files.

Dec 21, 2012 at 4:07 PM

Hello, thanks for the reply!

No. When I put a breakpoint in CancelUpload I see the file (0 size) in upload_temp folder and the job file. I use the Development Server, but I think that everything will be the same in iis

Coordinator
Dec 21, 2012 at 4:14 PM

If it's getting that far, then you should be able to put a break point in each of the overload methods (createnew, append, etc.) and see where it's failing.

Dec 21, 2012 at 5:25 PM

Yes, but CancelUpload - an event that comes from the client, the only thing he says is Unknown Error. OnError and Append is not called.

Coordinator
Dec 21, 2012 at 5:48 PM

Oh, so the client is encountering an error, and then calling cancel upload.

Can you share your server side UploadHanlder code?

Dec 22, 2012 at 1:52 AM

Sure, but is taken from the example in Source Code. The example works fine, but my server is not working.

public class UploadHandler : BaseUploadHandler
	{
		/// <summary>
		/// The Folder where the uploaded files are stored.
		/// </summary>
		public static string FileStoreFolder = @"Uploads";
		/// <summary>
		/// Gets the absolute path of the requested file.
		/// </summary>
		private string FilePath
		{
			get
			{
				if (string.IsNullOrEmpty(_filePath))
					_filePath = Path.Combine(this.GetFolder(FileStoreFolder), this.FileName);
				return _filePath;
			}
		} string _filePath;

		#region BaseUploadHandler Members
		public override bool IsAuthorized()
		{
			#region Validate Authorization
			//if (this.Context.User.Identity.IsAuthenticated)
			//{
			//    if (this.Context.User.IsInRole("requiredRole"))
			//        return true;
			//}
			//return false;
			#endregion

			return true;
		}
		public override bool CheckFileExists()
		{
			return File.Exists(FilePath);
		}
		public override void CreateNewFile()
		{
			if (File.Exists(FilePath))
				File.Delete(FilePath);
			File.Create(FilePath).Close();
		}
		public override Response AppendToFile(byte[] buffer)
		{
			#region Test Retry

			// If you're unable to append the bytes
			// you can request the client retry

			// Sample test for retry
			//if (sometest == false)
			//    return Responses.AppendFileRetry;

			#endregion

			using (var fs = File.Open(FilePath, FileMode.Append))
				fs.Write(buffer, 0, buffer.Length);

			return Response.Success;
		}
		public override void CancelUpload()
		{
			System.Diagnostics.Debug.WriteLine(this.FileName + " CANCELED");
			if (File.Exists(FilePath))
				File.Delete(FilePath);
		}
		public override string UploadComplete()
		{
			System.Diagnostics.Debug.WriteLine(this.Metadata);
			return this.FilePath; // Optional string to return to caller.
		}
		public override void OnError(ref Exception ex)
		{
			// Log Exception

			if (File.Exists(FilePath))
				File.Delete(FilePath);
		}
		#endregion
	}
Coordinator
Dec 23, 2012 at 1:18 PM

Without more information, we're not sure how to help. If it's a server setting, then you'll need to compare the two environments to see what's different.

We recommend using Fiddler to monitor the network traffic to see what's actually getting communicated both directions. That should provide more insight into the error.

Also, review your machine event logs for any ASP.NET error that may be getting logged.

Dec 24, 2012 at 1:03 PM

I did a debug of the client application, and I found a bug.

maxChunk size based on maxRequestLength from server. In my web.config I write:

<httpRuntime maxQueryStringLength="2097151" maxRequestLength="2147483647"/>

This Int32.Max.
If we go UploadClient.SetMaxChunkSize we see:

newMax = newMax * KB1; / / Convert to bytes
if (newMax> MAX_CHUNK)newMax = MAX_CHUNK;
this.maxChunk = newMax;
this.chunkSize = this.maxChunk;

newMax received Int32.Max value and this causes overflow int, and eventually newMax = -1024.

In functions UploadClient.FillBuffer, there is a line

this.currentChunk = this.chunkSize - HASH_SIZE;
if (this.currentChunk> bytesLeftToSend)
  this.currentChunk = (Int32) bytesLeftToSend;
/ / Read and hash current chunk
var bufferLen = this.currentChunk + HASH_SIZE;
var buffer = new byte [bufferLen];

bufferLen becomes negative, it causes a OverflowException in UploadClient AppendChunk

long len = asyncState.FillBuffer ();
# if SILVERLIGHT
var request = asyncState.Request = this.GetWebRequest (FileQueryCommand.Append, MainStrings.HTTP_POST, true, false, len);
# elsevar 
request = asyncState.Request = this.GetWebRequest (FileQueryCommand.Append, Strings.HTTP_POST, false, len);
# endif
request.BeginGetRequestStream (UploadClient.UploadChunkRequestCallback, asyncState);
}
catch (Exception exception)
{if (((exception is ThreadAbortException) | | 
(exception is StackOverflowException)) | |
 (exception is OutOfMemoryException))
throw;
if (! (exception is WebException) &&! 
(exception is SecurityException))
exception = new WebException (MainStrings.Ex_UnknownError, exception);
asyncState.Exception = exception;
this.SendCancel (asyncState);}

There is no handling for this exception in catch and we get Unknown Error.
Be careful with your web.config

Coordinator
Dec 24, 2012 at 4:04 PM

Yes, maxRequestLength should never be that big. It exposes your server to dos attacks. The default 4096 is safe and provides the best performance for most situations. On internal networks you could go to say 12mb since you'll have the bandwidth. HSS Interlink will auto-size the chunks starting with the maxRequestLength and then go smaller (but never above), to acheive the best perceived performance for the user.