I am developing an application, which requires chrome browser history. I have written a C# code for fetching the history. However there are two issues in my code which I am unable to figure out.
There is this warning.
Warning 1 There was a mismatch between the processor architecture of the project being built "MSIL" and the processor architecture of the reference "System.Data.SQLite", "AMD64". This mismatch may cause runtime failures. Please consider changing the targeted processor architecture of your project through the Configuration Manager so as to align the processor architectures between your project and references, or take a dependency on references with a processor architecture that matches the targeted processor architecture of your project. ChromeData
There is this error
SQLite error (5): database is locked
I tried closing the browser, but still there is this error. However, when I created a copy of History file and renamed it, gave its path instead of History, the program was working and it could read the file and fetch the data.
I am unable to figure it out where the error is. So, please help. I am posting my 3 class files.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Data.SQLite;
using System.Data;
namespace ChromeData
{
class GoogleChrome
{
public List<URL> Urls = new List<URL>();
public IEnumerable<URL> GetHistory()
{
string DocumentsFolder = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
//Console.WriteLine(DocumentsFolder);
string[] tempstr = DocumentsFolder.Split('\\');
foreach(string s in tempstr)
{
Console.WriteLine(s);
}
string tempstr1 = "";
DocumentsFolder += "\\Google\\Chrome\\User Data\\Default";
if(tempstr[tempstr.Length-1] != "Local")
{
for(int i =0; i<tempstr.Length-1;i++)
{
tempstr1 += tempstr[i] + "\\";
}
DocumentsFolder = tempstr1 + "Local\\Google\\Chrome\\User Data\\Default";
}
Console.WriteLine(DocumentsFolder);
if(Directory.Exists(DocumentsFolder))
{
return ExtractUserHistory(DocumentsFolder);
}
return null;
}
public IEnumerable<URL> ExtractUserHistory(string folder)
{
DataTable HistoryData = ExtractFromTable("urls", folder);
foreach(DataRow row in HistoryData.Rows)
{
string url = row["url"].ToString();
string title = row["title"].ToString();
URL u = new URL(url.Replace('\'',' '), title.Replace('\'',' '), "Google Chrome");
Urls.Add(u);
}
return Urls;
}
DataTable ExtractFromTable(string table, string folder)
{
SQLiteConnection sql_con;
SQLiteDataAdapter DB;
SQLiteCommand sql_cmd;
string dbpath = folder + "\\History";
DataTable DT = new DataTable();
if(File.Exists(dbpath))
{
try
{
sql_con = new SQLiteConnection("Data Source=" + dbpath + ";Version=3;New=False;Compress=True;");
sql_con.Open();
sql_cmd = sql_con.CreateCommand();
string CommandText = "select * from " + table;
DB = new SQLiteDataAdapter(CommandText, sql_con);
DB.Fill(DT);
sql_con.Close();
}
catch(Exception e)
{
TextWriter errorWriter = Console.Error;
errorWriter.WriteLine(e.Message);
}
}
return DT;
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ChromeData
{
class TestClass
{
public static List<URL> Urls = new List<URL>();
public static void Main()
{
string path = #"C:\Users\Public\Desktop\history.txt";
GoogleChrome g = new GoogleChrome();
Urls = (List<URL>)g.GetHistory();
using(StreamWriter sw = File.CreateText(path))
{
foreach(URL u in Urls)
{
sw.WriteLine(u.url);
}
}
Console.ReadLine();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ChromeData
{
class URL
{
public string url;
public string title;
public string browser;
public URL(string url,string title,string browser)
{
this.browser = browser;
this.title = title;
this.url = url;
}
}
One solution is to copy the file to a temporary location and read it from there.
string source = #"C:\Users\{USERNAME}\AppData\Local\Google\Chrome\User Data\Default\History";
string target = #"C:\Temp\History";
if (File.Exists(target))
{
File.Delete(target);
}
File.Copy(source, target);
string cs = #"Data Source=" + target;
string sql = "Select * From urls";
using (SQLiteConnection c = new SQLiteConnection(cs))
{
c.Open();
using (SQLiteCommand cmd = new SQLiteCommand(sql, c))
{
using (SQLiteDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
Console.WriteLine(rdr[1].ToString());
}
}
}
}
I've found chrome.exe will continue running, and holding the lock, despite exiting the browser as normal.
taskkill.exe /IM chrome.exe /F
This will shut down Chrome, with an added bonus of having a 'restore tabs' button upon restart by the user. Restore tabs is available because you killed forcefully.
Related
We had CefSharp calling a project deployed on IIS. That worked. And a cookie I need for the third party library is loaded successfully.
Now we want CefSharp to load the same html and third party library through disk, bypassing IIS. Files are loading and running complete with functioning javascript, however the third party library requires a "domain name" to match the one associated with the license.
I need my domain name to match the one on my license which was generated with domain=localhost. But once I specify a domain name, the page, including the license checker, doesn't load.
This is a related problem. A cookie I need to load loads succesfully when I use csharp to call the IIS project, but fails when I open up the html project from disk. For reference, static void FrameLoaded is the same cookie loading procedure used in both versions of my project.
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MinRepExample2
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
Form1.cs
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 CefSharp;
using CefSharp.WinForms;
namespace MinRepExample2
{
public partial class Form1 : Form
{
private ChromiumWebBrowser browser;
public Form1()
{
InitializeComponent();
try
{
string siteURL = "";
string FileBase = #"c:\users\romero.ryan\documents\visual studio 2015\Projects\MinRepExample2";
string CacheDir = FileBase+#"\Cef2";
// CefSettings to temporarily reduce security
CefSettings MySettings = new CefSettings();
MySettings.CachePath = CacheDir;
MySettings.CefCommandLineArgs.Add("enable-media-stream", "enable-media-stream");
MySettings.CefCommandLineArgs.Add("allow-file-access-from-files", "allow-file-access-from-files");
MySettings.CefCommandLineArgs.Add("disable-web-security", "disable-web-security");
MySettings.JavascriptFlags = "--expose-wasm";
// Browser Settings
BrowserSettings browserSettings = new BrowserSettings();
browserSettings.FileAccessFromFileUrls = CefState.Enabled;
browserSettings.LocalStorage = CefState.Enabled;
browserSettings.UniversalAccessFromFileUrls = CefState.Enabled;
browserSettings.WebSecurity = CefState.Disabled;
// Custom Scheme Registration
MySettings.RegisterScheme(new CefCustomScheme
{
SchemeName = MySchemeHandlerFactory.SchemeName,
SchemeHandlerFactory = new MySchemeHandlerFactory(),
IsFetchEnabled = true,
IsLocal = false,
IsCorsEnabled = true,
IsSecure = true,
//DomainName= #"\Users\romero.ryan"
DomainName = "localhost"
});
CefSharpSettings.LegacyJavascriptBindingEnabled = true;
if (!Cef.IsInitialized)
{
Cef.Initialize(MySettings);
}
//string fName = #"C:\Users\romero.ryan\Documents\Visual Studio 2015\Projects\WinHostScandit1\WebHostOnDisk\CefPrimeFiles";
//c:\users\romero.ryan\documents\visual studio 2015\Projects\MinRepExample2\TestSite.html
browser = new ChromiumWebBrowser(#"fileProtocol:\\" + FileBase + "\\TestSite.html");
browser.BrowserSettings = browserSettings;
browser.Dock = DockStyle.Fill;
browser.Name = "browser";
browser.LoadingStateChanged += FrameLoaded;
this.Controls.Add(browser);
}
catch (Exception ex)
{
throw ex;
}
}
public void FrameLoaded(object sender, LoadingStateChangedEventArgs e)
{
//ChromiumWebBrowser ans = (ChromiumWebBrowser)Controls.Find("browser", false).First();
if (!e.IsLoading)
{
// CefSharp specific Cookie manipulation to register app as single device used with Scandit Library.
// ADD Cookie in C# code. Also adding in javascript code
var cookman = browser.GetCookieManager();
string[] schemes = { "fileProtocol", "fileprotocol", "fileprotocol:", "fileProtocol:" };
cookman.SetSupportedSchemes(schemes, true);
CefSharp.Cookie cook1 = new CefSharp.Cookie();
cook1.Domain = "localhost";
cook1.Name = "scandit-device-id";
cook1.Value = "ffaf4f340998d137fc260d563004eabcd388e90f";
cook1.Path = "/scanditpage";
cook1.Expires = new DateTime(2029, 6, 17);
// cookman.SetCookieAsync(ConfigurationManager.AppSettings["ScanditURL"], cook1);
var respcook = cookman.SetCookieAsync("http://localhost/scanditpage/ScanditTest.html", cook1);
bool cookieSet = cookman.SetCookie("http://localhost/scanditpage/ScanditTest.html", cook1);
CefSharpSettings.LegacyJavascriptBindingEnabled = true;
//cookman.SetCookie
// Adding Test cookie
browser.ExecuteScriptAsync("TestAddCookie()");
// Launches Dev tools for Debugging Purposes.
browser.ShowDevTools();
}
}
}
}
MySchemeHandler.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CefSharp;
using System.IO;
namespace MinRepExample2
{
public class MySchemeHandler : ResourceHandler
{
public const string SchemeName = "fileProtocol";
private string folderPath;
public MySchemeHandler()
{
folderPath = "";
}
public override CefSharp.CefReturnValue ProcessRequestAsync(IRequest request, ICallback callback)
{
var uri = new Uri(request.Url);
string fileName = uri.LocalPath;
var requestedFilePath = "C:/" + fileName;
string bFileName = "";
bFileName = requestedFilePath;
if (File.Exists(bFileName))
{
byte[] bytes = File.ReadAllBytes(bFileName);
Stream = new MemoryStream(bytes);
var fileExtension = Path.GetExtension(bFileName);
MimeType = GetMimeType(fileExtension);
return CefReturnValue.Continue;
//return true;
}
else
{
throw new FileNotFoundException();
}
callback.Dispose();
return CefReturnValue.Continue;
}
}
}
MySchemeHandlerFactory:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CefSharp;
namespace MinRepExample2
{
public class MySchemeHandlerFactory: ISchemeHandlerFactory
{
public const string SchemeName = "fileProtocol";
public IResourceHandler Create(IBrowser browser, IFrame frame, string schemeName, IRequest request)
{
return new MySchemeHandler();
}
}
}
Testing HTML:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>Test Site for CefSharp Cookies</title>
<script type="text/javascript">
function AddCookie(name, value) {
// Add cookie as name value pair.
var newcookie = name + "=" + value + ";";
document.cookie=newcookie
}
function TestAddCookie() {
// Add specific cookie. Called from executescript in FrameLoaded method
AddCookie("name", "everlast");
}
function ButtonCookie() {
//Adds cookie by button click, then displays all available cookies.
AddCookie("button", "clicked");
var decodedCookie = decodeURIComponent(document.cookie);
alert(decodedCookie);
}
</script>
</head>
<body>
<div>Hello, World!</div>
<button onclick="ButtonCookie();">Add Cookie</button>
</body>
</html>
I figured it out from advice from amaitland and this answer: Simple Custom Scheme.
CefSettings allows you to set permissions like allowing CORS and Fetch for loading WASM files. CefSettings is also used for registering custom scheme handlers. Some schemes might need special permissions to load dependent javascript libraries. Permissions associated with this variable must be set before calling Cef.Initialize. Cef.Initialize should not be called after new ChromiumWebBrowser();
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 CefSharp;
using CefSharp.WinForms;
using CefSharp.SchemeHandler;
namespace EpmsMobileWF.ScanditWebForm
{
public partial class ScanditPopupForm : Form
{
public static ScanditPopupConfig scanditConfigs;
public static JSObj1 mess;
public ChromiumWebBrowser browser;
public ScanditPopupForm(TextBox inForm)
{
InitializeComponent();
InitScanner();
mess = new JSObj1(inForm, this);
}
public void InitScanner()
{
scanditConfigs = new ScanditPopupConfig();
var settings = new CefSettings();
FolderSchemeHandlerFactory newFac = new FolderSchemeHandlerFactory(scanditConfigs.HTMLRootFolder,null, scanditConfigs.DomainName, "ScanditTest.html");
CefCustomScheme ScanditScheme = new CefCustomScheme
{
SchemeName = "http",
DomainName = scanditConfigs.DomainName,
SchemeHandlerFactory = newFac,
};
ScanditScheme.IsCorsEnabled = true;
ScanditScheme.IsFetchEnabled = true;
ScanditScheme.IsLocal = true;
ScanditScheme.IsStandard = true;
settings.CachePath = scanditConfigs.ScanditCacheDirectory;
settings.CefCommandLineArgs.Add("enable-media-stream", "enable-media-stream");
settings.CefCommandLineArgs.Add("allow-file-access-from-files", "allow-file-access-from-files");
settings.PersistSessionCookies = true;
settings.JavascriptFlags = "--expose-wasm";
settings.RegisterScheme(ScanditScheme);
Cef.Initialize(settings);
browser = new ChromiumWebBrowser(scanditConfigs.ScanditURL);
this.Controls.Add(browser);
browser.Dock = DockStyle.Fill;
}
}
}
new to xamarin forms with SQLite. I need some guidance on how to use SQLite in Xamarin forms. Below is the code.
1) Create Interface
using System;
using SQLite.Net;
namespace SQLiteSample
{
public interface ISQLite
{
SQLiteConnection GetConnection();
}
}
2) Implementing ISQLite interface
using System;
using Xamarin.Forms;
using SQLiteEx.Droid;
using System.IO;
[assembly: Dependency(typeof(SqliteService))]
namespace SQLiteEx.Droid
{
public class SqliteService : ISQLite
{
public SqliteService() { }
public SQLite.Net.SQLiteConnection GetConnection()
{
var sqliteFilename = "myDB.db3";
// Documents folder
string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
var path = Path.Combine(documentsPath, sqliteFilename);
Console.WriteLine(path);
if (!File.Exists(path)) File.Create(path);
var plat = new SQLite.Net.Platform.XamarinAndroid.SQLitePlatformAndroid();
var conn = new SQLite.Net.SQLiteConnection(plat, path);
// Return the database connection
return conn;
}
}
}
3) Class for Database Operation :CRUD
using SQLite.Net;
using Xamarin.Forms;
namespace SQLiteEx
{
public class DataAccess
{
SQLiteConnection dbConn;
public DataAccess()
{
dbConn = DependencyService.Get<ISQLite>().GetConnection();
// create the table(s)
dbConn.CreateTable<Employee>();
}
public List<Employee> GetAllEmployees()
{
return dbConn.Query<Employee>("Select * From [Employee]");
}
public int SaveEmployee(Employee aEmployee)
{
return dbConn.Insert(aEmployee);
}
public int DeleteEmployee(Employee aEmployee)
{
return dbConn.Delete(aEmployee);
}
public int EditEmployee(Employee aEmployee)
{
return dbConn.Update(aEmployee);
}
}
}
I would like to know :
1) Where is the place to create a database that can be used through out the app. This means I can use it anywhere in any page without recreating it each time I need to use it.
2) Will table be recreated each time in above code?
3) How to I do a select statement in any page ie CustomerPage.xaml or SalesPage.xaml ?
In WinRT, I used below code. How to do it in Xamarin forms? Do I need to recreate SQLite DB? How to get the Path?
Using (var db = new SQLite.SQLiteConnection(App.DBPath){
var query = db.query<CashReceivable>("select * from CashRcvdTbl where Cust='" + Id + "'";
foreach( var item in query)
{
}
}
1) Here,
string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
This line in your ISQlite implementation points to your myDB.db3 SQLite file.
You can see this file into /data/data/#APP_PACKAGE_NAME#/files directory.
if (!File.Exists(path)) File.Create(path);
This line checks whether database file exists in above path or not. If not, then it creates this file once. This time it will be an empty sqlite file without any tables in it.
So, it will not recreated each time.
But, I think there is no need for this File exist check because, when you create a connection to the SQLite file, it automatically creates file if not exists.
So, it can be as simple as follows:
public class SqliteService : ISQLite
{
string dpPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), “myDB.db3”);
public SQLiteConnection GetConnection()
{
return new SQLiteConnection(new SQLite.Net.Platform.XamarinAndroid.SQLitePlatformAndroid(), dpPath, false);
}
}
2) Each time you create instance of DataAccess class, it will recreate Employee table/definition based on Table exists or not, as it calls dbConn.CreateTable<Employee>();
I generally write this line at Application Startup code.
public App ()
{
InitializeComponent ();
//Create all tables here. This will create them once when app launches.
using (var conn = DependencyService.Get<ISQLite>().GetConnection())
{
conn.CreateTable<Employee>();
}
MainPage = new HomePage ();
}
This will simply creates a new table in the SQLite file if table not exists, otherwise it updates the table definition.
3) You can do a select statement as follows:
public List<Employee> GetAllEmployees()
{
using (var conn = DependencyService.Get<ISQLite>().GetConnection())
{
return conn.Table<Employee>().ToList();
//OR
return conn.Query<Employee>("Select * From Employee");
}
}
In any page you can call this GetAllEmployees method to retrieve List of Employee.
It would be nice to be able to use BigQuery via ODBC. I already use MySQL through ODBC, and this would let me switch to BigQuery as a drop-in replacement for MySQL for my Big Data tables.
Simba, an expert in ODBC (they have ODBC drivers for nearly every data source you can think of), has built an ODBC connector for BigQuery. You can download it for free (for Windows) from the BigQuery third party tools page here (scroll down to the bottom of the page). If you would prefer to use Linux, you can download the ODBC driver from Simba directly from here. Note that Simba does charge if you download from their site. Their driver may be more up-to-date and will include support.
A feature to note is that the Simba driver has the ability to translate standard SQL-92 compliant SQL into BigQUery's dialect of SQL. This can be useful if you want to use it as a drop-in replacement for a relational database. However, if you want to use the full features of BigQuery (nested data, shuffled JOIN / GROUP BY), you should turn this switch off to send queries directly.
Once you've installed the BigQuery ODBC driver and created a DSN (see Simba ODBC docs for a step-by-step guide to DSN creation), you'll want to start making ODBC queries. Here is a code sample that does this from C#. If you compile and run it, it will connect to BigQuery, run a simple query, and print the results.
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Odbc;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BigQueryE2E
{
/**
* Helper class to build an ODBC Connection to connect to a Simba
* BigQuery ODBC Driver.
*/
class ConnectionBuilder {
private String Dsn;
private String Catalog;
private String ExecCatalog;
private bool UseNativeQuery;
public ConnectionBuilder SetDsn(String dsn) {
Dsn = dsn;
return this;
}
public ConnectionBuilder SetCatalog(String catalog) {
Catalog = catalog;
return this;
}
public ConnectionBuilder SetBillingCatalog(String catalog) {
ExecCatalog = catalog;
return this;
}
public ConnectionBuilder SetUseNativeQuery(bool nativeQuery) {
UseNativeQuery = nativeQuery;
return this;
}
public OdbcConnection Build() {
if (Catalog == null || Dsn == null) {
throw new ArgumentException("Missing required Connection setting");
}
StringBuilder connectionString = new StringBuilder();
connectionString.AppendFormat("DSN={0}; Catalog={1};", Dsn, Catalog);
if (ExecCatalog != null) {
connectionString.AppendFormat("ExecCatalog={0};", ExecCatalog);
}
if (UseNativeQuery) {
connectionString.Append("UseNativeQuery=1");
}
OdbcConnection conn = new OdbcConnection();
conn.ConnectionString = connectionString.ToString();
return conn;
}
}
class Program {
private static String Query =
"SELECT corpus, SUM(word_count) " +
"FROM samples.shakespeare " +
"GROUP BY corpus";
private static void PrintResults(OdbcDataReader reader) {
for (int ii = 0; ii < reader.FieldCount; ii += 1) {
System.Console.Write("{0}{1}",
reader.GetName(ii),
ii + 1 < reader.FieldCount ? "\t" : "\n");
}
while (reader.Read()) {
for (int ii = 0; ii < reader.FieldCount; ii += 1) {
System.Console.Write("{0}{1}",
reader.GetValue(ii),
ii + 1 < reader.FieldCount ? "\t" : "\n");
}
}
}
static void Main(string[] args) {
OdbcConnection connection = new ConnectionBuilder()
.SetDsn("bigquery1")
.SetCatalog("publicdata")
.SetBillingCatalog("bigquery-e2e")
.Build();
try {
connection.Open();
using (OdbcCommand command = connection.CreateCommand()) {
command.CommandText = Query;
using (OdbcDataReader reader = command.ExecuteReader()) {
PrintResults(reader);
}
}
} catch (Exception ex) {
System.Console.WriteLine("Error {0}: {1}",
connection.State != ConnectionState.Open
? "opening connection" : "executing query",
ex);
} finally {
connection.Close();
}
System.Console.ReadKey();
}
}
}
I have a schema in Tridion which have embedded schema fields which may further have embedded fields in there.
I want to reach final leaf field so that I can assign some value to it. For that I want to write recursive function which loop through each and every field until it reaches a final field.
I am implementing using the Core Service in SDL Tridion 2011
My code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ServiceModel;
using System.Net;
using System.Xml;
using Tridion.ContentManager.CoreService.Client;
using System.Text;
using Tridion.ContentManager.CoreService;
using System.ServiceModel.Channels;
using System.IO;
using System.Collections;
using System.Text.RegularExpressions;
using System.Xml.Linq;
using System.Data.OleDb;
using System.Data;
using System.Configuration;
namespace Loading_Utility
{
public partial class TST : System.Web.UI.Page
{
Fields obj = new Fields();
protected void Page_Load(object sender, EventArgs e)
{
using (ChannelFactory<ISessionAwareCoreService> factory =
new ChannelFactory<ISessionAwareCoreService>("wsHttp_2011"))
{
ISessionAwareCoreService client = factory.CreateChannel();
var schemaFields = client.ReadSchemaFields("tcm:202-2242-8", true, new ReadOptions());
ComponentData component = (ComponentData)client.GetDefaultData(ItemType.Component, "tcm:202-638-2");
var fields = Fields.ForContentOf(schemaFields);
component.Schema.IdRef="tcm:202-2242-8";
}
}
public void fieldRecursion(Field field)
{
//var getFields = fields;
if (field.GetType() == typeof(EmbeddedSchemaFieldDefinitionData))
{
// code for checking further if field is embedded or not
//Field newField = field.GetSubFields().GetFieldElements( new ItemFieldDefinitionData() as Field)
//fieldRecursion(recursiveField);
}
//string fieldName = recursiveField.Name;
//fields[fieldName] = "HI";
}
}
}
Whilst I don't have the solution you are looking for, I see you're using the core service, personally I prefer to get hold of the Component XML (Component.Content) and parse/manipulate it as I need. Perhaps if you can paste the XML here I can drop it into one of my sample core service projects and send you a solution back?
In the event that doesn't help you, i've had a look at the api, and this should help you get going in the right path. Perhaps once you have a solution you could paste it here?
public void RecurseEmbeddedFields(SchemaFieldsData schemaFields)
{
foreach (ItemFieldDefinitionData field in schemaFields.Fields)
{
if (field.GetType() == typeof(EmbeddedSchemaFieldDefinitionData))
{
// check if this field contains more embedded fields
// if it does recurse
}
}
}
OK, I felt a bit guilty about not helping, but I still stand by my view that this is not a Tridion-related question and that you should try getting some more experience with general development practices.
Here's an example of how to load the Component's content, then read it recursively using Xml:
Xml of the component:
<Content xmlns="uuid:02395f72-acef-44e8-9c35-ff8c9f380251">
<EmbeddedSchema1>
<SomeField>Hello</SomeField>
<EmbeddedSchema2>
<ATextField>There</ATextField>
</EmbeddedSchema2>
</EmbeddedSchema1>
</Content>
Core Service code:
static void Main(string[] args)
{
SessionAwareCoreServiceClient client = new SessionAwareCoreServiceClient("wsHttp_2011");
ReadOptions readOptions = new ReadOptions();
ComponentData component = (ComponentData)client.Read("tcm:5-3234", readOptions);
Console.WriteLine("Find fields recursively");
XmlDocument content = new XmlDocument();
content.LoadXml(component.Content);
SchemaData schema = (SchemaData)client.Read(component.Schema.IdRef, readOptions);
XmlNamespaceManager ns = new XmlNamespaceManager(new NameTable());
ns.AddNamespace("content", schema.NamespaceUri);
foreach (XmlElement node in content.SelectNodes("content:*", ns))
{
ReadContentRecursively(node, ns);
}
client.Close();
}
private static void ReadContentRecursively(XmlElement node, XmlNamespaceManager ns)
{
if(!string.IsNullOrEmpty(node.InnerText))
{
foreach (XmlNode innerNode in node)
{
if(innerNode is XmlText)
{
Console.WriteLine("Node " + node.Name + " with value \"" + innerNode.Value + "\"");
}
}
}
if(node.SelectNodes("content:*", ns).Count > 0)
{
foreach (XmlElement childNode in node.SelectNodes("content:*", ns))
{
Console.WriteLine("Found Field: " + childNode.Name);
ReadContentRecursively(childNode, ns);
}
}
}
Notice how ReadContentRecursively calls itself?
Hope this helps.
After hours and hours of head scratching and not knowing WHY my site's code used to work on the old server and now on the new server it just doesn't work (changed IP of mailserver, used subdomain address for the server, changed ports, tried 25, 26, 587 and anything suggested by the server admins) I have finally stumbled through the real issue (I think) which is that the hosting requires authentication.
I have no idea how to add authentication to my old code and the support doesn't even reply to my tickets anymore. Any help is appreciated.
This is the part in the registration file which sends the activation code:
MailClass.MailGonder("info#mysite.com", TxtEMail.Text, "Activation", body, "info#mysite.com", "emailpassword", "mail.mysite.com", 587);
And this is the Mail_Class.cs file which handles the mail sending of all pages (there are other pages which also use this other than the registration page):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Net.Mail;
using System.Net;
namespace Sngl
{
public class MailClass
{
public MailClass() { }
public static void MailGonder(string kimden, string kime, string title, string body, string senderEmail, string senderPassword, string smtpServer, int port)
{
try
{
System.Net.Mail.MailMessage MyMailMessage = new System.Net.Mail.MailMessage(kimden, kime, title, body);
MyMailMessage.IsBodyHtml = true;
MyMailMessage.Priority = System.Net.Mail.MailPriority.High;
System.Net.NetworkCredential mailAuthentication = new
System.Net.NetworkCredential(senderEmail, senderPassword);
System.Net.Mail.SmtpClient mailClient = new System.Net.Mail.SmtpClient(smtpServer, port);
mailClient.EnableSsl = false;
mailClient.UseDefaultCredentials = false;
mailClient.Credentials = mailAuthentication;
mailClient.Send(MyMailMessage);
PropertyClass.Result = true;
}
catch (Exception ex)
{
PropertyClass.Result = false;
PropertyClass.Message = ex.Message;
}
}
}
}
Error message shown is: "Failure sending mail."
No more details are given.
The link you gave must be for a really old posting because the example it gives uses obsolete .net classes. I've converted it to c# for you below, but i've got no idea if it will work as I've never used this stuff before.
using System;
using System.Web.Mail;
namespace Sngl
{
public class MailClass
{
public MailClass() { }
public static void MailGonder(string kimden, string kime, string title, string body, string senderEmail, string senderPassword, string smtpServer, int port)
{
try
{
var message = new MailMessage
{
From = kimden,
To = kime,
Subject = title,
Body = body
};
message.Fields["http://schemas.microsoft.com/cdo/configuration/smtpserver"] = smtpServer;
message.Fields["http://schemas.microsoft.com/cdo/configuration/smtpserverport"] = port;
message.Fields["http://schemas.microsoft.com/cdo/configuration/sendusing"] = 1;
message.Fields["http://schemas.microsoft.com/cdo/configuration/smtpauthenticate"] = 1;
message.Fields["http://schemas.microsoft.com/cdo/configuration/sendusername"] = senderEmail;
message.Fields["http://schemas.microsoft.com/cdo/configuration/sendpassword"] = senderPassword;
message.Fields["http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout"] = 60;
SmtpMail.SmtpServer = smtpServer;
SmtpMail.Send(message);
PropertyClass.Result = true;
}
catch (Exception ex)
{
PropertyClass.Result = false;
PropertyClass.Message = ex.Message;
throw;
}
}
}
}