Use data's user on different pages - silverlight

I'm doing an application. Based on mvvm, my app has different pages:
Inscription
Connection
Profil
...
I would like to transfert my user's info from page to page so i'm using
this.Client_ = (Client)IsolatedStorageSettings.ApplicationSettings["Client"];
But i'm not sure that it's the best idea to have my user's info. To get some info like photo, personal information like mail or adress i will call the server. Here I'm talking about the informations that i need for the server to get the correct user's info like pseudo and password. What is the best option to pass information from page to page ?
Thanks a lot for responding, sorry for english mistakes i could have done, je ne suis pas anglais ;).

Use a constants class and have a static member. You would be able to access that from anywhere. (same is the case with declaring something in App.xaml.cs but it is not recommended overloading the app.xaml.cs class)
rough example:
public class AppConstants
{
public static string Username = string.Empty;
public static Image userImage;
}
while navigating from page A to page B, you can set those parameters in page A
AppConstants.Username = "Abhiram";
AppConstants.Image = Obj_ClassA;
In Page B you can access these.
userName = AppConstants.Username;
ObjClassB = AppConstants.Image;
This would avoid your I/O and read-write operations in StorageSettings. This is a basic Global variable approach.
Please mark this as an answer if it helps.

Related

Share class between endpoint and Objectify with different field subset

Say this is my classes
#Entity
public class Library{
...
}
#Entity
public class Book{
#Load
#Parent
#ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
private Ref<Library> libraryRef;
#Ignore
private Library library;
}
I want to send List<Book> to the "android" client: I don't want the android client to get libraryRef but I want the client to get library
Here is the data access method I have now
public static List< Book > getAllBooks(){
return OfyService.ofy().load().type(Book.class).list();
}
My endpoint will just return List<Book> to android. I believe I have accomplished the first part: make sure datastore does not store library but libraryRef. But how do I accomplish the second part: make sure the client gets library?
I am sure it is not yet loaded. How do I make sure it is loaded? Do I have to use my own for-loop for iteration?
My advice for anyone working with code shared between client and server is to make a clean separation between your API objects and your domain objects. It's a little more work up front to make DTOs but it makes your whole system more flexible - if you want to change your domain objects, you don't risk breaking a zillion mobile phone apps that are on a slow (or nonexistant) upgrade cycle.

Why are HTML emails being sent by a APEX Schedulable class being delivered with blank bodies?

I have an APEX class that is used to send an email out each day at 7PM:
global class ReportBroadcaster implements Schedulable {
global ReportBroadcaster() {
}
global void execute(SchedulableContext sc) {
send();
}
global void send() {
PageReference page = new PageReference('/apex/nameofvfpage');
page.setRedirect(true);
Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
email.setSubject('Example Subject');
email.setHtmlBody(page.getContent().toString());
email.setToAddresses(new String[]{'test#test.com'});
Messaging.sendEmail(new Messaging.SingleEmailMessage[]{email});
}
}
When I execute the send() method via an instance of the ReportBroadcaster via anonymous APEX, it is delivered as expected. However, when I schedule the class, the email is delivered with a blank body. If I switch the email body to plain text, it delivers fine (but that doesn't work for me).
How do I make this work?
UPDATE:
You cannot call getContent() on PageReference instances from either scheduled APEX or #future methods (I'm not sure why that would be, but it is what it is). I think that the solution will be to create a web service that I'll call from the #future method. Seems incredibly hacky, but I'm not sure what else I could do.
FINAL UPDATE:
This is how to send HTML emails from scheduled APEX:
Create a class that implements the Schedulable interface.
Have the execute() method call an #future method.
Have the #future method call a web service enabled method in the class that sends the email.
While this approach is roundabout, it works.
getContent() method is not supported in scheduled Apex. See the last line of this page:
http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_scheduler.htm
I do not know of the top of my head why this doesnt work (it should), but I can maybe suggest a workaround.
You can convert your vforce page into vforce Email Template (or create a new based on the old if you are also using the page somewhere else) and then use that template as the source for your email. Key points to check in the documentation are SingleEmailMessage.setTemplateId in apex docs and <messaging:*> components in vforce docs.
I also faced same problem and was able to find Workaround. I have documented my solution here and hope it will help others.
http://www.shivasoft.in/blog/salesforce/apex/send-email-with-generated-pdf-as-attachment-from-trigger/
Regards,
Jitendra Zaa

Tombstoning the last visited page the user was on

I want to tombstone the last page that the user was on and to retrieve it when the user comes back to the app. All of the tombstoning examples on the Internet deal with saving some data or the state of the page that the user has edited somehow (i.e inputed text in the textbox). In my app I don't have anything for the user to modify/edit so I just want to save the last visited page that the user was on. I tried to use some online examples that used PhoneApplicationService.Current.State but with no success.
Thank you to anyone who would like to help me out resolving this issue!
To locally store persistent data (data that should remain even when the user closes the app), you can use Isolated Storage.
So, in your app's Deactivated event, you can write the page's name to Isolated Storage like this:
//You get the Isolated Storage for your app (other apps can't access it)
IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication();
//if the file already exists, delete it (since we're going to write a new one)
if (isf.FileExists("lastpage.txt")) isf.DeleteFile("lastpage.txt");
using (var isoFileStream = new IsolatedStorageFileStream("lastpage.txt", FileMode.OpenOrCreate, isf))
{
//open a StreamWriter to write the file
using (var sw = new StreamWriter(isoFileStream))
{
//NavigationService.CurrentSource returns the current page
//we can write this to the file
sw.WriteLine((Application.Current.RootVisual as PhoneApplicationFrame).CurrentSource.ToString());
}
}
This will write the current page's name to the Isolated Storage. Then, in your OnNavigatedto method of your main page (the page that first opens normally) you can read the file name and navigate to it:
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication();
string lastpage = string.Empty;
if (isf.FileExists("lastpage.txt"))
{
using (var isoFileStream = new IsolatedStorageFileStream("lastpage.txt", FileMode.Open, isf))
{
//read the file using a StreamReader
using (var sr = new StreamReader(isoFileStream))
{
//get the uri we wrote and then convert it from a String to a Uri
lastpage = sr.ReadLine().Replace("file:///", "");
}
}
(Application.Current.RootVisual as PhoneApplicationFrame).Navigate(new Uri(lastpage, UriKind.Relative));
}
base.OnNavigatedTo(e);
}
This should read in the file you saved and then convert the string into an actual URI that you can pass to the NavigationService.
You can then delete the text file after it's been read so that it doesn't always keep jumping to that page.
In addition you can use this for getting the page name ,string PageName = (Application.Current.RootVisual as PhoneApplicationPage).Name; for getting the current page name
While I agree all the above options are possible, they are not really the correct way of doing something within a WP7.
It's better to construct a navigation page at the start of your app for properly controlling navigation, it also helps with managing back key events while using the app and prevents hiccups.
See Here for one example of implementing this:
Properly Exiting Silverlight-based WP7
With this done use the advice on storing values in isolated storage / application settings to then just store the "Current Page" state value (e.g. value of Page.GamePage) then the app navigation will direct you accordingly.
BUT beware when just storing the current page itself as you also need to save the correct state of any values or User entered data on that page when it tombstones as well, this the above advice should lead you in the right direction.
Hope this helps

