Sending Image from WPF to Web API, thread error - c#

So, I want to send the image from my WPF app to the Web API controller. When I get the image as BitmapImage and try to send it, I get the error "the calling thread cannot access this object because a different thread owns it". I don't see how am I modifying UI and why do I get the error. Here's the code:
WPF code:
private void BtnSendImage_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.InitialDirectory = Environment.SpecialFolder.MyDocuments.ToString();
BitmapImage slika = null;
if (ofd.ShowDialog() == true)
{
odabranaSlika = ofd.FileName;
Uri adresa = new Uri(odabranaSlika, UriKind.Absolute);
slika = new BitmapImage(adresa);
ItemDAL idal = new ItemDAL();
if (idal.SendImage(slika))
{
MessageBox.Show("Yay!");
}
else
{
MessageBox.Show("Awwww");
}
}
}
Method SendImage from the ItemDAL class (the code stops at postResult.Wait() part):
public bool SendImage(BitmapImage bmp)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:52407/");
var postResult = client.PostAsJsonAsync<BitmapImage>("api/values/postimage", bmp);
postResult.Wait();
var result = postResult.Result;
if (result.IsSuccessStatusCode)
{
return true;
}
else
{
return false;
}
}
}
What am I doing wrong? I know I'm not suppose to modify UI, unless it's from the main thread, bot how is this doing anything to the UI?

Related

image doesn't change - WPF

I'm trying to change an image on runtime but it's not working.
I have a user control that when you click on imagebtn it's opening a new window with a list of images.
the next step is to take the image selected from the list, close the new window, and put the image on the imagebtn.
the user control still opens in the background.
this is my code.
NewWindow:
private string myData;
public ImagesWindow()
{
InitializeComponent();
InitialImageList();
}
private async void InitialImageList()
{
//add try catch
string get = await HttpRequests.GetRequest(URLImages);
allJsonCategory = JsonConvert.DeserializeObject<List<ImageArray>>(get);
Console.WriteLine(get);
ImageBoxList.ItemsSource = images;
foreach (var item in allJsonCategory)
{
images.Add(item);
}
}
private void ImageBoxList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
selectedImage = (ImageArray)ImageBoxList.SelectedItem;
myData = selectedImage.full_path;
Console.WriteLine("you clicked on: " + selectedImage.name);
ProductsCategory pro = new ProductsCategory();
pro.imagePath = myData;
this.Close();
}
my usercontrol(in mainWindow):
public void setImage(string imagePath)
{
if (!imageURL.Equals(""))
{
Image imageBtn = new Image();
var imgUrl = new Uri(imagePath);
var imageData = new WebClient().DownloadData(imgUrl);
// or you can download it Async won't block your UI
// var imageData = await new WebClient().DownloadDataTaskAsync(imgUrl);
var bitmapImage = new BitmapImage { CacheOption = BitmapCacheOption.OnLoad };
bitmapImage.BeginInit();
bitmapImage.StreamSource = new MemoryStream(imageData);
bitmapImage.EndInit();
imageBtn.Source = bitmapImage;
//this.imageBtn.InvalidateVisual();
}
}
XAML of the image:
where is my mistake?
thank you all :)

How to get an access authorization in the foreground of a WPF app? C#

I am writing a WPF app in C# which opens another program in the background. In my case I am opening TIA-Portal (a SIEMENS Software). To open a project the TIA-Portal needs an access authorization from the user. But the window of the access authorization always appears behind my MainWindow.
The code I am using:
private void openTIA_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog SearchTIAProject = new OpenFileDialog();
SearchTIAProject.Title = "TIA Projekt öffnen";
SearchTIAProject.Filter = "TIA Portal Project|*.ap14";
if (SearchTIAProject.ShowDialog() == true)
{
Block_PfadDesTIAProgramms.Visibility = System.Windows.Visibility.Visible;
Block_PfadDesTIAProgramms.Text = (SearchTIAProject.FileName);
string projectpath = SearchTIAProject.FileName;
myPublicPath = GetPublicPath(projectpath);
myOpenedTIAProject = OpenTIAProject(projectpath); //Functioncall
}
else
{
MessageBox.Show("Keine Datei ausgewählt!");
}
}
public Siemens.Engineering.Project OpenTIAProject(string referedPath)
{
myTIAPortal = new TiaPortal(TiaPortalMode.WithoutUserInterface);
ProjectComposition projects = myTIAPortal.Projects;
FileInfo projectPathTIA = new FileInfo(referedPath);
//This line then needs the access authorization:
myOpenedTIAProject = projects.Open(projectPathTIA);
return myOpenedTIAProject;
}
I have also tried this around the functioncall but it did not work:
MainWindow.Topmost = false;
myOpenedTIAProject = OpenTIAProject(projectpath);
MainWindow.Topmost = true;
MainWindow.Topmost = false;
Is there any way to the access authorization to the foreground (or the MainWindow to the background)?

Facebook logout Windows Phone Application without opening WebBrowser

