Owin Self Host Will Not Start - c#

using VS2015 with admin permissions my host starts and I can receive requests using Nancyfx.
IDisposable host = null;
IDisposable HostStart()
{
try
{
return WebApp.Start<Startup1>("http://*:7002");
}
catch (HttpListenerException ex)
{
throw new Exception(ex.Message);
}
}
When I make a setup project with the Visual Studio Extension and build and install and then run with admin privalages I don't get any exceptions but the server can not be found.I have turned off the firewall.I have now run out of ideas?
UPDATE: I am getting an exception
An exception has been thrown by the taget of invocation.
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Exception: Object reference not set to an instance of an object.
at CabbyTechOffice.Startup1.Configuration(IAppBuilder app)
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at Owin.Loader.DefaultLoader.<>c__DisplayClass12. <MakeDelegate>b__b(IAppBuilder builder)
at Owin.Loader.DefaultLoader.<>c__DisplayClass1. <LoadImplementation>b__0(IAppBuilder builder)
at Microsoft.Owin.Hosting.Engine.HostingEngine.ResolveApp(StartContext context)
at Microsoft.Owin.Hosting.Engine.HostingEngine.Start(StartContext context)
at Microsoft.Owin.Hosting.Starter.DirectHostingStarter.Start(StartOptions options)
at Microsoft.Owin.Hosting.Starter.HostingStarter.Start(StartOptions options)
at Microsoft.Owin.Hosting.WebApp.StartImplementation(IServiceProvider services, StartOptions options)
at Microsoft.Owin.Hosting.WebApp.Start(StartOptions options)
at Microsoft.Owin.Hosting.WebApp.Start[TStartup](StartOptions options)
at Microsoft.Owin.Hosting.WebApp.Start[TStartup](String url)
at CabbyTechOffice.MAIN.HostStart()
It seems the null ref is in the startup:
public class MyBoot : DefaultNancyBootstrapper
{
protected override void ConfigureApplicationContainer(TinyIoCContainer container)
{
CabbyTechOfficeConfig fig = ConfigUI.GetCabbyTechConfig();
if (fig == null)
{
throw new Exception("NO CONFIG");
}
ICabbytechOfficeDataAccess DB = null;
try
{
DB = ConnDBCreater.CreateDB(fig.DatabaseComputerName + "\\" + fig.DatabaseInstanceName, "taxidb", fig.DbPassword, 8);
IPEndPoint smsEP = null;
SmsCommsMob sms = null;
var comms = new ControlConnectAndSend(new IPEndPoint(IPAddress.Any, fig.DispatchFromPDAServerPort));
try
{
smsEP = new IPEndPoint(IPAddress.Parse(fig.SmsIp), fig.SmsPort);
sms = new SmsCommsMob(smsEP);
}
catch (Exception)
{
}
StateInjector stateInjector = new StateInjector(DB, comms, sms);
UdpBroadcasterJson.Send(new UDPCmd() { code = UDPCmd.commandsEnum.broadcastForDispatch }, stateInjector.UDPDispatchPort);
try
{
var comp = DB.CompaniesGet();
stateInjector.CompanyName = comp.company;
}
catch (Exception)
{
}
try
{
stateInjector.zones = DB.ZonesGet();
}
catch (Exception)
{
}
try
{
var locLog = new PdaLocLog();
var locLogger = new PdaLocLogger(DB, locLog);
stateInjector.locLogger = locLogger;
}
catch (Exception)
{
}
container.Register<IStateInjector, StateInjector>(stateInjector);
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
}
}

You have chains of try/catches with empty catch blocks.
try
{
var comp = DB.CompaniesGet();
stateInjector.CompanyName = comp.company;
}
catch (Exception)
{
}
try
{
stateInjector.zones = DB.ZonesGet();
}
catch (Exception)
{
}
try
{
var locLog = new PdaLocLog();
var locLogger = new PdaLocLogger(DB, locLog);
stateInjector.locLogger = locLogger;
}
catch (Exception)
{
}
this could leave stateInjector null which you then try to use.
You need to handle the catches in such a way that you can log any problems in those try/catches. Presumably there's a problem in the environment where it's failing, but you don't know that because of the empty catches.

There was problem in TinyIoc container in the NancyFx bootstrapper due to bad design in the exception handlers and a dependency was being injected null.

Related

How to handle Exception in Reflection(method.invoke) in C# with try catch

when exception is throwing from invoked method it's unable to catch and throw the exception.
`try
{
Type type = Type.GetType("abc");
Object obj = Activator.CreateInstance(type);
MethodInfo methodInfo = type.GetMethod("xyz");
object[] parameters = { new object[] { Json } };
response = (methodInfo.Invoke(obj, parameters));
}
catch
{
throw;
}
`
The problem is not in your code anyway. try to continue execution of code.
In the Debug/Exceptions menu, remove all checks. It should work.
try
{
Type type = Type.GetType("abc");
Object obj = Activator.CreateInstance(type);
MethodInfo methodInfo = type.GetMethod("xyz");
object[] parameters = { new object[] { Json } };
response = (methodInfo.Invoke(obj, parameters));
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
The exception thrown from a method call to Invoke() using reflection is a wrapping exception instance of System.Reflection.TargetInvocationException. The actual exception you're after will be in the InnerException. And don't forget to allow exceptions being thrown in visual studio using Debug-> Exception->
try
{
Type type = Type.GetType("abc");
Object obj = Activator.CreateInstance(type);
MethodInfo methodInfo = type.GetMethod("xyz");
object[] parameters = { new object[] { Json } };
response = (methodInfo.Invoke(obj, parameters));
}
catch (TargetInvocationException ex)
{
ex = ex.InnerException; // ex now stores the original exception
}
check the response.Exception?.InnerException
try
{
Type type = Type.GetType("abc");
Object obj = Activator.CreateInstance(type);
MethodInfo methodInfo = type.GetMethod("xyz");
object[] parameters = { new object[] { Json } };
response = (methodInfo.Invoke(obj, parameters));
if(response != null && response.Exception?.InnerException is Exception){
//this is an exception from reflection
throw response.Exception?.InnerException;
}
}
catch (Exception ex){
throw;
}

CommunicationObjectFaultedException - System.ServiceModel.Channels.ServiceChannel cannot be used for communication because it is in faulted state

Im working on an EConnect integration in C#. I working on a function that tests the GP connection string. Basically the string consists of the Dataserver name for GP and the database name. If the database name is wrong an eConnect exception is thrown and thats easy enough to catch and keep track of. When the server name is wrong the getentity function Im using to test the connection will just spin and time out. So Im using an IAsyncResult and a wait handle to test whether or not the application times out. If the application does time out I restart the service and allow the user to reenter the server name. Now the problem Im getting is after I test inputting the wrong server and everything is reset Im getting the System.ServiceModel.CommunicationObjectFaultedException.
Here is the info I am getting from the exception:
An exception of type 'System.ServiceModel.CommunicationObjectFaultedException' occurred in System.ServiceModel.dll but was not handled in user code
Additional information: The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.
System.ServiceModel.CommunicationObjectFaultedException was unhandled by user code
HResult=-2146233087
Message=The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.
Source=System.ServiceModel
StackTrace:
at System.ServiceModel.Channels.CommunicationObject.Close(TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelFactory.OnClose(TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelFactory.TypedServiceChannelFactory`1.OnClose(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Close(TimeSpan timeout)
at System.ServiceModel.ChannelFactory.OnClose(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Close(TimeSpan timeout)
at Microsoft.Dynamics.GP.eConnect.ServiceProxy.Dispose()
at Microsoft.Dynamics.GP.eConnect.eConnectMethods.Dispose()
at GP_Import___Sylectus.UpdateGPConnection.TestGPConnection() in C:\GP Import - Sylectus\GP Import - Sylectus\UpdateGPConnection.cs:line 265
at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Object[]& outArgs)
at System.Runtime.Remoting.Messaging.StackBuilderSink.AsyncProcessMessage(IMessage msg, IMessageSink replySink)
InnerException:
Here is my code:
namespace GP_Import___Sylectus
{
public partial class UpdateGPConnection : Form
{
Task task;
AsyncCallback cb;
public delegate string startProcessToCall();
startProcessToCall sp2c;
bool test = false;
string testResult = "";
public UpdateGPConnection()
{
InitializeComponent();
this.txtDatasourceName.Text = ConfigurationManager.AppSettings.Get("GPDataServer");
this.txtDatabaseName.Text = ConfigurationManager.AppSettings.Get("GPDatabase");
cb = new AsyncCallback(startProcessCallback);
sp2c = new startProcessToCall(TestGPConnection);
}
public void startProcessCallback(IAsyncResult iar)
{
startProcessToCall mc = (startProcessToCall)iar.AsyncState;
//bool result = mc.EndInvoke(iar);
//Console.WriteLine("Function value = {0}", result);
}
private void btnUpdate_Click(object sender, EventArgs e)
{
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.AppSettings.Settings["GPDataServer"].Value = txtDatasourceName.Text.ToUpper();
config.AppSettings.Settings["GPDatabase"].Value = txtDatabaseName.Text.ToUpper();
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
GPCongfigSettings.GPConnectionString = #"data source=" + txtDatasourceName.Text.ToUpper() + ";initial catalog=" + txtDatabaseName.Text.ToUpper() + ";integrated security=SSPI;persist security info=False;packet size=4096";
IAsyncResult asyncResult = null;
asyncResult = sp2c.BeginInvoke(cb, null);
Thread.Sleep(0);
Cursor.Current = Cursors.WaitCursor;
test = asyncResult.AsyncWaitHandle.WaitOne(15000);
if (test)
{
try
{
testResult = sp2c.EndInvoke(asyncResult);
}
catch (Exception exc)
{
Console.WriteLine(exc.Message);
}
}
bool result = asyncResult.IsCompleted;
string eConnectServiceName = ConfigurationManager.AppSettings.Get("eConnectServiceName");
string eConnectProcess = ConfigurationManager.AppSettings.Get("eConnectProcess");
Process[] process = Process.GetProcessesByName(eConnectProcess);
if (!test)
{
foreach (Process tempProcess in process)
{
tempProcess.Kill();
}
RestartService(eConnectServiceName, 20000);
RestartService(eConnectServiceName, 20000);
}
asyncResult.AsyncWaitHandle.Close();
Cursor.Current = Cursors.Default;
if (test == false)
{
MessageBox.Show("Dataserver Name is Incorrect", "Connection String Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
}
else
{
if (testResult == "Correct Connection")
{
MessageBox.Show("Connection String Successfully Updated", "", MessageBoxButtons.OK);
this.Close();
}
else if (testResult.Contains("eConnect Exception"))
{
MessageBox.Show("Database Name is Incorrect", "Connection String Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
}
else
{
MessageBox.Show(testResult, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
RestartService(eConnectServiceName, 20000);
}
}
}
public string TestGPConnection()
{
eConnectMethods requester = new eConnectMethods();
try
{
// Create an eConnect document type object
eConnectType myEConnectType = new eConnectType();
// Create a RQeConnectOutType schema object
RQeConnectOutType myReqType = new RQeConnectOutType();
// Create an eConnectOut XML node object
eConnectOut myeConnectOut = new eConnectOut();
// Populate the eConnectOut XML node elements
myeConnectOut.ACTION = 1;
myeConnectOut.DOCTYPE = "GL_Accounts";
myeConnectOut.OUTPUTTYPE = 2;
myeConnectOut.FORLIST = 1;
myeConnectOut.WhereClause = "(ACTNUMST = '99-9999-99-999')";
// Add the eConnectOut XML node object to the RQeConnectOutType schema object
myReqType.eConnectOut = myeConnectOut;
// Add the RQeConnectOutType schema object to the eConnect document object
RQeConnectOutType[] myReqOutType = { myReqType };
myEConnectType.RQeConnectOutType = myReqOutType;
// Serialize the eConnect document object to a memory stream
MemoryStream myMemStream = new MemoryStream();
XmlSerializer mySerializer = new XmlSerializer(myEConnectType.GetType());
mySerializer.Serialize(myMemStream, myEConnectType);
myMemStream.Position = 0;
// Load the serialized eConnect document object into an XML document object
XmlTextReader xmlreader = new XmlTextReader(myMemStream);
XmlDocument myXmlDocument = new XmlDocument();
myXmlDocument.Load(xmlreader);
var tokenSource = new CancellationTokenSource();
CancellationToken token = tokenSource.Token;
int timeOut = 20000; //20 seconds
try
{
string reqDoc = requester.GetEntity(GPCongfigSettings.GPConnectionString, myXmlDocument.OuterXml);
}
catch (CommunicationObjectFaultedException cofe)
{
return "Communication Exception - " + cofe.Message;
}
//connection string is correct
return "Correct Connection";
}
catch (FaultException fe)
{
return "Fault Exception - " + fe.Message;
}
catch (eConnectException exc)
{
Console.WriteLine(exc.Message);
return "eConnect Exception - " + exc.Message;
}
catch (CommunicationObjectFaultedException cofe)
{
return "Communication Exception - " + cofe.Message;
}
catch (Exception ex)
{
return "Exception - " + ex.Message;
}
finally
{
// Release the resources of the eConnectMethods object
requester.Dispose();
}
}
private void btnExit_Click(object sender, EventArgs e)
{
this.Close();
}
public static void RestartService(string serviceName, int timeoutMilliseconds)
{
ServiceController service = new ServiceController(serviceName);
try
{
int millisec1 = Environment.TickCount;
TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);
if (!service.Status.Equals(ServiceControllerStatus.Stopped))
{
service.Stop();
service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);
}
// count the rest of the timeout
int millisec2 = Environment.TickCount;
timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds - (millisec2 - millisec1));
if (service.Status.Equals(ServiceControllerStatus.Stopped) || service.Status.Equals(ServiceControllerStatus.StopPending))
{
service.Start();
service.WaitForStatus(ServiceControllerStatus.Running, timeout);
}
}
catch (Exception ex)
{
// ...
}
}
}
}
The error always seems to occur when I try to dispose the requester method in TestGPConnection.
Any ideas what I should do? Ive been googling this all day and Im getting pretty confused with what Im finding on how to fix this.
Try to change your code:
public string TestGPConnection()
{
try
{
using (eConnectMethods requester = new eConnectMethods())
{
// Create an eConnect document type object
eConnectType myEConnectType = new eConnectType();
// Create a RQeConnectOutType schema object
RQeConnectOutType myReqType = new RQeConnectOutType();
// Create an eConnectOut XML node object
eConnectOut myeConnectOut = new eConnectOut();
// Populate the eConnectOut XML node elements
myeConnectOut.ACTION = 1;
myeConnectOut.DOCTYPE = "GL_Accounts";
myeConnectOut.OUTPUTTYPE = 2;
myeConnectOut.FORLIST = 1;
myeConnectOut.WhereClause = "(ACTNUMST = '99-9999-99-999')";
// Add the eConnectOut XML node object to the RQeConnectOutType schema object
myReqType.eConnectOut = myeConnectOut;
// Add the RQeConnectOutType schema object to the eConnect document object
RQeConnectOutType[] myReqOutType = { myReqType };
myEConnectType.RQeConnectOutType = myReqOutType;
// Serialize the eConnect document object to a memory stream
MemoryStream myMemStream = new MemoryStream();
XmlSerializer mySerializer = new XmlSerializer(myEConnectType.GetType());
mySerializer.Serialize(myMemStream, myEConnectType);
myMemStream.Position = 0;
// Load the serialized eConnect document object into an XML document object
XmlTextReader xmlreader = new XmlTextReader(myMemStream);
XmlDocument myXmlDocument = new XmlDocument();
myXmlDocument.Load(xmlreader);
var tokenSource = new CancellationTokenSource();
CancellationToken token = tokenSource.Token;
int timeOut = 20000; //20 seconds
try
{
string reqDoc = requester.GetEntity(GPCongfigSettings.GPConnectionString, myXmlDocument.OuterXml);
}
catch (CommunicationObjectFaultedException cofe)
{
return "Communication Exception - " + cofe.Message;
}
//connection string is correct
return "Correct Connection";
}
}
catch (FaultException fe)
{
return "Fault Exception - " + fe.Message;
}
catch (eConnectException exc)
{
Console.WriteLine(exc.Message);
return "eConnect Exception - " + exc.Message;
}
catch (CommunicationObjectFaultedException cofe)
{
return "Communication Exception - " + cofe.Message;
}
catch (Exception ex)
{
return "Exception - " + ex.Message;
}
//finally
//{
// // Release the resources of the eConnectMethods object
// requester.Dispose();
//}
}

EF6 Retrying procedure throws "The SqlParameter is already contained by another SqlParameterCollection" for SqlQuery command

I'm trying to use the DBExecutionStrategy to retry queries that have timed out, but when the time out happens I get the error "The SqlParameter is already contained by another SqlParameterCollection". I'm using EF6.
My Query:
using (var ctx = new EntityModel())
{
IEnumerable<ItemResponse> items= ctx.Database.SqlQuery<ItemResponse>(
"spItemListGet #UserID", new SqlParameter("#UserID", UserID)
).ToList();
}
My Execution Strategy:
protected override bool ShouldRetryOn(Exception ex)
{
bool retry = false;
SqlException sqlException = ex as SqlException;
if (sqlException != null)
{
int[] errorsToRetry =
{
-2, //Timeout
};
if (sqlException.Errors.Cast<SqlError>().Any(x => errorsToRetry.Contains(x.Number)))
{
retry = true;
}
else
{
throw ex; //dont retry
}
}
return retry;
}
The stack trace:
System.ArgumentException: The SqlParameter is already contained by another SqlParameterCollection.
at System.Data.SqlClient.SqlParameterCollection.Validate(Int32 index, Object value)
at System.Data.SqlClient.SqlParameterCollection.AddRange(Array values)
at System.Data.Entity.Core.Objects.ObjectContext.CreateStoreCommand(String commandText, Object[] parameters)
at System.Data.Entity.Core.Objects.ObjectContext.ExecuteStoreQueryInternal[TElement](String commandText, String entitySetName, ExecutionOptions executionOptions, Object[] parameters)
at System.Data.Entity.Core.Objects.ObjectContext.<>c__DisplayClass65`1.<ExecuteStoreQueryReliably>b__64()
at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
at System.Data.Entity.Core.Objects.ObjectContext.<>c__DisplayClass65`1.<ExecuteStoreQueryReliably>b__63()
at System.Data.Entity.Infrastructure.DbExecutionStrategy.Execute[TResult](Func`1 operation)
at System.Data.Entity.Core.Objects.ObjectContext.ExecuteStoreQueryReliably[TElement](String commandText, String entitySetName, ExecutionOptions executionOptions, Object[] parameters)
at System.Data.Entity.Core.Objects.ObjectContext.ExecuteStoreQuery[TElement](String commandText, ExecutionOptions executionOptions, Object[] parameters)
at System.Data.Entity.Internal.InternalContext.<>c__DisplayClass14`1.<ExecuteSqlQuery>b__13()
at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
What could it be done to prevent this error? Can Database.SqlQuery be used for with the execution strategy?
The short answer: No, you can't do this (if your command has parameters).
The long answer:
Here is a minimal repro of the issue. I stripped out the execution strategy from the picture, and faked it with a loop instead. This logic is implemented in the ObjectContext, specifically in the ExecuteStoreQueryInternalAsync method. The problem seems to be that a command.Parameters.Clear() call is missing from the cleanup part.
static void Main(string[] args)
{
TestQuery();
}
private static void TestQuery()
{
using (var ctx = new ProductContext())
{
var parameter = new SqlParameter("#ID", 1);
var commandText = "select * from product where ProductId = #ID";
Action a = () =>
{
IDbCommand command = new SqlCommand();
command.CommandText = commandText;
command.Parameters.Add(parameter);
command.Connection = ctx.Database.Connection;
if (command.Connection.State != ConnectionState.Open)
{
command.Connection.Open();
}
var reader = command.ExecuteReader();
try
{
throw new Exception();
while (reader.Read())
{
var pId = reader["ProductID"];
}
reader.Close();
}
catch (Exception exc)
{
//for simplification, we just swallow this error, but in reality the connection error
//would reach the IDbExecutionStrategy, and would do a retry. Instead we fake the retry
//with a loop below
}
finally
{
reader.Dispose();
//command.Parameters.Clear(); <--------- THIS LINE IS MISSING FROM EF
command.Dispose();
}
};
for (int i = 0; i < 2; i++) // we fake the retry with a loop now
{
a();
}
}
}

Null values while updating DB in Parallel.Foreach

I use following script to get data from external service and store in dB. In certain rare cases less than 1% records gets updated with null values. In below code, the "re.status=fail" we see null. let us know if any thots.
public void ProcessEnquiries()
{
List<req> request = new List<req>();
var options = new ParallelOptions { MaxDegreeOfParallelism = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["MaxDegreeOfParallelism"]) };
try
{
Parallel.ForEach(request, options, currentRequest =>
{
ProcessedRequest processedRequest = null;
processedRequest = CommunicateToWS(currentRequest); // Here we call to webservice
});
}
catch (AggregateException exception)
{
foreach (Exception ex in exception.InnerExceptions)
{
// Handle Exception
}
}
}
public ProcessedRequest CommunicateToWS(req objReq)
{
ProcessedRequest re = new ProcessedRequest();
using (WebCall obj = new WebCall())
{
re.no = refnu;
try
{
retval = obj.getValue(inval);
objProxy.Close();
//get data
// parse and store to DB
}
catch (Exception e)
{
re.status = "fail";
//update DB that request has failed
//Handle Exception
obj.Close();
}
}
}

FacebookOAuthException was unhandled

I'm new in these things and I've been testing the api ...
and came to me a situation that is:
if the user changes the password of Facebook
the Access token is renewed ... and try to post the API Launches
an exception and the application crashes...
how to resolve this situation?
try {
FacebookApp app = new FacebookApp(FacebookToken);
var args = new Dictionary<string, object>();
args["message"] = "hi";
args["caption"] = "appcaption";
args["description"] = "appdescription";
args["name"] = "appname";
args["picture"] = "apppicture";
args["link"] = "applink";
app.ApiAsync((X) => { calback(X); }, null, "/me/feed", args, HttpMethod.Post);
}
catch (Exception ex) {
Uri url = new Uri("/MyFacebook.xaml", UriKind.Relative);
NavigationService.Navigate(url);
}
this is Api code, and it's crashing when throwing the OAuthExcepion at the line marked with "Exception HERE"
private static void ResponseCallback(IAsyncResult asyncResult, FacebookAsyncCallback callback, object state)
{
object result = null;
FacebookApiException exception = null;
try
{
var request = (HttpWebRequest)asyncResult.AsyncState;
var response = (HttpWebResponse)request.EndGetResponse(asyncResult);
using (Stream responseStream = response.GetResponseStream())
{
result = JsonSerializer.DeserializeObject(responseStream);
}
}
catch (FacebookApiException)
{
// Rest API Errors
throw;
}
catch (WebException ex)
{
// Graph API Errors or general web exceptions
exception = ExceptionFactory.GetGraphException(ex);
if (exception != null)
{
// Thow the FacebookApiException
throw exception;
}
throw; //Exception HERE
}
finally
{
// Check to make sure there hasn't been an exception.
// If there has, we want to pass null to the callback.
object data = null;
if (exception == null)
{
data = result;
}
#if SILVERLIGHT
callback(new FacebookAsyncResult(data, state, null, asyncResult.CompletedSynchronously, asyncResult.IsCompleted, exception));
#else
callback(new FacebookAsyncResult(data, state, asyncResult.AsyncWaitHandle, asyncResult.CompletedSynchronously, asyncResult.IsCompleted, exception));
#endif
}
}
thanks
The behavior of the SDK is intended. An exception is not "crashing" the application, but rather telling you when an error state has occurred. You are basically doing it correctly, but instead of catching Exception you should only catch FacebookOAuthException like this:
try {
FacebookApp app = new FacebookApp(FacebookToken);
var args = new Dictionary<string, object>();
args["message"] = "hi";
args["caption"] = "appcaption";
args["description"] = "appdescription";
args["name"] = "appname";
args["picture"] = "apppicture";
args["link"] = "applink";
app.ApiAsync("/me/feed", args, (X) => { calback(X); }, HttpMethod.Post);
}
catch (FacebookOAuthException) {
// This is where you would reauthorize the user or send them to a 'login' page
Uri url = new Uri("/MyFacebook.xaml", UriKind.Relative);
NavigationService.Navigate(url);
}
I would also suggest reading up on .Net exception handling to give you a better understanding of when and why they are used. http://msdn.microsoft.com/en-us/library/ms229005.aspx
Using the FacebookAuthenticationResult you can check if there was an error and then avoid to do the request:
private void FacebookLoginBrowser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
FacebookAuthenticationResult authResult;
if (FacebookAuthenticationResult.TryParse(e.Uri, out authResult))
{
if (authResult.ErrorReason == "user_denied")
{
// Do something knowing that this failed (cancel). }
else
{
fbApp.Session = authResult.ToSession();
loginSucceeded();
}
}
}
Have you seen this post? http://dotnetslackers.com/articles/net/wFace-windows-phone-7-facebook-integration-part-1.aspx
Specifically, take a look at part 3 - http://dotnetslackers.com/articles/net/wp7Gesicht-windows-phone-7-facebook-integration-part-3.aspx
Could you store the access token, and then on error, show the login page again?

Categories

Resources