Silverlight and RIA Services: Persisting login across sessions

I'm currently trying out Silverlight with RIA Services. I'm implementing a simple login form. I'm also using the provided Authentication Domain Service template which generates the following file:
[EnableClientAccess]
public class AuthenticationDomainService : AuthenticationBase<User>
{
// To enable Forms/Windows Authentication for the Web Application,
// edit the appropriate section of web.config file.
}
public class User : UserBase
{
// NOTE: Profile properties can be added here
// To enable profiles, edit the appropriate section of web.config file.
// public string MyProfileProperty { get; set; }
public int DefaultRows { get; set; }
}
Now I can login/logout without problem in my application. In the Silverlight app, after logging in, the line:
WebContext.Current.User.IsAuthenticated;
return true.
However, I need to persist this across sessions (i.e. when I reload the page using F5).
Currently, when the page reloads, I have to re-login.
Here is my Login code:
WebContext.Current.Authentication.Login(new LoginParameters(this.UserName, this.Password, true, string.Empty),
(LoginOperation loginOperation) =>
{
if (loginOperation.LoginSuccess)
{
NotificationMessage Message = new NotificationMessage(this, null, "CLOSE");
Messenger.Default.Send<NotificationMessage>(Message);
}
}, null);
The third parameter of the Login method is the IsPersistent parameter. From the MSDN Docs, I'd think that when setting it to true, the next time I load the page, the user would still be logged in. However, this is not the case.
Do I somehow need to read a cookie which has been set internally and then login in the background with the username/password provided by that cookie? Or is there some other magic at work here?
I hope somehow has already done this.
Thanks in advance
After going through the Silverlight Business Application template, I found this line of code:
WebContext.Current.Authentication.LoadUser(this.Application_UserLoaded, null);
A good place to call it is in the Application's Startup event inside App.xaml.cs. This will load the authenticated user from the server.
I thought I'd post this if anyone happens to stumble across the same problem.

Silveright - extending AuthenticationService to provide custom authentication

I am trying to add to the authentication system provided in the Silverlight 4 business template as my model does not completely fit that provided in the template. I have an existing web service that performs my authentication and provides roles and also permitted operations for each role. This is the model provided by AzMan/Authentication Manager.
However, rather than just get a single role, following authentication I provide the user with a list of available roles and allow the user to select one of these roles and then get a list of operations/actions for that selected role.
The problem that I have is that I can't work out how to add new methods to the authenticationservice to allow me to get the operations for the current user, and currently selected role in order to complete the login process e.g.
public SessionInfo GetOperations(string username, string selectedRole)
{
SessionInfo sessionInfo;
using (AzManServiceClient azClient = new AzManServiceClient("AnonymousAuthentication"))
{
sessionInfo = azClient.LoginUserByUsername("msldap://CN=LiveApps,CN=Program Data,DC=HLSUK,DC=local", "AIRS", selectedRole, null, username);
}
return sessionInfo;
}
The above method is not accessible from the LoginForm.xaml.cs using WebContextBase.Current.Authentication... Only methods such as Login are visible which is even more baffling because I can't see these methods in authenticationbase. I'm completely confused. How do I add new methods to the authentication service, or should I create a new domainservice, or should I access the azman service to get the operations directly from the silverlight client.
Have you tried to Override the methods in AuthenticationBase?
Then you can expand your authenticationservice with whatever logic you want.
<EnableClientAccess()>
Public Class AuthenticationRiaService
Inherits AuthenticationBase(Of UserAccount)
Protected Overrides Function ValidateUser(ByVal userName As String, ByVal password As String) As Boolean
End Function
End Class
Also set
WebContext.Current.Authentication To your authenticationservice as found in namespace System.ServiceModel.DomainServices.Client.ApplicationServices
Sorry for stupid VB code. :D

Resources