I am trying to develop a Windows Phone 7 application using Facebook login and logout operations. I found Facebook SDK and used it in order to carry out login, by opening WebBrowser. The user enters credentials to this browser and logs in successfully. Moreover, I managed to login the user without using any SDK, just using http requests, like the SDK actually does. However, I want to logout users without using any WebBrowser, but just clicking a button for example. There are so many solutions in the web suggesting that I should open web browser and navigate it to a certain URL in order to logout. However, this is not what I want. I think there should be a way to logout by clearing cookies, which I dont exactly know how to do, or any other that you suggest. Some part of my code below:
private static String appID = "";
private static String appSecret = "";
public static void login(String[] permissions)
{
try
{
permissionArray = permissions;
popup = new Popup();
popup.Height = 480;
popup.Width = 480;
popup.VerticalOffset = 100;
FacebookLoginUserControl control = new FacebookLoginUserControl();
control.facebookWebBrowser.Loaded += new RoutedEventHandler(webBrowser_Loaded);
control.facebookWebBrowser.Navigated += new EventHandler<System.Windows.Navigation.NavigationEventArgs>(webBrowser_Navigated);
popup.Child = control;
popup.IsOpen = true;
}
catch (Exception e)
{
//handle
}
}
private static void webBrowser_Loaded(Object sender, RoutedEventArgs e)
{
WebBrowser wb = (WebBrowser)sender;
String loginUrl = GetFacebookLoginUrl();
wb.Navigate(new Uri(loginUrl));
}
private static String GetFacebookLoginUrl()
{
String permissionString = String.Empty;
if (permissionArray.Length > 0)
permissionString = String.Join(",", permissionArray);
var uriParams = new Dictionary<string, string>() {
{"client_id", appID},
{"response_type", "token"},
{"scope", permissionString},
{"redirect_uri", "http://www.facebook.com/connect/login_success.html"},
{"display", "touch"}
};
StringBuilder urlBuilder = new StringBuilder();
foreach (var current in uriParams)
{
if (urlBuilder.Length > 0)
{
urlBuilder.Append("&");
}
var encoded = HttpUtility.UrlEncode(current.Value);
urlBuilder.AppendFormat("{0}={1}", current.Key, encoded);
}
var loginUrl = "http://www.facebook.com/dialog/oauth?" + urlBuilder.ToString();
return loginUrl;
}
private static void webBrowser_Navigated(Object sender, System.Windows.Navigation.NavigationEventArgs e)
{
if (string.IsNullOrEmpty(e.Uri.Fragment)) return;
if (e.Uri.AbsoluteUri.Replace(e.Uri.Fragment, "") == "http://www.facebook.com/connect/login_success.html")
{
string text = HttpUtility.HtmlDecode(e.Uri.Fragment).TrimStart('#');
var pairs = text.Split('&');
foreach (var pair in pairs)
{
var kvp = pair.Split('=');
if (kvp.Length == 2)
{
if (kvp[0] == "access_token")
{
accessToken = kvp[1];
MessageBox.Show("Access granted");
RequestUserProfile();
}
}
}
if (string.IsNullOrEmpty(accessToken))
{
MessageBox.Show("Unable to authenticate");
}
popup.IsOpen = false;
}
}
private static void RequestUserProfile()
{
var profileUrl = string.Format("https://graph.facebook.com/me?access_token={0}", HttpUtility.UrlEncode(accessToken));
request = (HttpWebRequest)HttpWebRequest.Create(new Uri(profileUrl));
request.Method = "GET";
request.BeginGetResponse(result =>
{
try
{
var resp = (result.AsyncState as HttpWebRequest).EndGetResponse(result);
using (var strm = resp.GetResponseStream())
{
StreamReader sr = new StreamReader(strm);
var responseString = sr.ReadToEnd();
}
}
catch (Exception ex)
{
//
}
}, request);
}
Any Ideas to solve the problem.
Thanks in advance
What's actually so spooky in using webBrowser? If you programmatically create a WebBrowser object, it won't be visible, unless you'd add it somewhere on form/page. If you want to clear cookies for Facebook, the solution will be something like that:
// Can be invoked from your button_click event
public void TryLogout()
{
webBrowser = new WebBrowser();
Uri uri = new Uri("http://m.facebook.com/home.php?r", UriKind.Absolute);
webBrowser.LoadCompleted += new LoadCompletedEventHandler(webBrowser_TryLogoutLoadCompleted);
webBrowser.Navigate(uri);
}
And then:
private void webBrowser_TryLogoutLoadCompleted(object sender, EventArgs e)
{
try
{
var cookies = webBrowser.GetCookies();
foreach (Cookie cookie in cookies)
{
if (cookie.Domain.Contains("m.facebook.com"))
{
cookie.Discard = true;
cookie.Expired = true;
}
}
// we've just cleaned up cookies
}
finally
{
webBrowser.LoadCompleted -= webBrowser_TryLogoutLoadCompleted;
}
}
Hope this helps.
GetCookies method

photoChooserTask cause SocketException

