XElement.Nodes() and similar methods doesn't work - linq

I am new to Windows phone development and currently I am facing an issue. I am working on consuming a RESTful service for a windows phone application and I am getting a response successfuly in the format shown below
<StationsResp xmlns="http://www.wmata.com" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Stations>
<Station>
<Code>A03</Code>
<Lat>38.9095980575</Lat>
<LineCode1>RD</LineCode1>
<LineCode2 i:nil="true" />
<LineCode3 i:nil="true" />
<LineCode4 i:nil="true" />
<Lon>-77.0434143597</Lon>
<Name>Dupont Circle</Name>
<StationTogether1 />
<StationTogether2 />
</Station>
<Station>
<Code>A02</Code>
<Lat>38.9032019462</Lat>
<LineCode1>RD</LineCode1>
<LineCode2 i:nil="true" />
<LineCode3 i:nil="true" />
<LineCode4 i:nil="true" />
<Lon>-77.0397008272</Lon>
<Name>Farragut North</Name>
<StationTogether1 />
<StationTogether2 />
</Station>
</Stations>
</StationsResp>
My C# code goes below to call the service and store this response.
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
Uri uri = new Uri("http://api.wmata.com/Rail.svc/Stations?api_key=API_KEY_CODE_OMITTED_INTENTIONALLY");
WebClient webClient = new WebClient();
webClient.DownloadStringCompleted += OnDownloadStringCompleted;
webClient.DownloadStringAsync(uri);
}
void OnDownloadStringCompleted(object sender, DownloadStringCompletedEventArgs args)
{
XElement elm = XElement.Load(args.Result);
var SearchResults = elm.Elements("Station");
}
My Problem is with the last line. object 'elm' has the value as per the response posted above. However, when I try to query the object elm using any methods [like elm.Descendents(), elm.Elements()] it doesn't work. My System.Xml.Linq reference version for windows phone is 2.0.5.0. Am I missing something else?
Following is the exact error message I get.
On watch window I see the value in object elm. But LINQ query elm.Elements("Station") errors out. The error message is "System.Collections.IEnumerator.CurrentCould not evaluate expression".
Any help is greatly appreciated. Thanks in advance.

Related

Xamarin.Auth OAuth Google API for user authentication for Android

I have been trying to authenticate via Google OAuth 2.0. Following this link.
Have been able to open the Google Auth page and login successfully.
The problem is after logging in i am redirected to the google search page.
If i close the application then in the OnAuthCompleted method of the OAuth2Authenticator i get the e.IsAuthenticated to false and not able to get any information of the user.
Xamarin Share Library code:
var authenticator = new OAuth2Authenticator(
"somekey-somekey1.apps.googleusercontent.com",
null,
"email",
new Uri("https://accounts.google.com/o/oauth2/v2/auth"),
new Uri("com.companyname.somenameofapp:/oauth2redirect"),
new Uri("https://www.googleapis.com/oauth2/v4/"),
null,
true);
var presenter = new Xamarin.Auth.Presenters.OAuthLoginPresenter();
presenter.Login(authenticator);
authenticator.Completed += OnAuthCompleted;
AuthenticationState.Authenticator = authenticator;
AuthenticationState Class
public class AuthenticationState
{
public static OAuth2Authenticator Authenticator;
}
The OnAuthCompleted method
private async void OnAuthCompleted(object sender, AuthenticatorCompletedEventArgs e)
{
if (e.IsAuthenticated)
{
await Navigation.PushAsync(new GoogleLoginSuccess());
}
}
Main Activity Code
protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
global::Xamarin.Auth.Presenters.XamarinAndroid.AuthenticationConfiguration.Init(this, savedInstanceState);
LoadApplication(new App());
}
CustomUrlSchemeInterceptorActivity
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
namespace XamAppGoogleAuth.Droid
{
[Activity(Label = "CustomUrlSchemeInterceptorActivity")]
[IntentFilter(
new[] { Intent.ActionView },
Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable },
DataSchemes = new[] { "com.companyname.somenameofapp" },
DataPath = ":/oauth2redirect",
DataHost = "com.companyname.somenameofapp")]
public class CustomUrlSchemeInterceptorActivity : Activity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
global::Android.Net.Uri uri_android = Intent.Data;
Uri uri_netfx = new Uri(uri_android.ToString());
// load redirect_url Page
AuthenticationState.Authenticator.OnPageLoading(uri_netfx);
var intent = new Intent(this, typeof(MainActivity));
intent.SetFlags(ActivityFlags.ClearTop | ActivityFlags.SingleTop);
StartActivity(intent);
this.Finish();
return;
}
}
}
AndroidManifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.somenameofapp">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="27" />
<application android:label="somenameofapp.Android"></application>
<activity android:name="somenameofapp.Android.MainActivity" android:label="MainActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="com.companyname.somenameofapp" android:host="com.companyname.somenameofapp" />
</intent-filter>
</activity>
</manifest>
When i close the Custom Tab explicitly i am navigated back to the application with the below toast message.
What i would want is after the user authenticates with Google OAuth, they are redirected back to the application and I can get the access token and other information as needed. I have been to a lot of links regarding this but havent been able to find a solution. Kindly help
#kinder-cappy
I noticed you have the URL scheme interceptor activity in your application manifest as well as an activity class. You will have to choose one or else you will have multiple intent on trigger.
To remove the "customtabs login screen ...." message add this to your MainActivity (not interceptor class) after Xamarin.Auth initialization:
global::Xamarin.Auth.CustomTabsConfiguration.CustomTabsClosingMessage = null;
Also use Xamarin.Auth version 1.5.0.3 for now in android. It works.
If the current redirect URL scheme you specified does not works, try to get the correct redirect URL from your provider documentations. In my case, I used Google so I am using the inverted URL (client id).
If the current redirect URL scheme you specified does not work, try to get the correct redirect URL from your provider documentation. In my case, I used Google so I am using the inverted URL (client id).
In your CustomUrlSchemeInterceptorActivity DataSchemes and in Redirect URI you need to put inverted URL (ie. client ID) which you can get from the developer console.
client-id : "somekey-somekey1.apps.googleusercontent.com"
Redirect URI looks like : com.googleusercontent.apps.somekey-somekey1:/oauth2redirect
DataSchemes = new[] { "com.googleusercontent.apps.somekey-somekey1" } at your CustomUrlSchemeInterceptorActivity

