Uploading image as attachment in RESTful WCF Service - c#

I am trying to upload an image as an attachment in REST WCF Service and I am getting the following error.
"Access to path "C:\ImageUpload" is denied"
I have enabled Full Contorl permissions to this folder. I dont understand why I am getting this error.
I am new to WCF, and the most of the code I gathered from online resources.
Appreciate if you could let me know If there is any mistake in my code.
Here is my code.
REST WCF Service Code:
[OperationContract]
[WebInvoke(UriTemplate = "uploadImage/{parameter1}")]
void uploadImage(Stream fileStream);
public void uploadImage(Stream fileStream)
{
string filePath = #"C:\ImageUpload";
FileStream filetoUpload = new FileStream(filePath, FileMode.Create);
byte[] byteArray = new byte[10000];
int bytesRead, totalBytesRead = 0;
do
{
bytesRead = fileStream.Read(byteArray, 0, byteArray.Length);
totalBytesRead += bytesRead;
}
while (bytesRead > 0);
filetoUpload.Write(byteArray, 0, byteArray.Length);
filetoUpload.Close();
filetoUpload.Dispose();
}
This is my Test Client Code(Simple .aspx web page)
protected void btnUpload_Click(object sender, EventArgs e)
{
string file = FileUpload1.FileName;
RESTService1Client client = new RESTService1Client();
byte[] bytearray = null;
string name = "";
if (FileUpload1.HasFile)
{
name = FileUpload1.FileName;
Stream stream = FileUpload1.FileContent;
stream.Seek(0, SeekOrigin.Begin);
bytearray = new byte[stream.Length];
int count = 0;
while (count < stream.Length)
{
bytearray[count++] = Convert.ToByte(stream.ReadByte());
}
}
WebClient wclient = new WebClient();
wclient.Headers.Add("Content-Type", "image/jpeg");
client.uploadImage(FileUpload1.FileContent);
}

It's likely nothing to do with WCF or your code. It really is highly probable that permissions on that folder are insufficient for the IIS process user. By default the ASP.NET user is Network Service.
Try creating a new Windows user just for your ASP.NET application. Grant that user explicit read/write access to the upload folder. Then use Impersonation to make ASP.NET use that user.
http://www.codeproject.com/Articles/107940/Back-to-Basic-ASP-NET-Runtime-Impersonation

Rewrite server side as such:
REST WCF Service Code:
[OperationContract]
[WebInvoke(UriTemplate = "uploadImage/{parameter1}/{parameter2}")]
void uploadImage(Stream fileStream, string fileName);
.
public void uploadImage(Stream fileStream, string fileName)
{
string filePath = #"C:\ImageUpload\";
using (FileStream filetoUpload = new FileStream(filePath + fileName, FileMode.Create))
{
byte[] byteArray = new byte[10000];
int bytesRead = 0;
do
{
bytesRead = fileStream.Read(byteArray, 0, byteArray.Length);
if (bytesRead > 0)
{
filetoUpload.Write(byteArray, 0, bytesRead);
}
}
while (bytesRead > 0);
}
}
and your client side as such:
protected void btnUpload_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile)
{
RESTService1Client client = new RESTService1Client();
client.uploadImage(FileUpload1.FileContent, Path.GetFileName(FileUpload1.FileName));
}
}

Related

WCF: ZIP file generation

I am uploading a file using a WCF service.
The client side code looks like this:
System.ServiceModel.EndpointAddress endPointAddress = new System.ServiceModel.EndpointAddress(address);
IFileStreamService proxy = new FileStreamServiceClient("FileTransfer", endPointAddress);
proxy.UploadFile(uploadReq); //upload the file
Server side includes
public void UploadFile(FileUploadRequest uploadRequest)
{
try
{
string targetFile = uploadRequest.getTargetFile();
Stream sourceStream = uploadRequest.FileByStream;
Log("Going to read stream from client");
using (FileStream outfile = new FileStream(targetFile, FileMode.Create))
{
const int bufferSize = 65536; // 64K chunk
Byte[] buffer = new Byte[bufferSize];
int bytesRead = sourceStream.Read(buffer, 0, bufferSize);
while (bytesRead > 0)
{
outfile.Write(buffer, 0, bytesRead);
bytesRead = sourceStream.Read(buffer, 0, bufferSize);
}
}
}
}
I am not doing any zipping at client side. But at the server side zip file is getting created like this
temp_c7dfbfd7-3495-43b6-a0ec-e46153cef72a.zip
zip file is also corrupted. Can anybody point me to where things are going wrong?

ASP.NET: Serve large video as content with one time url

