Creating a new MobileServiceClient() freezes VS and Android app - xamarin.forms

Working on a Xamarin Forms app (Android & iOS)
When trying to create my connection to an easy table I have in an Azure Mobile App my Visual Studio Freezes for around 7 seconds and then when it comes back it has exited the code and the Android app, running in debug is permanently frozen.
When stepping through the code it steps over
client = new MobileServiceClient(appUrl);
and then when it hits the next line it freezes. But it doesn't matter what the next line is. I have put many different things after and it still freezes. Also, this is in a try/catch block, yet no exception is thrown.
I also wanted to see if the problem was server side. But both Post and Get with PostMan works fine. So I think my server is fine. Not completely sure though...
Here is some of the code:
public class ChatStorageAzureService : IChatStorageAzureService
{
public MobileServiceClient client { get; set; }
private IMobileServiceSyncTable<MessageViewModel> chatTable;
public static bool UseAuth { get; set; } = false;
private static ChatStorageAzureService instance;
public static ChatStorageAzureService Instance => instance ?? (instance = new ChatStorageAzureService());
public async Task InitializeAsync()
{
if (client?.SyncContext?.IsInitialized ?? false)
return;
var appUrl = "http://"MY-WEBSITE".azurewebsites.net/";
try
{
client = new MobileServiceClient(appUrl);
var path = "syncstore.db";
var store = new MobileServiceSQLiteStore(path);
store.DefineTable<MessageViewModel>();
await client.SyncContext.InitializeAsync(store);
chatTable = client.GetSyncTable<MessageViewModel>();
}
catch (Exception e)
{
Debug.WriteLine("Exception thrown in Initialize: " + e);
throw;
}
}
The InitializeAsync has been called in Async methods. It has been called with .Wait() method in a constructor. It has been called with button presses or in page creations. I have tried a ton of different ways to call. But it always freezes.
One thing that I think is weird is that my server code, is one project containing both the SignalR hub code and the Easy Table, yet you access them through different web addresses, For example
"http://"SignalR".azurewebsites.net/"
and
"http://"EasyTable".azurewebsites.net/"
Again PostMan is able to access both the tables and the SignalR and the SignalR works on the Android project. But I dont know if having to domains is bad. I am new... if you could not tell already, lol!
I followed this Tutorial for the Easy Table integration and when I did it in a separate project it worked fine. I am trying to integrate it into my actual project and that is where I am having all these problems.
I also turned on debugging with Azure and it doesnt seem like my app ever even reaches the service. No call is ever met. I think. But again I am new to debugging with Azure, so I might not know how to do it right. I followed this Tutorial for setting up Azure debugging
Thanks for any and all help!

Your path is incorrect. It needs to be a directory path, for example on iOS it is /<AppHome>/Library/<YourAppName>/syncstore.db.
We can leverage MobileServiceClient.DefaultDatabasePath to get the default database path in a cross-platform manner.
var path = Path.Combine(MobileServiceClient.DefaultDatabasePath, "syncstore.db");
Feel free to reference this Xamarin.Forms Sample App that uses Azure Mobile Service Client:
https://github.com/brminnick/UITestSampleApp/blob/master/Src/UITestSampleApp/Services/AzureService.cs

So I finally got it to work!!! "How?" you ask. I went on 2 week vacation, came back, started a again. Copied the new URL of the tut project into my actual project, did some testing. And then this is the big thing, I then put the same address I had been using back into my app, and... it just worked.... I did NOTHING to the code, and now it seems to work... So almost a month of work time lost and all I had to do was just put a different URL in, run it, and then put the original URL back in.... Lovely. I am guessing it cleared out some weird temp file that was messing up the program or something... even though I erased the temp files countless times... I don't get it, but onward I go!

Related

Production net6 Api rest returns html when it should return a json

I am having a problem after publishing an application to a server, IIS, net6, Angular. In development, the APIs return a JSON adjusted to the type of response that is included, but after publishing them, they return an HTML in their error varieties. This initially occurs in Authentication, which you do through Microsoft authentication to Azure.
[HttpGet, ActionName("")]
[Authorize(AuthenticationSchemes = Microsoft.AspNetCore.Authentication.AzureAD.UI.AzureADDefaults.BearerAuthenticationScheme)]
public ActionResult<Collection<MenuActive>> ActiveMenu()
{
try
{
var menu= _menuservice.GetActivemenu();
return Ok(menu);
}
catch (Exception ex)
{
//loggear exeptions
return StatusCode((int)HttpStatusCode.InternalServerError, new DetalleRespuesta() { Detalle = "Error Get Active menu", Resultado = EnumResultado.RESULTADO_FALLA });
}
}
The previous code in development, in case of bad authentication or an authentication error, returns a 401 captured by the catch, which is:
But when you publish it, it becomes the following HTML response:
I don't understand the variation of result. I suppose it has to do with the fact that when I authenticate you, I enter another page and there is the error due to bad authentication, and this is the error that returns, a page, and not a status code as expected. I appreciate any help.
maybe in Program.cs or similar cs files there is a special setting for
Development or Production mode where certain parameters are set different (e.g. allowing http/https only in development)
(like here: How to check whether the code is running in development or Production mode in Program.cs file in ASP.NET CORE 2.1?)

Invalid Token when using ASP.NET MVC 5 and Dependency Injection with Unity

I am building an ASP.NET MVC 5 website and am using Unity for dependency injection. I get an Invalid Token exception when some time has passed (more than an hour, less than a day) between the token generation and the token validation.
I have the following code in my Startup.cs:
internal static IDataProtectionProvider DataProtectionProvider { get; private set; }
public void Configuration(IAppBuilder app)
{
DataProtectionProvider = app.GetDataProtectionProvider();
ConfigureAuth(app);
}
I have the following code in the conctructor of my ApplicationUserManager class (timespan is set to 7 days now just to make sure that is not the issue):
var dataProtectionProvider = Startup.DataProtectionProvider;
if (dataProtectionProvider != null)
{
this.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser> (dataProtectionProvider.Create("ASP.NET Identity")) {
TokenLifespan = TimeSpan.FromDays(7)
};
}
In Startup.Auth.cs, I have the following line of code in the ConfigureAuth method:
app.CreatePerOwinContext(() => DependencyResolver.Current.GetService<ApplicationUserManager>());
In UnityConfig.cs, I have set up dependency injection:
container.RegisterType<ApplicationDbContext>();
container.RegisterType<ApplicationSignInManager>();
container.RegisterType<ApplicationUserManager>();
container.RegisterType<ApplicationRoleManager>();
container.RegisterType<IAuthenticationManager>(
new InjectionFactory(c => HttpContext.Current.GetOwinContext().Authentication)
);
container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(
new InjectionConstructor(typeof(ApplicationDbContext))
);
container.RegisterType<IRoleStore<IdentityRole, string>, RoleStore<IdentityRole>>(
new InjectionConstructor(typeof(ApplicationDbContext))
);
I have to add that one of my scenarios allows for the creation of a Contact with an associated user account. The Contact and associated user account are created in the ContactController, while the ConfirmEmail method is in the AccountController. Both take ApplicationUserManager as a constructor parameter, which means the ApplicationUserManager is injected into the controllers.
That does not appear to be the issue, since everything works fine if I confirm right after receiving the confirmation email. However, if I wait an hour or so, and then try to confirm, I get the Invalid Token exception.
I have already verified that I am not accidentally mixing different token types, both generation and verification are for email confirmation. I have also verified that I am url encoding (and decoding) the token.
I am currently testing on an Azure virtual machine with a static IP that is running its own IIS, the production environment will most likely be on a non-Azure VPS, als running its own IIS. I am not an Azure expert, but to my knowledge, I didn't select any options that are related to load balancing.
I would really appreciate your help, as I have already tried any possible solutions I was able to find here and on other websites.
The Invalid token issue has been solved. Since it only happened after some time had passed, I figured it might have something to do with my application recycling.
I managed to get rid of the problem by setting a fixed MachineKey in my web.config. You can use IIS Manager to generate it, as described here: https://blogs.msdn.microsoft.com/vijaysk/2009/05/13/iis-7-tip-10-you-can-generate-machine-keys-from-the-iis-manager/
Please note: for some reason, IIS adds the IsolateApps when it generates a machine key. However, this results in ASP.NET throwing an exception. After you manually remove the IsolateApps and save, it should work as expected.

ASP.NET MVC - Real time updates using Web Service

I'm trying to find examples on how to get real time updates using a web service in ASP.NET MVC (Version doesn't matter) and posting it back to a specific user's browser window.
A perfect example would be a type of chat system like that of facebooks' where responses are send to the appropriate browser(client) whenever a message has been posted instead of creating a javascript timer on the page that checks for new messages every 5 seconds. I've heard tons of times about types of sync programs out there, but i'm looking for this in code, not using a third party software.
What i'm looking to do specifically:
I'm trying to create a web browser chat client that is SQL and Web Service based in ASP.NET MVC. When you have 2-4 different usernames logged into the system they chat and send messages to each other that is saved in an SQL database, then when there has been a new entry (or someone sent a new message) the Web Service see's this change and then shows the receiving user the new updated message. E.G Full Chat Synced Chat using a Web Service.
The thing that really stomps me in general is I have no idea how to detect if something new is added to an SQL table, and also I have no idea how to send information from SQL to a specific user's web browser. So if there are people userA, userB, userC all on the website, i don't know how to only show a message to userC if they are all under the username "guest". I would love to know hot to do this feature not only for what i'm trying to create now, but for future projects as well.
Can anyone point me into the right direction please? I know SQL pretty well, and web services i'm intermediate with.
You can use SignalR for this task.
Via Scott Hanselman:
Create Asp.net mvc empty application
install nuget package of SignalR
Add new Controller (as example HomeController):
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
}
Create view Index with javascript references:
#Url.Content("~/Scripts/jquery-1.6.4.min.js")"
"#Url.Content("~/Scripts/jquery.signalR.js")"
and function:
$(function () {
var hub = $.connection.chatHub;
hub.AddMessage = function (msg) {
$('#messages').append('<li>' + msg + '</li>');
};
$.connection.hub.start().done(function() {
$('#send').click(function() {
hub.send($('#msg').val());
});
});
});
Create class ChatHub:
public class ChatHub:Hub
{
public void Send(string message)
{
Clients.AddMessage(message);
}
}

