Seeking advice on transferring a file via WebMethod

  • Thread starter Thread starter Joseph Geretz
  • Start date Start date
J

Joseph Geretz

Up to this point, our application has been using Windows File Sharing to
transfer files to and from our application document repository. This
approach does not lend itself toward a secure environment and so we are in
the process of imposing a WebService gateway between our application client
and the repository.

(As a starting point, the WebService won't be a richly featured application
server; business rules are still implemented in the client. But this will
ensure that all access to the document repository is made via our software.
Although the WebMethod below accepts only a single parameter, I'll shortly
be adding authentication parameters to this method to ensure that accesses
to this WebMethod actually originate from our client application.)

Here is the method which I've defined (below). I have two questions, one
which relates to functionality, and the other which relates to performance.

1. I can't get this to work! When I test this I get the following error
message:

Could not open C:\Winzip.log --> Access to the path
"C:\Winzip.log" is denied.

Here's the line of code on which the exception occurs:

FileStream FS = new FileStream(FileSpec, FileMode.Open);

I can't imagine that this is a Windows security problem. I have anonymous
access disabled, integrated Windows authentication enabled, so the request
must be running using my credentials and I'm able to open this file via the
Windows shell. I imagine that perhaps I need to tweak a setting somewhere,
but I'm not sure where.

2. Is this the quickest way to stream a file back to a remote client? Speedy
delivery of the document to the client is critical and so anything that I
can do to improve performance is important to me. Maybe conversion to
Base64String is not as efficient? If I can use a more efficient format I
will. Just bear in mind that I need to stream binary files (e.g. JPG) as
well as textual, so I need a format which will preserve every bit as it
travels via HTTP.

Thanks very much for your advice!

- Joe Geretz -

[WebMethod]
public string GetFileStream(string FileSpec)
{
try
{
FileStream FS = new FileStream(FileSpec, FileMode.Open);
byte[] FileBytes = new byte[FS.Length];
FS.Read(FileBytes, 0, (int)FS.Length);
FS.Close();
return System.Convert.ToBase64String(FileBytes, 0, FileBytes.Length);
}
catch (Exception e)
{
throw new Exception("Could not open " + FileSpec, e);
}
}
 
Joseph said:
Up to this point, our application has been using Windows File Sharing to
transfer files to and from our application document repository. This
approach does not lend itself toward a secure environment and so we are in
the process of imposing a WebService gateway between our application client
and the repository.

(As a starting point, the WebService won't be a richly featured application
server; business rules are still implemented in the client. But this will
ensure that all access to the document repository is made via our software.
Although the WebMethod below accepts only a single parameter, I'll shortly
be adding authentication parameters to this method to ensure that accesses
to this WebMethod actually originate from our client application.)

Here is the method which I've defined (below). I have two questions, one
which relates to functionality, and the other which relates to performance.

1. I can't get this to work! When I test this I get the following error
message:

Could not open C:\Winzip.log --> Access to the path
"C:\Winzip.log" is denied.

Here's the line of code on which the exception occurs:

FileStream FS = new FileStream(FileSpec, FileMode.Open);

I can't imagine that this is a Windows security problem. I have anonymous
access disabled, integrated Windows authentication enabled, so the request
must be running using my credentials and I'm able to open this file via the
Windows shell. I imagine that perhaps I need to tweak a setting somewhere,
but I'm not sure where.

2. Is this the quickest way to stream a file back to a remote client? Speedy
delivery of the document to the client is critical and so anything that I
can do to improve performance is important to me. Maybe conversion to
Base64String is not as efficient? If I can use a more efficient format I
will. Just bear in mind that I need to stream binary files (e.g. JPG) as
well as textual, so I need a format which will preserve every bit as it
travels via HTTP.

Thanks very much for your advice!

- Joe Geretz -

[WebMethod]
public string GetFileStream(string FileSpec)
{
try
{
FileStream FS = new FileStream(FileSpec, FileMode.Open);
byte[] FileBytes = new byte[FS.Length];
FS.Read(FileBytes, 0, (int)FS.Length);
FS.Close();
return System.Convert.ToBase64String(FileBytes, 0, FileBytes.Length);
}
catch (Exception e)
{
throw new Exception("Could not open " + FileSpec, e);
}
}

For transferring a file via SOAP take a look at the Microsoft WSE and
the SOAP Attachments specification it implements.

Cheers
Jimbo.
 
Hi David,

Thanks for your response.

The file is on the server. That's the whole point, we're imposing the
WebService as a gateway between the server-side file repository and the
clients.

I am able to get access, by placing the following directive inside the
Web.config file:

<identity impersonate="true" userName="SRS\Joseph" password="foobar"/>

