C# tekst van een website krijgen

Status
Niet open voor verdere reacties.
[CPP]

var serializer = new DataContractSerializer(typeof(List<Favorieten>));
using (var stream = await ApplicationData.Current.LocalFolder.OpenStreamForReadAsync(XMLFILENAME))
{
var lijst = serializer.ReadObject(stream);
Debug.WriteLine("LIJST GEVONDEN{0}", lijst);
[/CPP]

In de debugger wordt de lijst niet eens gevonden, dus hij crasht ervoor al, ik weet niet waarom

ik zal je wel ff een mailtje sturen met daarin het project
 
Hij crashed de eerste keer omdat er dan nog geen bestand in de folder staat. Het zal zo blijven tot de gebruiker een spel toevoegt aan de favorieten en er een bestand wordt aangemaakt.

Dit los je op met een try catch die alleen de FileNotFoundException opvangt.

vb:
Code:
try
{
	var serializer = new DataContractSerializer(typeof(List<Favorieten>));
	var folder = ApplicationData.Current.LocalFolder;

	using (var stream = await folder.OpenStreamForReadAsync(XMLFILENAME))
	{
		var deserializedList = serializer.ReadObject(stream) as List<Favorieten>;
		if (deserializedList != null)
		{
			favoriet.ItemsSource = deserializedList;
			Debug.WriteLine("{0} favorites loaded", deserializedList.Count);
		}
	}
}
catch (FileNotFoundException)
{
	Debug.WriteLine("'{0}' not found in the local folder.", XMLFILENAME);
}





=====

En hoe het komt dat je maar 1 favoriet kunt opslaan:

Bij je buildObjectGraph maak een een nieuwe List<Favorieten>, voeg je een spel toe en sla je de lijst met deze ene favoriet op.
Je moet dus eerste de bestaande uitlezen, toevoegen aan de lijst, de nieuwe toevoegen en het geheel weer opslaan met de nieuwe favoriet. (of de oude in een field/property ergens vasthouden zoals ik in eerdere posts zei)

=====

Je moet wel CreationCollisionOption.ReplaceExisting blijven gebruiken anders schrijf je er achteraan en klopt je xml bestandindeling niet meer. (dan krijg je een crash bij het omzetten van de stream naar een List<Favorieten> omdat het geen geldig xml document meer is.
 
Laatst bewerkt:
Het meerdere favorieten toevoegen lukt nog niet echt, ik snap niet hoe ik die dan weer toe moet voegen aan de lijst

en hoe clear je de list?

ik weet nou trouwens ook waarom er geen tekst werd weergegeven in de grid, ik moest [DataMember] toevoegen in de class favorieten
 
Laatst bewerkt:
Ik heb nog nooit gewerkt met de DataContractSerializer maar dat je de properties moet markeren is dan wel waarschijnlijk ja, anderes weet de serializer niet wat jij wilt en niet wilt in het bestand. Dat doe ik ook met JSON.

Als je een favoriet toevoegt moet je niet een new List<Favorieten> maar de huidige lijst laden en daar aan toevoegen. (zelfde met wijzigen/verwijderen)
De favorieten leeg maken kun je zelfs doen door het bestand te verwijderen of een lege lijst op te slaan.

Je kunt ook een class maken die een lijst met favorieten serialized en deserialized, dan heb je bijvoorbeeld ook de naam van het bestand ook maar op een plaats.
 
mainpage:
onnavigatedto (load favorites)


item page:
add (load favorites, add new favorite, save favorites)

favorieten worden dan altijd geladen als je naar de mainpage gaat
 
Dat snap ik dat ik eerst de oude favorieten moet ophalen en dan de nieuwe moet ophalen en dan opslaan, maar hoe moet ik die oude weer toevoegen bij de nieuwe?

Laat maar was makkelijker dan ik dacht ;p
 
Laatst bewerkt:
Je moeten even snappen dat je alles in het favorieten.xml bestand overschrijft, dus de oude/huidige verdwijnen als je een lijst serialized. Er zit geen kabouter die de bestaande laat staan en de nieuwe toevoegt. :P


Code:
var result = readobject....

result.Add(new favorite...

writeobject(result)
 
als je met de localfolder getFileasync gebruikt kun je met de storagefile die je ervan terug krijgt een deleteasync method aanroepen.
 
Voorheen heb je altijd data opgevraagd met 'GET'. Nu moet je bepaalde data naar een uri posten met 'POST'.

De httpclient heeft een method; 'PostAsync' die een uri neemt en een content. De content is een HttpFormUrlEncodedContent class met de parameters die je normaal in de textbox invult.

Met de response die de PostAsync returned kun je de statuscode kijken van je response. (OK, FORBIDDEN, UNAUTHORIZED etc)

Nadat je een response hebt kun je uit de filter die in de constructor met de httpclient meegaat de cookies halen. Deze moet je daarna altijd met je requests (in de filter.CookieManager) meegeven zodat de client weet dat je ingelogd bent. Deze moet je dus ook ergens opslaan in je programma.


Ik kan niet veel testen bij deze website omdat ik geen juiste inlog gegevens heb maar kan wel een stukje voorbeeld code geven van iets dat ik zelf gebruik.
(code gewijzigd voor voorbeeld)


Om wat gegevens op te slaan heb ik een 'Account' class. Username kun je gebruiken om aan te geven hoe de gebruiker is aangemeld en de cookies heb je nodig bij elke keer dat je data van een website wilt halen.
[CPP]public class Account
{
private readonly string _username;
private readonly HttpCookieCollection _cookies;

public Account(string username, HttpCookieCollection cookies)
{
_username = username;
_cookies = cookies;
}

public string Username
{
get { return _username; }
}
public HttpCookieCollection Cookies
{
get { return _cookies; }
}

public override string ToString()
{
var sb = new StringBuilder();

sb.AppendLine(string.Format("username:{0}", Username));

foreach (var cookie in Cookies)
{
sb.AppendLine(string.Format("\t{0}:{1}", cookie.Name, cookie.Value));
}

return sb.ToString();
}
}[/CPP]

En om in te loggen heb ik een 'AuthenticationService' class (ook voorbeeld code)
[CPP]public class AuthenticationService
{
private readonly Uri _baseUri = new Uri("https://www.somtoday.nl");
private readonly Uri _authUri = new Uri("https://www.somtoday.nl/willibrord/login");

public async Task<Account> Authenticate(string username, string password)
{
using (var filter = new HttpBaseProtocolFilter())
using (var client = new HttpClient(filter))
{
//%3Asubmit=x&username=user&password_1402487292712=pass

var parameters = new Dictionary<string, string>
{
{"%3Asubmit", "x"},
{"username", username},
{"password_1402487292712", password},
};

var content = new HttpFormUrlEncodedContent(parameters);
var postUri = new Uri("https://www.somtoday.nl/willibrord/login");

using (var response = await client.PostAsync(postUri, content))
{
Debug.WriteLine("the statuscode from the response is '{0}'", response.StatusCode);

if (response.StatusCode == HttpStatusCode.Ok)
{
var cookieCollection = filter.CookieManager.GetCookies(_baseUri);
return new Account(username, cookieCollection);
}
}
}

return null;
}
}[/CPP]


In je browser (of sniffer zoals wireshark) als je je netwerk verkeer volgt (dev tools, ongeveer zoals je de html elements kunt bekijken) kun je data zien als je inlogt daar vandaan komen de namen van de parameters, de url van de post etc


In de account class kun je later ook andere gegevens toevoegen over het account zoals dingen in het profiel (geb. datum, woonplaats etc)
 
Ja, je moet alleen altijd de cookies gebruiken als je de source van de page wilt krijgen. Anders krijg je de source van een pagina waarop staat dat je ingelogd moet zijn om deze pagina te bekijken (of zo iets dergelijks).
 
Deze moet je daarna altijd met je requests (in de filter.CookieManager) meegeven zodat de client weet dat je ingelogd bent. Deze moet je dus ook ergens opslaan in je programma.

dus zoiets als:

Code:
using (var filter = new HttpBaseProtocolFilter())
{
	foreach(Cookie cookie in account.Cookies)
	{
		//add to filter.CookieManager...
	}
	
	using (var client = new HttpClient(filter))
	{	
		//get source
	}
}
 
[CPP]

foreach (Cookie cookie in account.Cookies)
{
filter.CookieManager(cookie);
}
[/CPP]

Wat moet er dan ipv account , want dat herkend ie niet?
 
Bekijk de voorbeeld code, je moet de cookies eerst ophalen en ergens opslaan. Dan weet je ook waar account vandaan komt en wat je inplaats van account kunt gebruiken.

Je hoeft geen account class te gebruiken maar je moet wel ergens je cookiecollection opslaan want deze moet je bij elk request meegeven. Ik gebruik een account class zodat ik die als parameter in methods mee kan geven, maar dan kan natuurlijk ook alleen de cookie collection zijn.
 
Ik weet dat ie van de Account class komt, maar hij herkent account niet en ook Account.Cookies niet
 
Dat komt omdat het voorbeeld code (daadwerkelijke code zelf even maken) is, je moet wel ergens die account variable vandaan halen. Dus zoals ik zei bijvoorbeeld in de method als parameter.

(zie de authenticate method geeft een account terug als de statuscode OK was)

Dan krijg je dus zoiets als dit, en kun je daarna de account var gebruiken waar nodig)

Code:
var service = new AuthenticationService();
var account = await service.Authenticate("username", "password");

if(account != null)
{
//get data using this account
}
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan