I want to upload image from the WP page to the database via WCF service. I have the following service implementation that compiles fine:
public bool Upload(Stuff picture)
{
FileStream fileStream = null;
BinaryWriter writer = null;
string filePath;
try
{
filePath = HttpContext.Current.Server.MapPath(".") +
ConfigurationManager.AppSettings["PictureUploadDirectory"] +
picture.stuffName;
if (picture.stuffName != string.Empty)
{
fileStream = File.Open(filePath, FileMode.Create);
writer = new BinaryWriter(fileStream);
writer.Write(picture.stuffPhoto);
}
return true;
}
catch (Exception)
{
return false;
}
finally
{
if (fileStream != null)
fileStream.Close();
if (writer != null)
writer.Close();
}
}
But on the WP page I have errors. I'm following this tutorial: http://www.silverlightshow.net/items/Uploading-and-downloading-images-from-WCF-in-Silverlight.aspx Here is my code:
private void uploadBtn_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog(); // error 1,2
openFileDialog.Filter = "JPEG files|*.jpg";
if (openFileDialog.ShowDialog() == true)
{
Stream stream = (Stream)openFileDialog.File.OpenRead();
byte[] bytes = new byte[stream.Length];
stream.Read(bytes, 0, (int)stream.Length);
string fileName = openFileDialog.File.Name;
ServiceReference1.Stuff pictureFile = new ServiceReference1.Stuff();
ServiceReference1.Stuff.stuffName = fileName; //error 3,4
ServiceReference1.Stuff.stuffPhoto = bytes;
ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
client.UploadCompleted += new EventHandler
<System.ComponentModel.AsyncCompletedEventArgs>(client_UploadCompleted); // error 5
client.UploadAsync(pictureFile);
}
}
void client_UploadCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
if (e.Error == null)
{
if (e.Result) // error 6
{
ResultTextlock.Text = "Upload succeeded :)";
}
else
{
ResultTextBlock.Text = "Upload failed :(";
}
}
}
Errors are:
1,2) The type or namespace name 'OpenFileDialog' could not be found (are you missing a using directive or an assembly reference?).
3,4) An object reference is required for the non-static field, method, or property 'PhoneApp1.ServiceReference1.Stuff.stuffName.get'
5) Cannot implicitly convert type 'System.EventHandler' to 'System.EventHandler'
6)'System.ComponentModel.AsyncCompletedEventArgs' does not contain a definition for 'Result' and no extension method 'Result' accepting a first argument of type 'System.ComponentModel.AsyncCompletedEventArgs' could be found (are you missing a using directive or an assembly reference?)
7) The type or namespace name 'Forms' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?) (I have tis statement: using System.Windows.Forms;)`
Windows Phone does not have OpenFileDialog, you have to use the Photo Chooser task
You are referencing the ServiceReference1.Stuff as a static object. I think you mean pictureFile.stuffName etc.
The types of the event are wrong, as the error message states.
Windows Phone doesn't have Windows Forms available.
You can't just copy/paste code from Silverlight to Windows Phone and assume it works. You have to learn how to work with WP. Also these are basic errors that are explained clearly in the error messages. I suggest brushing up on the basics.
Related
I need to use a prepopulated database in my Xamarin.Forms application, so I searched for possible solutions.
I've found this article and tested with Android - it worked okay.
However, it uses Windows Phone 8 - that is not compatible with Windows 8.1.
So I tried to modify this Windows Phone 8 code:
public static void CopyDatabaseIfNotExists(string dbPath)
{
var storageFile = IsolatedStorageFile.GetUserStoreForApplication();
if (!storageFile.FileExists(dbPath))
{
using (var resourceStream = Application.GetResourceStream(new Uri("people.db3", UriKind.Relative)).Stream)
{
using (var fileStream = storageFile.CreateFile(dbPath))
{
byte[] readBuffer = new byte[4096];
int bytes = -1;
while ((bytes = resourceStream.Read(readBuffer, 0, readBuffer.Length)) > 0)
{
fileStream.Write(readBuffer, 0, bytes);
}
}
}
}
}
Into this code:
public static async void CopyDatabaseIfNotExists(string dbPath)
{
IStorageFolder applicationFolder = ApplicationData.Current.LocalFolder;
StorageFile existingFile = await Windows.Storage.StorageFile.GetFileFromPathAsync("prep.db");
IStorageFile storageFile = await applicationFolder.GetFileAsync(dbPath);
if (storageFile == null)
{
await existingFile.CopyAndReplaceAsync(storageFile);
However, it does not work, I can't provide a proper filepath for my existing db file (it is in the root of the project), it always gives me this error:
Value does not fall within the expected range.
How could I get a proper path to my prepopulated file?
Also, why do I need to use a stream based "copy" when I could simply copy the file itself?
The following code works for Windows Phone 8.1 and UWP:
public async void CopyDatabaseIfNotExists(string dbPath)
{
IStorageFolder applicationFolder = ApplicationData.Current.LocalFolder;
var existingFile = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(myDBFileName);
if (!await CheckForExistingFile(myDBFileName))
await existingFile.CopyAsync(applicationFolder);
}
private async Task<bool> CheckForExistingFile(string filePath)
{
try
{
var file = await ApplicationData.Current.LocalFolder.GetFileAsync(Uri.EscapeDataString(filePath));
//no exception means file exists
return true;
}
catch (FileNotFoundException ex)
{
//find out through exception
return false;
}
}
I have two dlls (xNet.dll and ag.dll), which I want to use in my project.
I add them to resourses, stated that build action is Embedded Resource.
Next I have such code to load the first dll:
public Form1()
{
AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolve;
InitializeComponent();
}
private static Assembly AssemblyResolve(object sender, ResolveEventArgs args)
{
Assembly assembly = Assembly.GetExecutingAssembly();
string assemblyName = args.Name.Split(',')[0];
using (Stream stream = assembly.GetManifestResourceStream("Yandex.dll.xNet.dll"))
{
if (stream == null)
return null;
byte[] rawAssembly = new byte[stream.Length];
stream.Read(rawAssembly, 0, (int)stream.Length);
return Assembly.Load(rawAssembly);
}
}
How to load the second dll?
You should match on the requested assembly name and return the correct assembly.
I don't know your assembly names so i'm doing only a very simple matching but it should look something like :
private static Assembly AssemblyResolve(object sender, ResolveEventArgs args)
{
if (args.Name.Contains("xNet"))
{
return LoadAssemblyFromResource("Yandex.dll.xNet.dll");
}
if (args.Name.Contains("ag"))
{
return LoadAssemblyFromResource("ag.dll");
}
return null;
}
private static Assembly LoadAssemblyFromResource(string resourceName)
{
Assembly assembly = Assembly.GetExecutingAssembly();
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
{
if (stream == null)
return null;
byte[] rawAssembly = new byte[stream.Length];
stream.Read(rawAssembly, 0, (int)stream.Length);
return Assembly.Load(rawAssembly);
}
}
Why not extract the dll's to a temporary path and then load them.Assume you've two dll's,namely firstDll and secondDll with both having build action set to Resource.
Then extract those dll's to a temporary path,like this;
byte[] firstAssembly=Properties.Resources.firstDll;
File.WriteAllBytes(#"C:\Temp\firstDll.dll",firstAssembly);
byte[] secondAssembly=Properties.Resources.secondDll;
File.WriteAllBytes(#"C:\Temp\secondDll.dll",secondAssembly);
After this use Reflection to load those assembles and work with them.
I have a C# console program that uses the nuget plugin SocketIO4Net
When I build the exe and move it to my Windows 2008 server, it doesn't work, whereas on my local machine, it works.
Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'SocketIOClient, Version=0.6.26.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
Is there any way I can bake all my dependencies into the exe?
I tried doing:
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
var resName = "converter.SocketIOClient.dll";
var thisAssembly = Assembly.GetExecutingAssembly();
using (var input = thisAssembly.GetManifestResourceStream(resName))
{
return input != null
? Assembly.Load(StreamToBytes(input))
: null;
}
};
But that didn't work. Perhaps I'm getting the resourceName wrong?
Here is my example which is based off of Embedding one dll inside another as an embedded resource and then calling it from my code but has some helpful screenshots.
using System;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using MyEmbbedFile;
namespace ProjectNameSpace
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
var resName = "ProjectNameSpace.MyEmbbedFile.dll";
var thisAssembly = Assembly.GetExecutingAssembly();
using (var input = thisAssembly.GetManifestResourceStream(resName))
{
return input != null
? Assembly.Load(StreamToBytes(input))
: null;
}
};
}
private void button1_Click(object sender, EventArgs e)
{
MyEmbbedFileApp app = new MyEmbbedFileApp();
app.DoStuff();
}
private static byte[] StreamToBytes(Stream input)
{
var capacity = input.CanSeek ? (int)input.Length : 0;
using (var output = new MemoryStream(capacity))
{
int readLength;
var buffer = new byte[4096];
do
{
readLength = input.Read(buffer, 0, buffer.Length);
output.Write(buffer, 0, readLength);
}
while (readLength != 0);
return output.ToArray();
}
}
}
}
There are 2 other things you will need to do:
You will still need to make sure you add your assembly as a reference so your code compiles. Just make sure it does not copy to the output directory.
The second thing you need to do is add your reference to the project as a normal file. Then set it's build action to Embedded Resource under properties.
Yes.
Use AppDomain.AssemblyResolve to 'hydrate' embedded assemblies at runtime.
This project SQLDiagCmd at Github contains an example of doing this. It is based on Jeffrey Ricther's method:
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
String resourceName = "AssemblyLoadingAndReflection." +
new AssemblyName(args.Name).Name + ".dll";
using (var stream = Assembly.GetExecutingAssembly()
.GetManifestResourceStream(resourceName))
{
Byte[] assemblyData = new Byte[stream.Length];
stream.Read(assemblyData, 0, assemblyData.Length);
return Assembly.Load(assemblyData);
}
};
The 'trick' is where the embedded assembly is located and (as you have found), the string used to refer to it in the AssemblyResolve handler. [I don't have time right now but will look again later...]
MonoDevelop (2.10.8) is reporting:
JPGCorruptForm.cs(20,20): Warning CS0219: The variable `myStream' is assigned but its value is never used (CS0219) (JPGCorrupt)
For this function:
private void toolStripButtonChooseText_Click(object sender, EventArgs e)
{
Stream myStream = null;
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.InitialDirectory = ".";
openFileDialog.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
openFileDialog.FilterIndex = 1;
openFileDialog.RestoreDirectory = false;
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
Stop();
try
{
if ((myStream = openFileDialog.OpenFile()) != null)
{
_settings.TextFile = openFileDialog.FileName;
CurrentTextFile = _settings.TextFile;
}
}
catch (Exception ex)
{
MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message);
}
}
}
This is my frist mono test project and I'm not sure if this kind of thing is normal. It certainly is not fatal, but could get annoying.
Well you're assigning a value to the variable, but you're never actually reading from it. In other words, you could easily remove it, just changing the middle expression to:
if (openFileDialog.OpenFile() != null)
Note that your existing code doesn't actually read from the variable even though you might think it does in the comparison to null. It's more like this:
Stream tmp = openFileDialog.OpenFile();
myStream = tmp;
if (tmp != null)
It sounds like you probably should be using it, to close the stream if nothing else... although I'd then declare it as late as possible, like this:
using (Stream myStream = openFileDialog.OpenFile())
{
if (myStream != null)
{
_settings.TextFile = openFileDialog.FileName;
CurrentTextFile = _settings.TextFile;
}
}
Here's a simpler example of the same problem, but the way:
using System;
class Test
{
static void Main()
{
string x;
if ((x = "Hello") != null)
{
Console.WriteLine("Yes");
}
}
}
Note that with warning level 4 (and possibly lower ones), the Microsoft C# 4 compiler picks up on it too:
Test.cs(7,16): warning CS0219: The variable 'x' is assigned but its value is
never used
i have the following code used to serialize a label's content. When i press the "save" button, an xml file is generated. When press the "load" button after i select the same xml file, an error occured, IOexception was unhandled, The process cannot access the file 'C:\datasaved.xml' because it is being used by another process. Is there anything wrong with my code?
Thanks.
public class FormSaving
{
private string major;
public string Majorversion
{
get;
set;
}
}
private void SaveButton_Click(object sender, RoutedEventArgs e)
{
string savepath;
SaveFileDialog DialogSave = new SaveFileDialog();
// Default file extension
DialogSave.DefaultExt = "txt";
// Available file extensions
DialogSave.Filter = "XML file (*.xml)|*.xml|All files (*.*)|*.*";
// Adds a extension if the user does not
DialogSave.AddExtension = true;
// Restores the selected directory, next time
DialogSave.RestoreDirectory = true;
// Dialog title
DialogSave.Title = "Where do you want to save the file?";
// Startup directory
DialogSave.InitialDirectory = #"C:/";
DialogSave.ShowDialog();
savepath = DialogSave.FileName;
DialogSave.Dispose();
DialogSave = null;
FormSaving abc = new FormSaving();
abc.Majorversion = MajorversionresultLabel.Content.ToString();
FileStream savestream = new FileStream(savepath, FileMode.Create);
XmlSerializer serializer = new XmlSerializer(typeof(FormSaving));
serializer.Serialize(savestream, abc);
}
private void LoadButton_Click(object sender, RoutedEventArgs e)
{
Stream checkStream = null;
Microsoft.Win32.OpenFileDialog DialogLoad = new Microsoft.Win32.OpenFileDialog();
DialogLoad.Multiselect = false;
DialogLoad.Filter = "XML file (*.xml)|*.xml|All files (*.*)|*.*";
if ((bool)DialogLoad.ShowDialog())
{
try
{
if ((checkStream = DialogLoad.OpenFile()) != null)
{
loadpath = DialogLoad.FileName;
}
}
catch (Exception ex)
{
System.Windows.MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message);
}
}
else
{
System.Windows.MessageBox.Show("Problem occured, try again later");
}
FormSaving abc;
FileStream loadstream = new FileStream(loadpath, FileMode.Open);
XmlSerializer serializer = new XmlSerializer(typeof(FormSaving));
abc = (FormSaving)serializer.Deserialize(loadstream);
loadstream.Close();
MajorversionresultLabel.Content = abc.Majorversion;
}
This is the most immediate problem:
FileStream savestream = new FileStream(savepath, FileMode.Create);
XmlSerializer serializer = new XmlSerializer(typeof(FormSaving));
serializer.Serialize(savestream, abc);
You're not closing the stream, so the file can't be reopened for read. Use a using statement:
using (Stream savestream = new FileStream(savepath, FileMode.Create))
{
XmlSerializer serializer = new XmlSerializer(typeof(FormSaving));
serializer.Serialize(savestream, abc);
}
You should take the same approach when loading the file as well, instead of calling Close explicitly... with your current code, if an exception occurs when deserializing, you won't be closing the stream.
You're also opening the file via Dialog.OpenFile, but not closing that stream... and why bother opening it twice? Just read from the stream you've opened.
Finally (for the moment) you're catching an exception (blindly, with no regard for which exceptions are really worth trying to handle) but then continuing regardless. If you've caught an exception, chances are the last part of the method won't execute correctly, so you should either return or throw another exception yourself.