However, the following directive doesn't work, even though I am logged in as
SRS\Joseph.

<identity impersonate="true" userName="" password=""/>

I'm curious as to why the latter doesn't work. My site is set up to use
integrated Windows authentication. Shouldn't the transaction be using the
credentials SRS\Joseph in the latter case, just as it is in the former case?
Why don't you just use Windows SharePoint Services. It's part of the OS,
and that's what it's for.

Sharepoint stores its files inside SQL Server. BLOB access is not as quick
as native filesystem access. If we wanted to go that route, we'd have been
storing our documents inside SQL Server a long time ago.

Thanks,

- Joe Geretz -
 
However, the following directive doesn't work, even though I am logged in
as SRS\Joseph.

<identity impersonate="true" userName="" password=""/>

Cancel that. It does work.

- Joe Geretz -
 
Joseph Geretz said:
Hi David,

Thanks for your response.

The file is on the server. That's the whole point, we're imposing the
WebService as a gateway between the server-side file repository and the
clients.

I am able to get access, by placing the following directive inside the
Web.config file:

<identity impersonate="true" userName="SRS\Joseph" password="foobar"/>

However, the following directive doesn't work, even though I am logged in
as SRS\Joseph.

<identity impersonate="true" userName="" password=""/>

I'm curious as to why the latter doesn't work. My site is set up to use
integrated Windows authentication. Shouldn't the transaction be using the
credentials SRS\Joseph in the latter case, just as it is in the former
case?


Sharepoint stores its files inside SQL Server. BLOB access is not as quick
as native filesystem access. If we wanted to go that route, we'd have been
storing our documents inside SQL Server a long time ago.

Transfering over SOAP will require Base64 encoding and lots of memory on the
server, as you've discovered. Which is a far cry from native filesystem
access.

David
 
I have got this figured out now. Evidently, when you run client and
webservice projects in a signle solution, Visual Studio does not create the
proxy. I removed the webservice project and instead added a reference to the
webservice to the client project; Voila! Visual Studio created the proxy
class for me. Of course, I still had to tweak the proxy class, but getting
the proxy class created was 90% of the solution.

- Joe Geretz -

Joseph Geretz said:
Hi Luis,

I am trying to use WSE 2 but I'm having a problem. (I can't use WSE3
because it's not production yet.)

I created a brand new WebService project and added in the reference to
WSE. I didn't modify the Web.Config
file myself, but when I looked I was pleasantly surprised to see that all
entries were added automatically for me (see Web.config file below).

Here is the Web Service method which I've defined:

[WebMethod]
public int DropDIMEOnMe(string FileSpec)
{
SoapContext respContext = ResponseSoapContext.Current;
DimeAttachment dimeAttach = new DimeAttachment("file/unknown",
TypeFormat.MediaType, FileSpec);
respContext.Attachments.Add(dimeAttach);
return respContext.Attachments.Count;
}

The statement

respContext.Attachments.Add(dimeAttach);

trips the following error:

Object reference not set to an instance of an object.

The crux of the problem is that ResponseSoapContext.Current = <undefined
value> when I attempt to access it. Why am I unable to get access to the
ResponseSoapContext object?

Thanks for any assistance which you can provide!

- Joe Geretz -

Here's my Web.Config file:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="microsoft.web.services2"
type="Microsoft.Web.Services2.Configuration.WebServicesConfiguration,
Microsoft.Web.Services2, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" />
</configSections>
<system.web>
<compilation defaultLanguage="c#" debug="true" />
<customErrors mode="RemoteOnly" />
<authentication mode="Windows" />
<authorization>
<allow users="*" />
</authorization>
<trace enabled="false" requestLimit="10" pageOutput="false"
traceMode="SortByTime" localOnly="true" />
<sessionState mode="InProc"
stateConnectionString="tcpip=127.0.0.1:42424" sqlConnectionString="data
source=127.0.0.1;Trusted_Connection=yes" cookieless="false" timeout="20"
/>
<globalization requestEncoding="utf-8" responseEncoding="utf-8" />
<webServices>
<soapExtensionTypes>
<add type="Microsoft.Web.Services2.WebServicesExtension,
Microsoft.Web.Services2, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" priority="1" group="0" />
</soapExtensionTypes>
</webServices>
</system.web>
<microsoft.web.services2>
<diagnostics />
</microsoft.web.services2>
</configuration>

Luis Azedo said:
Hi Joseph,

i would recommend using WSS on the server side vecause it gives you good
security on files.

i also recommend you to look at WSE 3, with the MTOM implementation, the
downloads would get smaller.

hope it helps
 
Back
Top