Xamarin Android Facebook AppInviteDialog not showing

I'm using the Xamarin.FacebookSdk to display the App Invite Dialog. For iOS everything works great but for Android, nothing displays.
Update
It turns out iOS isn't always working. I actually get the following error sometimes:
[0:] Invite Failed Error Domain=com.facebook.sdk.core Code=9 "(null)"
I can step through the following code until it gets to the AppInv.Show. However, Show never shows anything. I tried having the Facebook app installed and without it installed.
public class FacebookService : IFacebookService
{
public void InviteFriends(string appLinkUrl, string previewImageUrl)
{
if (AppInviteDialog.CanShow())
{
var activity = Xamarin.Forms.Forms.Context as Activity;
var content = new AppInviteContent.Builder().SetApplinkUrl(appLinkUrl).SetPreviewImageUrl(previewImageUrl).Build() as AppInviteContent;
//AppInviteDialog.Show(activity, content);
AppInviteDialog AppInv = new AppInviteDialog(activity);
var callbackManager = CallbackManagerFactory.Create();
var invitecallback = new CCallback();
AppInv.RegisterCallback(callbackManager, invitecallback);
AppInv.Show(content);
}
}
}
public class CCallback : Java.Lang.Object, IFacebookCallback
{
public void OnCancel()
{
System.Diagnostics.Debug.WriteLine($"Invite was cancelled");
}
public void OnError(FacebookException error)
{
System.Diagnostics.Debug.WriteLine($"Invite failed {error.Message}");
}
public void OnSuccess(Java.Lang.Object result)
{
System.Diagnostics.Debug.WriteLine($"Invite was a success: {result}");
}
}
I added the following to the AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
........
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="#string/app_id" />
<activity android:name="com.facebook.FacebookActivity" android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation" android:theme="#android:style/Theme.Translucent.NoTitleBar" android:label="#string/app_name" />
<provider android:authorities="com.facebook.app.FacebookContentProviderXXXXXMy App IdXXXX" android:name="com.facebook.FacebookContentProvider" android:exported="true" />
It turns out that AppInviteDialog was deprecated by Facebook.
It sure would have been nice for a more informative error to be displayed.

Struts validations problems [duplicate]