ASP.NET Routing - GetRouteData does not work if path exists

I have a HttpModule which intercepts all requests and loads data from the database based on routing rules. However, I run into one problem all the time; GetRouteData only works if the path does not exist:
var routeData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(HttpContext.Current));
Assuming a request comes in for the url http://localhost/contact, I get the correct routing data relating to that url if that path does not exist in the file system. The problem appears when I want to customize the page at that url which I do by creating an aspx page in the path ~/contact/default.aspx. Once I do that, GetRouteData return null.
I have even tried creating a new HttpContext object, but I still can not retrieve route data if the page exists.
Has anyone ever run into this problem? Is there a solution/workaround?
All help will be greatly appreciated.
Set RouteCollection.RouteExistingFiles to true.
public static void RegisterRoutes(RouteCollection routes)
{
// Cause paths to be routed even if they exists physically
routes.RouteExistingFiles = true;
// Map routes
routes.MapPageRoute("...", "...", "...");
}
Beware though. IIS7 behaves a little differently than the server used when debugging within Visual Studio. I got bit by this when I deployed my application to the web. Check out this feedback I submitted to Microsoft Connection.

The remote host closed the connection. The error code is 0x80070057

I'm getting a lot of these error messages in my logs on one of my servers and intermittently on two others.
Googling didn't reveal very much information, mostly related to file uploads or downloads being interrupted.
My pages are basically just text files with "ok" in them that only have .aspx extension for future plans, there's no actual code powering the pages. Servers are all Windows Server 2008 RC2 x64 running IIS7 / ASP.NET 4.
Statistically it's happening well under 1% of the time but because of the volume of traffic that still clutters my event log with 2 or 3 of these messages per minute.
Edit:
I tracked down the problem, setting buffering to true stopped it occurring.
I know this has been answered, but on the off chance this helps someone else, it happened in my MVC project sometimes when I had one dbContext set at the top of a repository. When I switched to a using statement for database connections, the error never appeared again.
So, I went from this at the top of each repository:
DbContext db = new DbContext();
To this for each individual connection:
using (DbContext db = new DbContext())
{
//db connection stuff here....
}
Worth saying that no one ever reported seeing the error and no error was ever shown to the browser, but nice to get it off the logs all the same!
Are you returning a Stream?
You might need to close it after the method finishes.
Check out this: Closing Returned Streams in WCF
Here is the code this blog suggests:
public Stream GetFile(string path)
{
Stream fileStream = null;
try
{
fileStream = File.OpenRead(path);
}
catch(Exception)
{
return null;
}
OperationContext clientContext = OperationContext.Current;
clientContext.OperationCompleted +=
new EventHandler(delegate(object sender, EventArgs args)
{
if (fileStream != null) fileStream.Dispose();
});
return fileStream;
}

Resources