I want to return a photo using PhotoChooserTask like this:
private void getimage_Click(object sender, EventArgs e)
{
photoChooserTask = new PhotoChooserTask();
photoChooserTask.Completed += new EventHandler<PhotoResult>(photoChooserTask_Completed);
try
{
photoChooserTask.Show();
}
catch (System.InvalidOperationException ex)
{
MessageBox.Show("An error occurred.");
}
}
void photoChooserTask_Completed(object sender, PhotoResult ee)
{
if (ee.TaskResult == TaskResult.OK)
{
BitmapImage bmp = new BitmapImage();
bmp.SetSource(ee.ChosenPhoto);
if (ee.TaskResult == TaskResult.OK && ee.Error == null)
{
WriteableBitmap wb = new WriteableBitmap(bmp);
notes.Add(new chatinfo() { sendimage = bmp });
noteListBox.ItemsSource = null;
noteListBox.ItemsSource = notes;
}
}
}
but everytime the program arrived here:"bmp.SetSource(ee.ChosenPhoto);" A SocketException will be called.
private void OnRecieveFrom()
{
var receiveArgs = new SocketAsyncEventArgs();
receiveArgs.RemoteEndPoint = this.IPEndPoint;
receiveArgs.SetBuffer(new Byte[MAX_BUFFER_SIZE], 0, MAX_BUFFER_SIZE);
var strBdr = new StringBuilder();
receiveArgs.Completed += (__, result) =>
{
string message = CreateMessage(result);
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
this.RaiseReceived(message);
});
socket.ReceiveFromAsync(receiveArgs);
};
socket.ReceiveFromAsync(receiveArgs);
}
The SocketException is called by " socket.ReceiveFromAsync(receiveArgs);"
I just want to get a photo from the phone,and there is not send or recieve operation.I don't know why receive function was called.
Would the app lose the socket communication when it jumps to the photo album (the value "RemoteEndPoint" of socket change to null)? p.s. "socket" is an object of class "Socket".
If so, should I recreate the "socket" every time the app jumps out?
Thank you!
Once the PhotoChooserTask is called your app will be Fast App Switched (or maybe even Tombstoned).
Either way your socket will be closed. You'll have to reopen your socket when your app is Activated again.

Error in web browser control navigating

In my web browser app for wp7, i have two xaml pages. One is mainpage.xaml and other is web.xaml.
I have a youtube button in mainpage.xaml, if i click on it, it navigates to youtube.com in web.xaml. But if i press the device back button(to navigate to mainpage) after the youtube is fully navigated, then there is no error. But if i press the back button while the youtube is navigating then it throws an error. Error in recording the history i think(I also have history page to record the history). The error is - "Cannot write to a closed TextWriter". This error will also occur sometime for someother sites too. I have also added the image of that error. Can anyone help me with this? Thanks in advance for your help!
public partial class Web : PhoneApplicationPage
{
List<Uri> HistoryStack;
int HistoryStack_Index;
bool fromHistory;
bool navigationcancelled = false;
public IsolatedStorageFile historyFile = null;
public IsolatedStorageFileStream filestream = null;
public StreamWriter stream = null;
public Web()
{
InitializeComponent();
HistoryStack = new List<Uri>();
historyFile = IsolatedStorageFile.GetUserStoreForApplication();
if (historyFile.FileExists("History.txt"))
{
Error in this line--->filestream = historyFile.OpenFile("History.txt", System.IO.FileMode.Append, FileAccess.Write);--->Error in this line
stream = new StreamWriter(filestream);
}
else
{
filestream = historyFile.OpenFile("History.txt", System.IO.FileMode.Create);
stream = new StreamWriter(filestream);
}
HistoryStack_Index = 0;
fromHistory = false;
browsers[this.currentIndex].Navigated += new EventHandler<System.Windows.Navigation.NavigationEventArgs>(browsers_Navigated);
browsers[this.currentIndex].Navigating += new EventHandler<NavigatingEventArgs>(browsers_Navigating);
}
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
{
stream.Close();
}
}
private void browsers_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
if (!fromHistory)
{
if (HistoryStack_Index < HistoryStack.Count)
{
HistoryStack.RemoveRange(HistoryStack_Index, HistoryStack.Count - HistoryStack_Index);
}
HistoryStack.Add(e.Uri);
//HistoryURL temp = new HistoryURL();
//temp.URL = e.Uri.ToString();
//app.historyList.Add(temp);
Thread.Sleep(100);
Dispatcher.BeginInvoke(() =>
{
string title = (string)browsers[this.currentIndex].InvokeScript("eval", "document.title.toString()");
stream.WriteLine(title + ";" + e.Uri.ToString());---> **Error in this line.**
});
}
HistoryStack_Index += 1;
}
fromHistory = false;
navigationcancelled = false;
}
If I understand this correctly you are having 2 handlers for navigated event (OnNavigatedFrom and browsers_Navigated).
The problem probably is that in OnNavigatedFrom you are calling stream.Close(); so stream.WriteLine will fail the next time it is called since the stream was closed.
Try moving stream.Close(); to the application close event and use stream.Flush() after stream.WriteLine.

Categories