I have following defined in
struts-config.xml:
<struts-config>
<form-beans>
<form-bean name="LoginForm" type="com.actionform.LoginForm"/>
</form-beans>
<action-mappings>
<!-- action for login -->
<action input="/views/login.jsp" name="LoginForm" path="/Login" scope="session" type="com.actions.LoginAction"
parameter="method" validate="true">
<forward name="success" path="/views/Frameset.html" />
</action>
</action-mappings>
<message-resources parameter="/WEB-INF/ApplicationResources"/>
<!-- ========================= Validator plugin ================================= -->
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property
property="pathnames"
value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>
</plug-in>
</struts-config>
The login form:
public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
ActionErrors errors = new ActionErrors();
if (userName == null || userName.length() < 1) {
System.out.println("in validate ---");
errors.add("userName", new ActionMessage("error.userName.required"));
// TODO: add 'error.name.required' key to your resources
}
if (password == null || password.length() < 1) {
errors.add("password", new ActionMessage("error.password.required"));
// TODO: add 'error.name.required' key to your resources
}
return errors;
}
login.jsp:
<html:form action="/Login?method=loginUser">
<html:errors/>
<html:text name="LoginForm" property="userName" />
<html:messages id="err_userName" property="userName">
<bean:write name="err_userName" />
</html:messages>
</html:form>
Property file:
error.userName.required = User Name is required.
error.password.required = Password is required.
Where am I doing wrong? I am getting the following error
javax.servlet.jsp.JspException: Cannot find bean error in any scope
I just want to display the error in the same JSP.
After you obtain the ActionMessages/ActionErrors object which contains the messages or errors you want to display in your input page (using <html:messages> tags or <html:errors> tags), you must call one of the following methods from your Action object to place the result of your validation in scope:
addMessages(HttpServletRequest request, ActionMessages messages)
or
addErrors(HttpServletRequest request, ActionMessages errors)
Are you doing that?
I'm really do not care how about struts handles an exception. Using old raw code from 1.2 generally when overriding a RequestProcesor, I should probably replace the two methods - process and processException. First thing is happy about catching exception from the request after processValidation has been made. The fragment of code could look like
Exception exception = null;
if (needValidation)
try {
if (! processValidate(request, response, form, mapping)) {
return;
}
exception = (Exception)request.getAttribute(Globals.EXCEPTION_KEY);
} catch (InvalidCancelException ex) {
exception = ex;
}
ActionForward forward;
// Check out if exception occurred
if (exception != null){
forward = processException(request, response, exception, form, mapping);
The second is pretty easy if you have configured the errors forward. The errors forward is usually one of the global forwards that easily found from the mapping. Once it found, it likes to display your error message on the page. I think those would probably enough for processing an exception
exception.printStackTrace();
log.error(exception);
request.setAttribute("error", exception.getMessage());
return mapping.findForward("error");
It has been done because validate method from ActionForm or ValidatorForm doesn't throw any exceptions and I couldn't properly override this method without throwing some. Once thrown, who will care about it?!

ASP.NET MVC properly handling invalid URLs

I'm trying to properly handle and return a 404 for this URL: http://localhost:2867/dd./xml (notice the dot before the slash)
In my current implementation I get 4 exceptions/errors in Application_Error. The first exception returned by Server.GetLastError() is System.Web.HttpException while the next three are null.
I made a bare minimum implementation to reproduce this issue. Here's the code in global.asax.cs:
protected void Application_Error(object sender, EventArgs e)
{
Exception exception = Server.GetLastError();
Server.ClearError();
var routeData = new RouteData();
routeData.Values.Add("controller", "Error");
routeData.Values.Add("action", "Generic");
routeData.Values.Add("area", "");
IController errorController = new ErrorController();
// this line throws System.Web.HttpException is a view is returned from ErrorController
errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
}
The error controller looks like this:
public class ErrorController : Controller
{
public ActionResult Generic()
{
Response.TrySkipIisCustomErrors = true;
Response.StatusCode = (int)HttpStatusCode.NotFound;
return View();
// returning content rather than a View doesn't fire 'System.Web.HttpException' in Application_Error
//return Content("Some error!");
}
}
There are two issues. One is that for the given URL instead of one error in Application_Error I get 3 or 4, and the other is that when returning a view from the ErrorController an exception is thrown on the Execute call line in Application_Start. If a Content("something") is returned instead this internal (to MVC I assume) exception is not triggered.
In order to see the problem you have to be in debug mode and use the development server. When using IIS or IIS Express the error is not caught for some reason. Also, every now and then these errors go away. To get it back to the beginning you have to clean the solution.
If you'd like to play with it here's the bare minimum solution: http://dl.dropbox.com/u/16605600/InvalidUrl.zip
Thank you for your help!
If you're using IIS7+ putting this in the web.config works:
<system.webServer>
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404" />
<error statusCode="404" responseMode="ExecuteURL" path="/Error/PageNotFound" />
</httpErrors>
</system.webServer>
(Answer from How can I properly handle 404 in ASP.NET MVC?)
Would still be nice to know what is going on in the Application_Error.
You can handle a 404 by changing the customeErrors section in the web.config
There is also a redirectMode attribute which you can use to control the nature of the error page redirection (and avoid the 302) (Read here)
<configuration>
...
<system.web>
<customErrors mode="RemoteOnly"
redirectMode="ResponseRewrite"
defaultRedirect="/ErrorPages/Oops.aspx">
<error statusCode="404" redirect="/ErrorPages/404.aspx" />
</customErrors>
...
http://www.asp.net/hosting/tutorials/displaying-a-custom-error-page-cs
In ASP.net MVC, there is a method you can override to catch all exceptions thrown in a controller. Just override Controller.OnException(...) and you can do custom error handling in there as well. If all of your controllers inherit from a common base controller class, you can put the error handling there.
http://msdn.microsoft.com/en-us/library/system.web.mvc.controller.onexception.aspx

HttpWebRequest returning "The remote server returned an error: NotFound" on Windows Phone 7

I am trying to authenticate against the Huddle API using the Windows Phone 7 Emulator. However, I am not getting any success. I keep getting "The remote server returned an error: NotFound". I have even tried "dumbing down" my code and just trying a straight web site, eg. Google but still get the same result.
I have the following code:
string url = "http://www.google.com";
HttpWebRequest client= WebRequest.CreateHttp(new Uri(url)) as HttpWebRequest;
client.AllowReadStreamBuffering = true;
// Call and handle the response.
client.BeginGetResponse(
(asResult) =>
{
Dispatcher.BeginInvoke(
() =>
{
try
{
var response = client.EndGetResponse(asResult);
System.IO.StreamReader reader = new System.IO.StreamReader(response.GetResponseStream());
string responseString = reader.ReadToEnd();
}
catch (WebException failure)
{
throw failure;
}
});
},
null
);
Execution always ends up in the catch section. However, having watched Fiddler2, there seems not to be any traffic at all to google.com. So the request doesn't seem to be being made.
I've seen a similar problem here Retrieve XML from https using WebClient/HttpWebRequest - WP7, but I am using a standard port so not sure this is relevant. I have also tried simplifying the code as per the post, but no success.
Interestingly, the most likely option seems to be because I may not have Network Capabilities defined in my AppManifestWM.xaml file as per HttpWebRequest Breaks On WP7, but my AppManifestWM.xaml file appears to have this defined:
<Deployment xmlns="http://schemas.microsoft.com/windowsphone/2009/deployment" AppPlatformVersion="7.0">
<App xmlns="" ProductID="{ac5b5d62-573c-4134-b290-0ad4f678ad7f}" Title="xxx.WindowsPhone7.Client" RuntimeType="Silverlight" Version="1.0.0.0" Genre="apps.normal" Author="xxx.WindowsPhone7.Client author" Description="Sample description" Publisher="xxx.WindowsPhone7.Client publisher">
<IconPath IsRelative="true" IsResource="false">ApplicationIcon.png</IconPath>
<Capabilities>
<Capability Name="ID_CAP_NETWORKING" />
<Capability Name="ID_CAP_LOCATION" />
<Capability Name="ID_CAP_SENSORS" />
<Capability Name="ID_CAP_MICROPHONE" />
<Capability Name="ID_CAP_MEDIALIB" />
<Capability Name="ID_CAP_GAMERSERVICES" />
<Capability Name="ID_CAP_PHONEDIALER" />
<Capability Name="ID_CAP_PUSH_NOTIFICATION" />
<Capability Name="ID_CAP_WEBBROWSERCOMPONENT" />
</Capabilities>
<Tasks>
<DefaultTask Name ="_default" NavigationPage="MainPage.xaml"/>
</Tasks>
<Tokens>
<PrimaryToken TokenID="xxx.WindowsPhone7.ClientToken" TaskName="_default">
<TemplateType5>
<BackgroundImageURI IsRelative="true" IsResource="false">Background.png</BackgroundImageURI>
<Count>0</Count>
<Title>xxx.WindowsPhone7.Client</Title>
</TemplateType5>
</PrimaryToken>
</Tokens>
</App>
</Deployment>
So I'm at a loss. The request doesn't actually seem to be occurring, leading me to think something is preventing it.
Update:
Nothing changed, but thought this stack trace might heko:
System.Net.WebException was unhandled
Message=The remote server returned an
error: NotFound. StackTrace:
at System.Net.Browser.ClientHttpWebRequest.InternalEndGetResponse(IAsyncResult
asyncResult)
at System.Net.Browser.ClientHttpWebRequest.EndGetResponse(IAsyncResult
asyncResult)
at xxx.WindowsPhone7.Client.Views.AddHuddleUserPage.<>c__DisplayClass2.<>c__DisplayClass4.b__1()
at System.Reflection.RuntimeMethodInfo.InternalInvoke(RuntimeMethodInfo
rtmi, Object obj, BindingFlags
invokeAttr, Binder binder, Object
parameters, CultureInfo culture,
Boolean isBinderDefault, Assembly
caller, Boolean verifyAccess,
StackCrawlMark& stackMark)
at System.Reflection.RuntimeMethodInfo.InternalInvoke(Object
obj, BindingFlags invokeAttr, Binder
binder, Object[] parameters,
CultureInfo culture, StackCrawlMark&
stackMark)
at System.Reflection.MethodBase.Invoke(Object
obj, Object[] parameters)
at System.Delegate.DynamicInvokeOne(Object[]
args)
at System.MulticastDelegate.DynamicInvokeImpl(Object[]
args)
at System.Delegate.DynamicInvoke(Object[]
args)
at System.Windows.Threading.DispatcherOperation.Invoke()
at System.Windows.Threading.Dispatcher.Dispatch(DispatcherPriority
priority)
at System.Windows.Threading.Dispatcher.OnInvoke(Object
context)
at System.Windows.Hosting.CallbackCookie.Invoke(Object[]
args)
at System.Windows.Hosting.DelegateWrapper.InternalInvoke(Object[]
args)
at System.Windows.RuntimeHost.ManagedHost.InvokeDelegate(IntPtr
pHandle, Int32 nParamCount,
ScriptParam[] pParams, ScriptParam&
pResult)
The status is System.Net.WebExceptionStatus.UnknownError
Thanks for your time.
Never used Fiddler2 but had exact the same problem when developing a Windows Phone app.
For me the cause was quite different:
The WMAppManifest.xml was just missing ID_CAP_NETWORKING!
Since I got the "not found" exception and not a "not supported exception" I tried almost everything else until I found the real cause of the problem ... ;-)
I prefer disabling all CAPS and only enable the ones the app really needs since users will not understand/accept if an app needs access to "everything" ;-)
I worked several hours with the exact same symptoms as the original poster. Then I closed Fiddler2 as suggested above. And then it works. No more "The remote server returned and error: NotFound."
Magic! Thank you, kellyb. Should have upvoted but I do not have enough credit.
Do you have Fiddler running? I get this error repeatedly when Fiddler is attached to my networking stack. With Fiddler off, no issues.
I would be interested in hearing the why's behind that if someone knows...
Cheers
Shutting down Fiddler2 solved my issue.
Ok, I've solved it ... but don't know how. My machine has not been rebooted, my code has not changed. The only possible explanation is my emulator did crash a few times. Maybe something in there.
Thanks for your time, this is the code I'm using, which works well with the Huddle API:
string url = "https://api.huddle.net/v1/xml/workspaces"; ;
HttpWebRequest client= WebRequest.CreateHttp(new Uri(url)) as HttpWebRequest;
client.Credentials = new NetworkCredential(ViewModel.UserAccount.UserName, ViewModel.UserAccount.Password);
client.AllowReadStreamBuffering = true;
// Call and handle the response.
client.BeginGetResponse(
(asResult) =>
{
Dispatcher.BeginInvoke(
() =>
{
try
{
var response = client.EndGetResponse(asResult);
System.IO.StreamReader reader = new System.IO.StreamReader(response.GetResponseStream());
string responseString = reader.ReadToEnd();
}
catch (WebException failure)
{
MessageBox.Show(failure.Message, "Cannot authenticate", MessageBoxButton.OK);
#if DEBUG
throw failure;
#endif
}
});
},
null
);
This may just be a matter of resolving your network connectivity.
Can you access the web via IE and a WebBrowser control inside an app?
You may have a proxy in the way. See if this doco helps in that regard.
Proxy Support for Windows Phone Emulator

Resources