I want to load a local HTML file that is in my Xamarin.Forms project. The file name is index.html. I searched and found a lot of people talking about this but none of the answers worked for me. This is where I am right now. You can see the HTML file on the side.
Visual Studio Image #3
And this is my code for now
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
initBrowser();
}
public void initBrowser()
{
var source = new HtmlWebViewSource();
string url = DependencyService.Get<IBaseUrl>().Get();
string TempUrl = Path.Combine(url, "index.html");
source.BaseUrl = url;
string html;
try
{
using (var sr = new StreamReader(TempUrl))
{
html = sr.ReadToEnd();
source.Html = html;
}
browser.Source = source.Html;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
EDIT: My problem is that I am not able to access my index.html in the android asset folder
10-28 15:13:23.111 I/mono-stdout(13979): Could not find a part of the
path "/file:/android_asset/AboutAssets.txt". Could not find a part of
the path "/file:/android_asset/index.html".
EDIT 2: I found a way to solve my problem by just not trying to use HtmlWebViewSource. I just use the URI directly in the browser.Source
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace PreuveXamarin
{
public interface IBaseUrl { string Get(); }
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
initBrowser();
}
public void initBrowser()
{
string path = DependencyService.Get<IBaseUrl>().Get();
string url = Path.Combine(path, "index.html");
browser.Source = url;
}
}
}
Related
Hi im so sorry for the generic question i am really new to C#. I am using a previous colleagues code but im looking to populate a textbox on a form with the data from a class.
This is the code for the thing i want to reference
public string GetToken(string username, string password) {
var request = SvcRequest
.Get(_url)
.WithAuthentication(this.CreateHeader(username, password))
.ReturningXml();
var response = _svc.Send(request);
return this.ExtractToken(response.Body);
I need to populate my text box with this.ExtractToken(response.Body). How do i do this?
Thanks a lot!
Code for main .cs file
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.XPath;
using System.Configuration;
using System.IO;
namespace EbsWebServices
{
internal sealed class EbsAuthManager
{
private readonly string _url;
private readonly SvcUtility _svc = new SvcUtility();
public EbsAuthManager()
{
_url = "URL_HERE";
if(!_url.EndsWith("/"))
{
_url += "/";
}
_url += "Rest/Authentication";
}
public string GetToken(string username, string password)
{
var request = SvcRequest
.Get(_url)
.WithAuthentication(this.CreateHeader(username, password))
.ReturningXml();
var response = _svc.Send(request);
return this.ExtractToken(response.Body);
}
private string CreateHeader(string username, string password)
{
var credentials = String.Format("{0}:{1}", username, password);
var encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes(credentials));
return String.Format("Basic {0}", encoded);
}
private string ExtractToken (string xml)
{
var doc = new XmlDocument();
doc.LoadXml(xml);
var navigator = doc.DocumentElement.CreateNavigator();
var success = navigator
.SelectChildren("Success", string.Empty)
.Cast<XPathNavigator>()
.First();
var token = navigator
.SelectChildren("Token", string.Empty)
.Cast<XPathNavigator>()
.First();
return Convert.ToBoolean(success.InnerXml)
? token.InnerXml
: null;
}
}
}
Code for my form
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using EbsWebServices;
namespace EBSGetTokenForm
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
}
}
}
My attempted implementation
using INWORK.Models;
using INWORK.Services;
using INWORK.Views;
using MvvmHelpers;
using Plugin.SimpleAudioPlayer;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Essentials;
using Xamarin.Forms;
namespace INWORK.ViewModels
{
public class AboutViewModel : ViewModelBase, INotifyPropertyChanged
{
public AboutViewModel()
{
//MessagingCenter.Subscribe<ViewModelBase>
Task.Run(async () => await Refresh());
Title = "About";
OpenWebCommand = new Command(async () => await Browser.OpenAsync("https://aka.ms/xamarin-quickstart"));
var player = Plugin.SimpleAudioPlayer.CrossSimpleAudioPlayer.Current;
player.Load(GetStreamFromFile("SmallBeep.wav"));
player.Play();
}
public ICommand GoInfoCommand { get; set; }
private Stream GetStreamFromFile(string filename)
{
var assembly = typeof(App).GetTypeInfo().Assembly;
var stream = assembly.GetManifestResourceStream("ĪNWORK." + filename);
return stream;
}
public async Task Refresh()
{
Device.StartTimer(TimeSpan.FromSeconds(0.5), () =>
{
if (StaticClass.refreshbool == true)
{
StaticClass.refreshbool = false;
Loadup();
StaticClass.passedbool = true;
}
return true;
});
}
public ICommand OpenWebCommand { get; }
}
}
Context for further text
I have attempted to add the file to the android solution(in drawable and assets) as AndroidResource and Embedded resource
as well as Embedded resource in the main Assets folder(i do not know if the assets folder needs to be declared somewhere), but all attempts so far have resulted in the same error
System.Reflection.TargetInvocationException: 'Exception has been thrown by the target of an invocation.'
If you only want it for Android you can place it in Assets folder of Android Project as AndroidAsset and not AndroidResource like you did. Then play it with:
Plugin.SimpleAudioPlayer.ISimpleAudioPlayer player = Plugin.SimpleAudioPlayer.CrossSimpleAudioPlayer.Current;
_ = player.Load("beep.wav");
player.Play();
I was being a bit of an idiot, but just in case anyone is having problems with this
Put in main folder as embeddedresource:
var stream = assembly.GetManifestResourceStream("INWORK.Assets." + filename);
Whole path needs to be defined with dots and then everything works great
I'm following a tutorial step by step to create a local database by using SQLite.net-PCL. However, when running the app, I tried to insert a data into the database, but it threw me a 'System.NullReferenceException'.
What I have done:
I'm only using SQLite.Net-TCL (1.2.1) package, and also added it into Android and iOS.
I noticed some tutorials saying that I should implement sqlite database on android and iOS, but I didn't find the tutorial is using this way, or maybe the IFileHelper interface has the same function?
I keep FileHelper interface in my Android folder
After debug, the database code passed. So the problem should happen when inserting data.
The exception happened at this line: if (person.ID != 0), and this line : await App.DB.SaveItemAsync(person);
Tutorial: https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/databases/
This is my database code:
using System.Threading.Tasks;
using System.Collections.Generic;
using System;
using SQLite;
namespace DatabaseDemo
{
public class Database
{
readonly SQLiteAsyncConnection _database;
public Database(string path)
{
_database = new SQLiteAsyncConnection(path);
_database.CreateTableAsync<Model>().Wait();
}
public Task<List<Model>> GetItemsAsync()
{
return _database.Table<Model>().ToListAsync();
}
public Task<int> SaveItemAsync(Model person)
{
if (person.ID != 0)
{
return _database.UpdateAsync(person);
}
else
{
return _database.InsertAsync(person);
}
}
}
}
This is my interface:
<StackLayout Margin="20" VerticalOptions="StartAndExpand">
<Label Text = "Name"/>
<Entry Text = "{Binding Name}" />
<Button Text = "Save" Clicked="OnSaveClicked" />
</StackLayout>
using Xamarin.Forms;
using System;
namespace DatabaseDemo
{
public partial class DatabaseDemoPage : ContentPage
{
public DatabaseDemoPage()
{
InitializeComponent();
}
async void OnSaveClicked(object sender, EventArgs e)
{
var person = (Model)BindingContext;
await App.DB.SaveItemAsync(person);
}
}
}
App.cs
using Xamarin.Forms;
namespace DatabaseDemo
{
public partial class App : Application
{
static Database database;
public static Database DB
{
get
{
if (database == null)
{
database = new Database(DependencyService.Get<IFileHelper>().GetLocalFilePath("db.db3"));
}
return database;
}
}
public App()
{
InitializeComponent();
MainPage = new DatabaseDemoPage();
}
}
}
I also created a public interface, and also created for Andriod and iOS.
using System;
namespace DatabaseDemo
{
public interface IFileHelper
{
string GetLocalFilePath(string filename);
}
}
You have to create Android side...
[assembly: Dependency(typeof(FileHelper))]
namespace Todo.Droid
{
public class FileHelper : IFileHelper
{
public string GetLocalFilePath(string filename)
{
string path = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
return Path.Combine(path, filename);
}
}
}
Here all info
Once the interface has been defined, use the DependencyService to obtain an implementation and get a local file path (note that this interface has not been implemented yet). The following code gets an implementation in the App.Database property:
static TodoItemDatabase database;
public static TodoItemDatabase Database
{
get
{
if (database == null)
{
database = new TodoItemDatabase(DependencyService.Get<IFileHelper>().GetLocalFilePath("TodoSQLite.db3"));
}
return database;
}
}
The TodoItemDatabase constructor is shown below:
public TodoItemDatabase(string dbPath)
{
database = new SQLiteAsyncConnection(dbPath);
database.CreateTableAsync<TodoItem>().Wait();
}
This approach creates a single database connection that is kept open while the application runs, therefore avoiding the expense of opening and closing the database file each time a database operation is performed.
Solved by the following code:
public DatabaseDemoPage()
{
InitializeComponent();
this.BindingContext = new Model();
}
I am using vs 2017rc and I have compatibility issues. I can't add windows form doll to my project and when I try to convert the code from win forms to Asp k get issues. Maybe I am doing it wrong but it seem to work on vs2015.
Please I need help to solve this. Maybe I am doing it wrong. See the code below.
using DotNetBrowser;
using DotNetBrowser.WinForms;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Windows.Forms;
namespace GetAjaxResponseBodySample
{
public partial class Form1 : Form
{
private static List<string> ajaxUrls = new List<string>();
private WinFormsBrowserView browserView;
public Form1()
{
InitializeComponent();
browserView = new WinFormsBrowserView();
browserView.Browser.Context.NetworkService.ResourceHandler = new AjaxResourceHandler();
browserView.Browser.Context.NetworkService.NetworkDelegate = new AjaxNetworkDelegate();
Controls.Add(browserView);
browserView.Browser.LoadURL("http://www.w3schools.com/xml/ajax_examples.asp");
}
private class AjaxResourceHandler : ResourceHandler
{
public bool CanLoadResource(ResourceParams parameters)
{
if (parameters.ResourceType == ResourceType.XHR)
{
Debug.WriteLine("Intercepted AJAX request: " + parameters.URL);
ajaxUrls.Add(parameters.URL);
}
return true;
}
}
private class AjaxNetworkDelegate : DefaultNetworkDelegate
{
public override void OnDataReceived(DataReceivedParams parameters)
{
if (ajaxUrls.Contains(parameters.Url))
{
Debug.WriteLine("Captured response for: " + parameters.Url);
Debug.WriteLine("MimeType = " + parameters.MimeType);
Debug.WriteLine("Charset = " + parameters.Charset);
PrintResponseData(parameters.Data);
}
}
private void PrintResponseData(byte[] data) {
Debug.WriteLine("Data = ");
var str = Encoding.Default.GetString(data);
Debug.WriteLine(str);
}
}
}
Am not concerned with the browser view... I already get the Jason I need from the Ajax response body.
It is possible to use Browser in a headless mode without creating BrowserView at all.
The following sample code works in the web application on VS2017rc with ASP.NET Core Web Application (.NET Framework) or ASP.NET Web Application (.NET Framework).
Please take into account that it is necessary to Dispose browser after the response body has been captured.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using DotNetBrowser;
using System.Diagnostics;
using System.Text;
namespace WebApplication7.Controllers
{
public class HomeController : Controller
{
private static List<string> ajaxUrls = new List<string>();
Browser browser;
public string Index()
{
Init();
return "Test page";
}
private void Init()
{
browser = BrowserFactory.Create();
browser.Context.NetworkService.ResourceHandler = new AjaxResourceHandler();
browser.Context.NetworkService.NetworkDelegate = new AjaxNetworkDelegate();
browser.LoadURL("https://www.w3schools.com/xml/ajax_examples.asp");
}
private class AjaxResourceHandler : ResourceHandler
{
public bool CanLoadResource(ResourceParams parameters)
{
if (parameters.ResourceType == ResourceType.XHR)
{
Debug.WriteLine("Intercepted AJAX request: " + parameters.URL);
ajaxUrls.Add(parameters.URL);
}
return true;
}
}
private class AjaxNetworkDelegate : DefaultNetworkDelegate
{
public override void OnDataReceived(DataReceivedParams parameters)
{
if (ajaxUrls.Contains(parameters.Url))
{
Debug.WriteLine("Captured response for: " + parameters.Url);
Debug.WriteLine("MimeType = " + parameters.MimeType);
Debug.WriteLine("Charset = " + parameters.Charset);
PrintResponseData(parameters.Data);
}
}
private void PrintResponseData(byte[] data)
{
Debug.WriteLine("Data = ");
var str = Encoding.UTF8.GetString(data);
Debug.WriteLine(str);
}
}
}
}
I can't figure out how to get rid of this error. I'm very new to C#, but please give any assistance you can. Thanks
Error: The type name 'LoginWindows' does not exist in the type 'ProjectServer.WebSvcLoginWindows'
Source Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Configuration;
using ProjectServer.LoginForms;
using ProjectServer.Statusing;
using ProjectServer;
using System.Net;
using System.Threading;
using PSLibrary = Microsoft.Office.Project.Server.Library;
using System.Windows.Forms.MessageBox;
using System.Windows.Forms;
namespace ProjectServer
{
public partial class LogonProjectServer : Form
{
public static WebSvcLoginWindows.LoginWindows loginWindows =
new WebSvcLoginWindows.LoginWindows();
public static CookieContainer cookies = new CookieContainer();
public static WebSvcProject.LoginForms loginForms =
new SyprisProjectServer.WebSvcProject.LoginForms();
private const string LOGINFORMSWEBSERVICE = "/PWA/_vti_bin/PSI/LoginForms.asmx?wsdl";
private const string LOGINWINDOWSWEBSERVICE = "/PWA/_vti_bin/PSI/LoginWindows.asmx?wsdl";
private string baseUrl; // Example: http://ServerName/ProjectServer/
public bool LogonPS(bool useWinLogon, string baseUrl,
string userName, string password)
{
const string LOGINWINDOWS = "PWA/_vti_bin/PSI/LoginWindows.asmx?wsdl";
const string LOGINFORMS = "PWA/_vti_bin/PSI/LoginForms.asmx?wsdl";
bool logonSucceeded = false;
try
{
if (useWinLogon)
{
loginWindows.Url = baseUrl + LOGINWINDOWS;
loginWindows.Credentials = CredentialCache.DefaultCredentials;
if (loginWindows.Login()) logonSucceeded = true;
}
}
// Catch statements
catch (System.Web.Services.Protocols.SoapException ex)
{
MessageBox.Show(ex.Message.ToString(), "Logon Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (System.Net.WebException ex)
{
MessageBox.Show(ex.Message.ToString(), "Logon Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
return logonSucceeded;
}
}
}
The problem is likely due to either the class name (LoginWindows) or the namespace (WebSvcLoginWindows) being incorrect when you create the loginWindows variable:
public static WebSvcLoginWindows.LoginWindows loginWindows = new WebSvcLoginWindows.LoginWindows();
Make sure the namespace and class name are spelled correctly and have the correct capitalisation.
If the class is contained in a separate asssembly, make sure your winforms project has a reference to the other assembly.
Hope that helps.
Check your build configuration and make sure all referenced projects are being built and being built for the correct configuration (64 vs 32 bit). Also, ensure you are using the correct version of any referenced dlls.