I need serve a very large video (1gb) as content and in order to do it I using the following code.
protected void Page_Load(object sender, EventArgs e)
{
///check the token
///proceed if token if valid
Response.Clear();
Response.Buffer = false;
Response.ContentType = "video/mp4";
var wc = new WebClient();
string filePath = Server.MapPath("videos/vid.mp4");
//Context.Response.BinaryWrite(File.ReadAllBytes(filePath));
const int chunkSize = 1024; // read the file by chunks of 1KB
using (var file = File.OpenRead(filePath))
{
int bytesRead;
byte[] buffer = new byte[chunkSize];
while ((bytesRead = file.Read(buffer, 0, buffer.Length)) > 0)
{
Context.Response.BinaryWrite(buffer);
}
}
Response.End();
}
Questions
Is this the right way?
Video is getting played but video's seek bar is not working.
How to provide video in chunks to the client?

Download a torrent file result is corrupt WP8

in an app I am making some of the files required are torrent files but i'm having an odd issue, whenever I download a torrent file through the app the files ends up corrupt and wont open in any torrent app, I used wptools to extract them to a pc and test it and still corrupt here is my code I can't see what 'im doing wrong, I am fairly new to using webclient. I assume it has something to do with the way im saving the file any help would be great thanks.
private void tbLink_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
string[] linkInfo = (sender as TextBlock).Tag as string[];
fileurl = linkInfo[0];
System.Diagnostics.Debug.WriteLine(fileurl);
WebClient client = new WebClient();
client.OpenReadCompleted += client_OpenReadCompleted;
client.OpenReadAsync(new Uri(fileurl), linkInfo);
client.AllowReadStreamBuffering = true;
}
async void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
string[] linkInfo = e.UserState as string[];
filetitle = linkInfo[1];
filesave = (filetitle);
var isolatedfile = IsolatedStorageFile.GetUserStoreForApplication();
using (IsolatedStorageFileStream stream = isolatedfile.OpenFile(filesave, System.IO.FileMode.Create))
{
byte[] buffer = new byte[e.Result.Length];
while (e.Result.Read(buffer, 0, buffer.Length) > 0)
{
stream.Write(buffer, 0, buffer.Length);
}
}
try
{
StorageFolder local = Windows.Storage.ApplicationData.Current.LocalFolder;
StorageFile torrentfile = await local.GetFileAsync(filesave);
Windows.System.Launcher.LaunchFileAsync(torrentfile);
}
catch (Exception)
{
MessageBox.Show("File Not Found");
}
This is incorrect:
byte[] buffer = new byte[e.Result.Length];
while (e.Result.Read(buffer, 0, buffer.Length) > 0)
{
stream.Write(buffer, 0, buffer.Length);
}
The Read method will return the number of bytes read, it can be less than buffer.Length. So the code should read:
int byteCount;
// Select an appropriate buffer size.
// This is a buffer, not space for the entire file.
byte[] buffer = new byte[4096];
while ((byteCount = e.Result.Read(buffer, 0, buffer.Length)) > 0)
{
stream.Write(buffer, 0, byteCount);
}
UPDATE: If the data is compressed, as in the question that you posted in your comment, then you can decompress the stream:
int byteCount;
byte[] buffer = new byte[4096];
using (GZipStream zs = new GZipStream(e.Result, CompressionMode.Decompress))
{
while ((byteCount = zs.Read(buffer, 0, buffer.Length)) > 0)
{
stream.Write(buffer, 0, byteCount);
}
}
Note that I have not tested this code, I'm assuming that e.Result is a stream.

Upload file from WinRT to WCF

Help again please. I managed to upload a file from ASP.NET to my WCF service and it works like a charm. Now I want to do the same thing from WinRT without success. My file upload service is based on this post http://www.seesharpdot.net/?p=214. From ASP.NET I upload the file using this code
string filePath = Server.MapPath("~/Files/Happy.jpg");
string fileName = "Happy.jpg";
ServiceReference1.FileMetaData metadata = new ServiceReference1.FileMetaData();
metadata.LocalFilename = fileName;
metadata.FileType = ".jpg";
fileStream = new FileInfo(filePath).OpenRead();
oService.UploadFile(metadata, fileStream);
byte[] buffer = new byte[2048];
int bytesRead = fileStream.Read(buffer, 0, 2048);
while (bytesRead > 0)
{
fileStream.Write(buffer, 0, 2048);
bytesRead = fileStream.Read(buffer, 0, 2048);
}
From WinRT I thought this will work but it does not. No exception is thrown.
FileOpenPicker openPicker = new FileOpenPicker();
openPicker.ViewMode = PickerViewMode.Thumbnail;
openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
openPicker.FileTypeFilter.Add(".jpg");
openPicker.FileTypeFilter.Add(".jpeg");
openPicker.FileTypeFilter.Add(".png");
StorageFile file = await openPicker.PickSingleFileAsync();
if (file != null)
{
byte[] bytes = await GetByteFromFile(file);
await App.ServiceInstance.UploadFileAsync(bytes);
}
// This is the method to convert the StorageFile to a Byte[]
private async Task<byte[]> GetByteFromFile(StorageFile storageFile)
{
var stream = await storageFile.OpenReadAsync();
using (var dataReader = new DataReader(stream))
{
var bytes = new byte[stream.Size];
await dataReader.LoadAsync((uint)stream.Size);
dataReader.ReadBytes(bytes);
return bytes;
}
}
What is interesting is that my WCF Service method only accepts a byte array (byte[]) as parameter and ignores the messageContract. Do I need to change my WCF service? How would you recommend I go about to fix this? Any help appreciated.
My WCF Service:
public void UploadFile(FileUploadMessage request)
{
Stream fileStream = null;
Stream outputStream = null;
try
{
fileStream = request.FileByteStream;
string rootPath = HttpContext.Current.Server.MapPath("~\\Files"); ; // ConfigurationManager.AppSettings["RootPath"].ToString();
string newFileName = Path.Combine(rootPath, request.MetaData.LocalFileName);
outputStream = new FileInfo(newFileName).OpenWrite();
const int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int bytesRead = fileStream.Read(buffer, 0, bufferSize);
while (bytesRead > 0)
{
outputStream.Write(buffer, 0, bytesRead);
bytesRead = fileStream.Read(buffer, 0, bufferSize);
}
}
catch (IOException ex)
{
throw new FaultException<IOException>(ex, new FaultReason(ex.Message));
}
finally
{
if (fileStream != null)
{
fileStream.Close();
}
if (outputStream != null)
{
outputStream.Close();
}
}
}
I had to implement the same, but the WinRT generation of the library is different as to the one for desktop (Console application).
I had to take out Mtom in the binding, and leave the WCF service parameter as a Stream type.
This still allowed me to upload the document as required. However, on the service, i named the file to the md5 checksum value. The windows 8 app then sent another message to the service, with the parameter being the md5 checksum (calculated on the WinRt device) along with the file metadata. The WCF service then looked for the file with the md5 checksum and renamed the file.
So its a 2 step process from what I see as an immediate workaround, which I think i am happy with.
Happy to share the code for the md5 checksum on the service and WinRt side if required.

How to upload photo to a server from .net winforms?

I have created a window form application in C#. There is a user registration section where user details are filled and a photo is uploaded. How to upload photo a common location in server not in client system. I need to upload the picture of user to a location in server so that the website section of the application can show the picture in the profile of user.
I would actually store the information including the picture in the database, so it's available from all your other applications.
if you simply want to copy a raw file from client computer to a centralized location, as a starting point:
private void button1_Click(object sender, EventArgs e)
{
WebClient myWebClient = new WebClient();
string fileName = textBox1.Text;
string _path = Application.StartupPath;
MessageBox.Show(_path);
_path = _path.Replace("Debug", "Images");
MessageBox.Show(_path);
myWebClient.UploadFile(_path,fileName);
}
private void btnBrowse_Click(object sender, EventArgs e)
{
OpenFileDialog ofDlg = new OpenFileDialog();
ofDlg.Filter = "JPG|*.jpg|GIF|*.gif|PNG|*.png|BMP|*.bmp";
if (DialogResult.OK == ofDlg.ShowDialog())
{
textBox1.Text = ofDlg.FileName;
button1.Enabled = true;
}
else
{
MessageBox.Show("Go ahead, select a file!");
}
}
Maybe best way is to use an FTP Server ,if you can install it .
Than you can upload file's using this code
FileInfo toUpload = new FileInfo("FileName");
System.Net.FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://serverip/FileName");
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential("UserName","Password");
Stream ftpStream = request.GetRequestStream();
FileStream file = File.OpenRead(files);
int length = 1024;
byte[] buffer = new byte[length];
int bytesRead = 0;
do
{
bytesRead = file.Read(buffer, 0, length);
ftpStream.Write(buffer, 0, bytesRead);
}
while (bytesRead != 0);
file.Close();
ftpStream.Close();
upload a file to FTP server using C# from our local hard disk.
private void UploadFileToFTP()
{
FtpWebRequest ftpReq = (FtpWebRequest)WebRequest.Create("ftp://www.server.com/sample.txt");
ftpReq.UseBinary = true;
ftpReq.Method = WebRequestMethods.Ftp.UploadFile;
ftpReq.Credentials = new NetworkCredential("user", "pass");
byte[] b = File.ReadAllBytes(#"E:\sample.txt");
ftpReq.ContentLength = b.Length;
using (Stream s = ftpReq.GetRequestStream())
{
s.Write(b, 0, b.Length);
}
FtpWebResponse ftpResp = (FtpWebResponse)ftpReq.GetResponse();
if (ftpResp != null)
{
if(ftpResp.StatusDescription.StartsWith("226"))
{
Console.WriteLine("File Uploaded.");
}
}
}

Categories