Laden...

Forenbeiträge von Yheeky Ingesamt 200 Beiträge

25.06.2012 - 00:02 Uhr

Hallo Achim,

danke für die Rückmeldung! Die mobile Version ist auch noch stark in der Beta, die sollte eigentlich noch nicht online sein 😉
Aber danke für den Hinweis! Die mobile Seite kommt bald 😃

Viele Grüße,
Christian

24.06.2012 - 20:16 Uhr

Hallo zusammen,

ich würde hier gerne mein neues Projekt **KickCom **vorstellen.
Bei dem Projekt handelt es sich um eine Fussball-Community, die zum Diskutieren von Fussballspielen einlädt. Bisher ist es als "Pilotprojekt" gestartet und startet am kommenden Dienstag den 26.06.2012 mit der 1.Fussball Bundesliga.
Die Plattform ist natürlich kostenlos und wird nicht über Werbung finanziert!

Homepage: http://www.kickcom.de
Infos: http://www.kickcom.de/Home/WasErwartetMich
Facebook: https://www.facebook.com/KickCom.de

Das Konzept


Als Fan einer Mannschaft verfolgt man natürlich gerne die Spiele seines Lieblingsvereins. Am meisten Spaß macht es, wenn man die Spiele nicht alleine verfolgen muss, sondern mit anderen Benutzern interagieren, in diesem Fall, diskutieren kann. Hier kommt die Plattform "KickCom" ins Spiel.

Nach der Anmeldung gelangt man in die Nachrichtenübersicht des Lieblingsvereins. Hier findet man Nachrichten, Transfergerüchte oder Trainingsberichte des Lieblingsclubs. Es findet lediglich eine interne Diskussion untereinander statt. Möchte man mit Fans von anderen Clubs diskutieren, stehen die Fanlager zur Verfügung. Hier können sich alle Benutzer untereinander austauschen.

Jeder Benutzer kann an einem Spieltag die Partie seiner Wahl verfolgen - am ehesten natürlich die des eigenen Vereins.  Um der Partie beizuwohnen, muss der Benutzer - wie im echten Leben - ein Ticket lösen (kostenlos). Dann ist man berechtigt bei der Diskussion dieses Spiels teilzunehmen und mit den eigenen, aber auch den Gästefans für Stimmung zu sorgen.
Wenn man sich im Vorfeld intensiv mit der Begegnung befasst hat, kann man sein Wissen mit den anderen Benutzern teilen und einen sogenannten Vorbericht erstellen. Hier werden alle gesammelten Informationen in einem eigens verfassten Text zusammengeschrieben und informiert die Community mit allen Informationen, die es zu dem Spiel zu wissen gibt. Abschließend kann der Vorbericht von den Benutzern zum Vorbericht des Spiels gewählt werden.
Wenn ihr euch jetzt noch als Fussballkenner zeigen möchtet, könnt ihr einen Tipp bezüglich des Ausgangs der Partie abgeben. 
Die Anzahl deiner verfolgten Spiele, deine erstellten Vorberichte, sowie die Erfolgsquote deiner Tipps werden in deinem persönlichen Profil angezeigt und geben an, ob du Fussballsachverstand besitzt!

Einen Bezug zu diesem Forum hat sie auch. Die Webanwendung habe ich in .NET mit dem MVC Framework entwickelt.

Wäre schön, wenn ihr mal vorbeischauen würdet und die Seite mal ein bisschen mit Leben füllt.

Vielen Dank fürs Lesen!

Viele Grüße,
Christian

24.02.2012 - 19:54 Uhr

Ich habe gerade was gemerkt, was ziemlich faul ist. Ich habe beim Login folgenden Code:


            FormsAuthentication.SetAuthCookie(username, rememberMeBool);
           
            if (rememberMeBool)
            {
                var createdCookie = FormsAuthentication.GetAuthCookie(username, true);
                createdCookie.Expires = DateTime.Now.AddYears(10);
                Response.Cookies.Add(createdCookie);
            }

Der Cookie hat ein Expires-Datum von 2022! Beim nächsten Request springt der Debugger in AuthorizationCode und wenn ich in der Identity nach dem Ticket schaue, steht da wieder 2012, mit einem Expires-Datum was eine Minute höher ist, wie die aktuelle Zeit (Timeout von 1 in web.config).
Er merkt sich das also im Cookie irgendwie nicht 🙁

Kann doch nicht so schwer sein, sowas zu implementieren...

24.02.2012 - 19:00 Uhr

Ich habe den Timeout in der web.config mal aus Spaß auf 1 gesetzt. Wenn ich nun länger als 1 Minute warte und per Breakpoint ins Programm gehe, gibt es irgendwas, was den Timeout verschiebt, obwohl ich das nun so umgestellt habe, dass ich quasi GARNICHTS mache. Normalerweise müsste doch der Timeout verfolgen, das Ticket abgelaufen sein (IsAuthenticated = false) etc...ich verstehe wirklich nicht, was da passiert!
Hier mal meine relavanten Dateien:

web.config:


<configuration>
    <.....>
    <system.web>
        <.....>
        <authentication mode="Forms">
      <forms loginUrl="~/Home/Index"
             timeout="1"
             defaultUrl="~/Home/Index"
             slidingExpiration="true"
             protection="All"
             enableCrossAppRedirects="false"
             cookieless="AutoDetect"/>
    </authentication>
        <!-- Machine Key for timeout cookie required ! -->
        <machineKey validationKey="key here"
                    decryptionKey="key here"
                    validation="SHA1"
                    decryption="AES" />
        <membership defaultProvider="MeinProvider">
            <providers>
                <clear />
                <add name="MeinProvider"
                     type="Solution.Models.MeinProvider" />
            </providers>
        </membership>
            <.....>
    </system.web>
        <.....>
</configuration>

Einen RoleProvider brauche ich nicht. Einen "MeinProvider" habe ich relativ "nackt" erstellt und sieht so aus:

using System;
using System.Web.Mvc;
using System.Web.Security;
using System.Text;

namespace Solution.Models
{
    public class MeinProvider : MembershipProvider
    {
        public override string ApplicationName
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public override bool ChangePassword(string username, string oldPassword, string newPassword)
        {
            throw new NotImplementedException();
        }

        public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)
        {
            throw new NotImplementedException();
        }

        public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
        {
            throw new NotImplementedException();
        }

        public override bool DeleteUser(string username, bool deleteAllRelatedData)
        {
            throw new NotImplementedException();
        }

        public override bool EnablePasswordReset
        {
            get { throw new NotImplementedException(); }
        }

        public override bool EnablePasswordRetrieval
        {
            get { throw new NotImplementedException(); }
        }

        public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
        {
            throw new NotImplementedException();
        }

        public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
        {
            throw new NotImplementedException();
        }

        public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
        {
            throw new NotImplementedException();
        }

        public override int GetNumberOfUsersOnline()
        {
            throw new NotImplementedException();
        }

        public override string GetPassword(string username, string answer)
        {
            throw new NotImplementedException();
        }

        public override MembershipUser GetUser(string username, bool userIsOnline)
        {
            throw new NotImplementedException();
        }

        public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
        {
            throw new NotImplementedException();
        }

        public override string GetUserNameByEmail(string email)
        {
            throw new NotImplementedException();
        }

        public override int MaxInvalidPasswordAttempts
        {
            get { throw new NotImplementedException(); }
        }

        public override int MinRequiredNonAlphanumericCharacters
        {
            get { throw new NotImplementedException(); }
        }

        public override int MinRequiredPasswordLength
        {
            get { throw new NotImplementedException(); }
        }

        public override int PasswordAttemptWindow
        {
            get { throw new NotImplementedException(); }
        }

        public override MembershipPasswordFormat PasswordFormat
        {
            get { throw new NotImplementedException(); }
        }

        public override string PasswordStrengthRegularExpression
        {
            get { throw new NotImplementedException(); }
        }

        public override bool RequiresQuestionAndAnswer
        {
            get { throw new NotImplementedException(); }
        }

        public override bool RequiresUniqueEmail
        {
            get { throw new NotImplementedException(); }
        }

        public override string ResetPassword(string username, string answer)
        {
            throw new NotImplementedException();
        }

        public override bool UnlockUser(string userName)
        {
            throw new NotImplementedException();
        }

        public override void UpdateUser(MembershipUser user)
        {
            throw new NotImplementedException();
        }

        public override bool ValidateUser(string username, string password)
        {
            if ((from d in new DatabaseDataContext().Benutzer where d.Benutzername == username && d.Passwort == password select d).Any())
            return true;
			
			return false;
        }
    }
}

Und ein AuthorizeAttribute habe ich auch noch erstellt:


using System;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;

namespace Solution.Models
{
    public sealed class MeinAuthorizeAttribute : AuthorizeAttribute
    {
        public new string Roles;

		private string GetRoleForUser(string username)
        {
            return (from u in new DatabaseDataContext().Benutzer
                    where u.Benutzername == username
                    select u.Rolle).FirstOrDefault();
        }
		
        public MeinAuthorizeAttribute()
        {
		
        }

        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (httpContext == null)
                return false;

            if (!httpContext.User.Identity.IsAuthenticated)
                return false;

            var personRole = GetRoleForUser(httpContext.User.Identity.Name);

            return Roles.Contains(personRole);
        }

        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            if (filterContext == null)
            {
                throw new ArgumentNullException("filterContext");
            }

            if (AuthorizeCore(filterContext.HttpContext))
            {
                // ** IMPORTANT **
                // Since we're performing authorization at the action level, the authorization code runs
                // after the output caching module. In the worst case this could allow an authorized user
                // to cause the page to be cached, then an unauthorized user would later be served the
                // cached page. We work around this by telling proxies not to cache the sensitive page,
                // then we hook our custom authorization code into the caching mechanism so that we have
                // the final say on whether a page should be served from the cache.
                var cachePolicy = filterContext.HttpContext.Response.Cache;
                cachePolicy.SetProxyMaxAge(new TimeSpan(0));
                cachePolicy.AddValidationCallback(CacheValidateHandler, null);

                if (!HttpContext.Current.Request.RawUrl.StartsWith("/Ajax/"))
                {
                    //var createdCookie = FormsAuthentication.GetAuthCookie(HttpContext.Current.User.Identity.Name, true);
					//createdCookie.Expires = DateTime.Now.AddDays(1);
					//Response.Cookies.Add(createdCookie);
                }
            }
            else
            {
                filterContext.HttpContext.Response.Redirect("/Home/NotLoggedIn");
                filterContext.Result = new ContentResult();
            }
        }
    }
}

Aufgerufen werden alle Funktionen in den Controllern nach folgendem Schema:


[MeinAuthorizeAttribute(Roles = "Administrator,Benutzer")]
        public ActionResult Index()
        {
            return View();
        }

Ich bin echt ratlos X(

24.02.2012 - 14:08 Uhr

Du machst Dir einen eigenen MemberShipProvider zusammen mit einem CustomAuthorizeAttribute. Weiß nicht, ob das CustomAuthorizeAttribute alleine ausreicht. Hab ich grad nicht im Kopf.

Anschließend kannst Du :::

Das habe ich doch gemacht und auch oben dargestellt. Ich habe einen BaseController, der bei jedem Request (in meinem Fall Seitenaufruf) gefeuert wird. Die normalen Controller werden von BaseController abgeleitet. Alle Ajax-Aufrufe gehen in den AjaxController, der eben kein Event feuert. Vom Prinzip her funktioniert also die Unterscheidung von Ajax und Nicht-Ajax Aufruf.
Nur bekomme ich es nicht hin, dass ein Benutzer angemeldet bleibt.

Was ich allerdings nicht verstehe: beim Einloggen wird der Timeout durch mein Ticket (s. oben im ersten Posting) auf 525600 gesetzt von daher sollte das Ticket ja folglich auch nicht ablaufen. Irgendetwas sorgt allerdings dafür, dass das Ticket abläuft, obwohl der Timeout so hoch ist - das verstehe ich nicht.

23.02.2012 - 22:12 Uhr

Das ist kein Problem.
Kann man auch mit nem Attribut an einem Controller / Action steuern, sodass Du sogar entscheiden kannst, welche Action ein Timeout verlaengert und welches nicht.

Ja, aber dann muss ich das doch manuell weiterschieben 😉

Hast du ein Beispiel von dem was du meinst?

23.02.2012 - 20:49 Uhr

Hi Abt,

ich hatte mich ja für den manuellen Weg entschieden gehabt, weil ich viele AJAX-Calls verwende und da jedes Mal der Timeout weitergeschoben wird, auch wenn der Benutzer kein "Angemeldet bleiben" ausgewählt hat.
Was mich nun aber noch stutzig macht. Es gibt soviele Stellen, wo von einem Timeout gesprochen wird. Wo sind denn da die Unterschiede?
1.web.config: <forms timeout="10"> 1.web.config: <membership defaultProvider="MyMembershipProvider" userIsOnlineTimeWindow="10"> 1.var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket)
{
Expires = DateTime.Now.AddMinutes(timeout),
HttpOnly = true
};

1.Session.Timeout = 10;

Ich bin irgendwie verwirrt, wo man den überall setzen muss, wo man Hilfestellungen bekommt etc...
Habe leider auch keine aufschlussreichen Tutorials gefunden, die mir da groß weiterhelfen.

Wäre super, wenn du dazu noch was schreiben könntest.

Danke und Gruß,
Yheeky

22.02.2012 - 00:51 Uhr

Mhmm wieder ausgeloggt 😦
Scheint doch noch irgendwo zu haken...noch eine Idee?

21.02.2012 - 22:00 Uhr

Cool danke! Habs jetzt mal eingebaut (man muss doch außer dem MachineKey in der web.config nichts machen, oder?) und bisher funktioniert es. Habe die Seite nach einer Stunde wieder aufgemacht und war noch eingeloggt 👍

Vielen Dank nochmal!
Gruß Yheeky

20.02.2012 - 18:02 Uhr

Hast Du den <machineKey /> in der Web.Config gesetzt? Erst dann funktioniert ein Remember.

Nee, den habe ich nicht gesetzt. Wie muss ich den denn setzen und wieso funktioniert es dann lokal?

17.02.2012 - 20:37 Uhr

Hi,

ich habe in meiner MVC-Anwendung eine Funktion "Angemeldet bleiben" implementiert. Ich möchte, dass der Benutzer sich nicht jedes Mal anmelden muss, wenn er auf meine Seite kommt (und er natürlich den Haken gesetzt hat). Dies funktioniert lokal auch hervorragend, jedoch nicht auf meinem Webserver.
Weiss jemand woran das liegen könnte?

Hier die Art und Weise, wie ich das mache:

Beim Login wird diese Funktion aufgerufen:

var rememberMeBool = rememberMe == "on" ? true : false;
var timeout = rememberMeBool ? 525600 : 10;
var authTicket = new FormsAuthenticationTicket(username, rememberMeBool, timeout);
var encryptedTicket = FormsAuthentication.Encrypt(authTicket);
var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket)
	{
		Expires = DateTime.Now.AddMinutes(timeout),
        HttpOnly = true
    };
Response.Cookies.Add(authCookie);

HttpContext.User = new GenericPrincipal(new FormsIdentity(authTicket), new[] { String.Empty });

Session["LastAction"] = DateTime.Now;
Session.Timeout = 10;

Bei jedem Seitenaufruf überprüfe ich, ob die "LastAction" in der Session älter ist, als der gesetzte Timeout.

protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
    var sessionDate = new DateTime();

    if (Session["LastAction"] != null)
    DateTime.TryParse((Session["LastAction"]).ToString(), out sessionDate);
	
    if (HttpContext.User.Identity.IsAuthenticated)
    {
        Session["LastAction"] = DateTime.Now;
	}
}

Ich kann in dem Fall nicht die Standardfunktionalität der FormsAuthentication nutzen, da ich viele AJAX-Aufrufe in meiner Webseite habe (auch welche mit Interval), die natürlich die Session automatisch verlängern und somit nie auslaufen lassen.
Die Session benutze ich also, um die wirkliche Inaktivität herauszufinden.

Ich hoffe mir kann jemand bei dem Problem behilflich sein.

Danke schonmal und viele Grüße,
Yheeky

23.09.2011 - 08:54 Uhr

Hi,

ich möchte in meiner Anwendung ein Suchfeld anbieten und dafür habe ich RegEx verwendet, um meine Datenbank nach passenden Einträgen zu durchsuchen.
Die Verwendung von ? und * funktioniert schon wunderbar, nur hätte ich gerne noch eine Unterstützung, wie man nach mehreren verschiedenen Einträgen suchen kann.

Beispiel:
Ich suche nach "*pel" - so wird mir "Opel" geliefert.
Ich suche nach "*wagen" - so wird mir "Volkswagen" geliefert.

Jetzt brauche ich ein Denkanstoß, damit ich beide irgendwie in einer Suche verknüpfen kann, damit ich sowas wie "*pel + *wagen" eingeben kann und ich "Opel" und "Volkswagen" zurückbekomme.

Hat da jemand eine Idee oder - noch besser - ein Beispiel, wie man das umsetzen könnte?

Danke schonmal und Gruß,
Yheeky

14.09.2011 - 15:41 Uhr

Klingt nach einer guten Idee! DANKE!
Wenn die Datensätze mehr werden (was erstmal nicht abzusehen ist) kann ich immer noch über eine andere Variante nachdenken.

Gruß Yheeky

14.09.2011 - 01:45 Uhr

Hi,

ich habe eine SQL Server 2008 R2 Datenbank mit der ich arbeite und suche momentan nach einer Möglichkeit, wie ich folgende Funktionalität umsetzen kann.
Ich habe eine Tabelle in der wöchentlich ca. 30 Einträge hinzukommen. Für diese 30 Einträge gibt es jeweils ein Attribut, welches ein zukünftiges Datum enthält.
Ich suche nun nach einer Möglichkeit, eine Funktion auszuführen, wenn genau das Datum aus einem Datenbank (inkl. Zeitstempel) erreicht wird. Gibt es eine solche Funktion oder muss ich permanent einen Job laufen lassen, der das prüft?

Danke schonmal für die Antworten!
Gruß Yheeky

05.09.2011 - 17:56 Uhr

Hi Abt,

danke für die Links!
Nun funktioniert es. Es reicht doch eigentlich aus, wenn ich bei der Validierung "<script>" und "<link>" elemente nicht zulasse oder? Ansonsten kann man ja nicht wirklich viel mit machen, oder täusche ich mich?

Danke nochmal und Gruß,
Yheeky

05.09.2011 - 15:40 Uhr

Hi,

ich arbeite an einer Anwendung basierend auf dem MVC.
Ich habe bereits viele AJAX Aufrufe über jQuery realisiert. Nun stoße ich auf ein Problem:
Ich möchte dem Benutzer ermöglichen HTML-Code in der Datenbank abzulegen. Korrekterweise schlägt die Anwendung Alarm (was ja gut ist). Nun möchte ich diesen jedoch deaktivieren und die Validierung selbst vornehmen. Ein ValidateRequest="false" in der Page-Anweisung bringt leider nichts.
Desweiteren bringt es auch nichts, den eigentlichen Textstring in ein Objekt zu stecken und das per AJAX zu übertragen...wird trotzdem anerkannt (was auch gut ist an sich 😉).
Gibt´s eine Möglichkeit, wie ich den String relativ einfach übertragen kann?

Danke schonmal für die Hilfe!

Gruß Yheeky

18.07.2011 - 15:23 Uhr

Ich möchte nicht nur eine Art Onlineliste realisieren sondern ich möchte auch implementieren, dass ein Benutzer per E-Mail über neue Nachrichten informiert wird, wenn er nich mehr eingeloggt ist. Dabei könnte ich beim Absenden einer Nachricht prüfen lassen, wie lange die letzte Aktion des Empfängers schon her ist und demnach entscheiden, ob er Benutzer z.B. per E-Mail benachrichtigt wird, da er nicht als "Online" angenommen wird oder er direkt über die Webseite informiert wird.
Alles nicht so einfach! 😉

18.07.2011 - 14:07 Uhr

Hi,

ich verstehe aber nicht, wie man das Problem mit dem Schließen des Browsers lösen könnte 🙁
Oder meintest du, dass bei OnActionExecuting alle eingeloggten Benutzer überprüft werden, ob sie beispielsweise in den letzten 30 Minuten eine Aktion hatten? Dies würde ja nur funktionieren, wenn sich immer ein Benutzer eingeloggt hat, ansonsten funktioniert das ja auch nicht.

18.07.2011 - 00:19 Uhr

Ok, habe ich jetzt soweit eingebaut 👍 8)
Mein Problem ist jetzt nur noch: wenn ein Benutzer die Seite verlässt, ohne, dass er auf "Ausloggen" geht, bin ich ja immer noch auf den Session/FormsAuthentication Timeout angewiesen, oder? Oder gibt´s ne andere Möglichkeit beim Schließen des Browsers noch eine letzte Aktion auszuführen und den Benutzer in der Datenbank auf Offline zu setzen?
Eine alternative Möglichkeit wäre ein DB-Job, der regelmäßig ausgeführt wird, aber das kostet Performance und das möchte ich vermeiden 😉

Gruß Yheeky

17.07.2011 - 19:51 Uhr

Hi,

@MarsStein: danke erstmal für deinen Post und die Idee 😃 ich habe sowas sogar schonmal in einem anderen Projekt ähnlich gelöst, aber in dem Fall habe ich den Wald vor lauter Bäumen nicht gesehen 😉

@Abt: Ich verwende in der Tat das MVC 😉
Ich habe meine Controller so aufgebaut, dass ich die normalen Aufrufe implementiert habe (Index, Edit, Details, etc...) und eben die WebMethoden mit [HttpPost] Attribut. Du sprichst von einem Aufbau nach dem Nested-Singleton und einem separataten Ajax-Controller. Ich denke ich weiss, was du meinst, aber um sicher zu gehen schreibe ich nochmal auf, wie ich es verstanden habe 😉

Die gewöhnlichen Aufrufe (Index, Edit, Details) der einzelnen Seiten gehen über die herkömmlichen Controller (Home, Benutzer, Nachrichten bzw. Home/Index, Benutzer/Index, Nachrichten/Index etc.). Dann erstelle ich einen Controller, der NUR mit Ajax-Aufrufen umgeht. Dieser beinhaltet keine OnActionExecution Methode, weil der Timeout nicht neu gesetzt werden muss, richtig?

Nun ist es ja aber so, dass das FormsAuthenticationTicket nur zum Lesen freigegeben ist...wie muss ich das denn dann erweitern? Neu instanziieren und zuweisen bzw. überschreiben?

Danke schonmal an euch!

Gruß Yheeky

17.07.2011 - 14:16 Uhr

Hi,

ich habe eine Webseite mit FormsAuthentication und habe in der web.config testweise einen Timeout von 1 Minute gesetzt.

<authentication mode="Forms">
      <forms loginUrl="~/Home/Index"
             timeout="1"
             defaultUrl="~/Home/Index"
             slidingExpiration="true"
             protection="All"
             enableCrossAppRedirects="false" />
    </authentication>

Ich habe in diversen Artikeln gelesen, dass dieser Wert jedoch nicht immer eine Auswirkung hat. Deswegen habe ich beim Login das FormsAuthenticationTicket selbst gesetzt:

var ticket = new FormsAuthenticationTicket(
                        1,
                        username,
                        DateTime.Now,
                        DateTime.Now.AddMinutes(1),
                        false,
                        String.Format("{0},{1}", username, password),
                        FormsAuthentication.FormsCookiePath
            );

            var encryptedTicket = FormsAuthentication.Encrypt(ticket);
            var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket)
            {
                HttpOnly = FormsAuthentication.RequireSSL,
                Path = FormsAuthentication.FormsCookiePath,
                Domain = FormsAuthentication.CookieDomain
            };
            Response.AppendCookie(cookie);

Das Problem ist nun, dass der Timeout NIE kommt! Ich habe längere Zeit überlegt und bin dann auf die Idee meiner AJAX-Calls gekommen. Ich lasse nämlich, wenn ein Benutzer eingeloggt ist, alle 10 Sekunden überprüfen, ob er neue Nachrichten im Postfach hat.

Ist es nun so, dass dieser Request immer dafür sorgt, dass das Timeout neu gesetzt wird? Wenn dem so ist: wie kann ich bei einer Anwendung, die AJAX-Calls verwendet, trotzdem einen Timeout hevorrufen lassen?
Ich hätte gerne eine Online/Offline Funktion und die funktioniert momentan natürlich so nicht.

Bin für jeden Tipp dankbar!

Gruß Yheeky

05.06.2011 - 13:22 Uhr

Also ich habe es jetzt gelöst und zwar mit einem foreach.
Folgenden Workaround habe ich gemacht.

Ich habe mir erst die Benutzer geholt, mit denen der aktuelle Benutzer eine Konversation hatten:

var query = (from k in Konversationen
                         where (k.BenutzerId_Empfänger == benutzerId)
                         orderby k.Datum descending
                         select k.BenutzerId_Sender).Distinct();

Dann bin ich diese Benutzer per foreach durchgegangen, habe alle Nachrichten aus der DB geholt, die mit der Konversation zu tun haben.

foreach (var queryItem in query)
{
	var newestItem = (from k in Konversationen
					   where
						   (k.BenutzerId_Sender == queryItem  && k.BenutzerId_Empfänger == benutzerId) ||
						   (k.BenutzerId_Sender == benutzerId && k.BenutzerId_Empfänger == queryItem)
					   select k).OrderByDescending(d => d.Datum).First();

	returnListe.Add(newestItem);
}

Die returnListe enthält dann alle Daten, die ich gesucht habe 😃

EDIT:
Ich habe die foreach nun durch eine Lambda-Expression ersetzt:

return query.Select(queryItem => (from k in Konversationen
                                 where (k.BenutzerId_Sender == queryItem && k.BenutzerId_Empfänger == benutzerId) || (k.BenutzerId_Sender == benutzerId && k.BenutzerId_Empfänger == queryItem)
                                 select k).OrderByDescending(d => d.Datum).First()).ToList();

Danke für eure Hilfe!

Gruß Yheeky

05.06.2011 - 12:30 Uhr

Das geht so nicht.

-> Inhalt nach Datum sortieren

Das hat er doch oben auch schon gemacht. Dann bekomme ich eine Liste, die so aussieht:

1, 3, Hi, how are you?, 05.06.2011 01:40
2, 1, Wie geht´s dir?, 05.06 01:38

1, 2, Hi zurück, 05.06.2011 01:35
3, 1, Hi there, 05.06.2011 01:33
2, 1, Hi, 05.06.2011 01:30

-> gfoidl's Linq Ausdruck verwenden

Damit bekomme ich die Konversation des letzten Partners, aber nicht alle letzten Konversationen. Ich möchte quasi die dick-markierten Einträge in dem Fall bekommen.
Jede Konversation hat ja logischerweise zwei beteiligte Benutzer. Wer von beiden zuletzt geschrieben hat, ist egal. Es soll im eigenen Profil angezeigt werden. Es müsste quasi ein DISTINCT gemacht werden, bei dem aber 1, 2 und 2, 1 als eins behandelt werden...weiss aber nicht, wie ich das umsetzen könnte.

Gerne könnte ihr mir auch in Form von T-SQL helfen, dann kann ich das vielleicht auch umsetzen.

Das Prinzip wird übrigens u.a. auch bei Facebook verwendet. Nur falls es noch etwas unklar ist, was ich genau will. Vielleicht konnte ich mich bisher noch nicht so gut ausdrücken 😃

05.06.2011 - 03:30 Uhr

Hi,

danke erstmal für die schnelle Antwort zu später/früher Stunde 😉
Das war aber leider nicht das was ich gesucht habe. Ich habe es aber auch nicht genau ausgedrückt 😉
Gehe nicht von den Daten aus dem ersten Posting aus, sondern von diesen hier:

2, 1, Hi, 05.06.2011 01:30
1, 2, Hi zurück, 05.06.2011 01:35
2, 1, Wie geht´s dir?, 05.06 01:38
3, 1, Hi there, 05.06.2011 1:33
1, 3, Hi, how are you?, 05.06.2011 01:40

Nun stelle dir vor, ich wäre der Benutzer mit der ID 1. Ich gehe in den Posteingang und dort sollen nun ALLE meine Konversationen aufgelistet werden, nicht nur die letzte! Es soll auf der Hauptseite von jeder einzelnen Konversation die letzte Nachricht angezeigt werden, damit man weiss, was die letzte Nachricht in der Konversation war. Bei den obrigen Daten wäre das:

Konversation zwischen 1 und 2:
Wie geht´s dir?, 05.06 01:38

Konversation zwischen 1 und 3:
Hi, how are you?, 05.06.2011 01:40

Nun dürfte sich das Ganze noch etwas schwieriger gestalten, nehme ich an 😉
Ich habe es leider noch nicht hinbekommen...vielleicht hast du ja noch eine Idee.

Gruß Yheeky

05.06.2011 - 02:05 Uhr

Hi,

ich habe eine MSSQL-Datenbank und eine Nachrichten-Tabelle.
Über meine Webseite können sich Benutzer Nachrichten versenden. Ich möchte die Anzeige in Konversationen anzeigen lassen.
Ich habe folgendes Tabellendesign (inkl. Testdaten):

BenutzerID_Sender, BenutzerId_Empfänger, Nachricht, Datum
2, 1, Hi, 05.06.2011 01:30
1, 2, Hi zurück, 05.06.2011 01:35
2, 1, Wie geht´s dir?, 05.06 01:38
3, 4, Hi there, 05.06.2011 1:33
4, 3, Hi, how are you?, 05.06.2011 01:40

Nun bin ich am Überlegen, wie ich eine LINQ Query zusammenbastele, die mir die beiden Konversationen mit der letzten Nachricht (und Datum) zurückgibt. Kann mir da vielleicht jemand auf die Sprünge helfen? Irgendwie bekomme ich das nicht so wirklich hin 😦

Danke schonmal und Gruß!
Yheeky

26.02.2011 - 15:42 Uhr

Habe es inzwischen geloest.
Bei jedem Seitenaufruf wird ein "Zuletzt gesehen" Wert gesetzt. Wenn dieser Wert aelter ist als 10 Minuten wird man als offline betrachtet.

Denke die Loesung passt fuer mich und vielleicht auch fuer andere 😃

Gruss Yheeky

25.02.2011 - 22:15 Uhr

Hi,

ich habe eine Webanwendung und eine Benutzerverwaltung. In meiner Datenbank habe ich ein Feld, welches das Login-Datum setzt. So kann ich schauen, ob ein Benutzer eingeloggt ist oder nicht. Nur wie kann ich den Logout realisieren?

Ich hoffe mir kann da jemand helfen. Ich benutze das ASP.NET MVC 2 Framework, vielleicht gibts da ja schon was passendes 😉

Danke und Gruss,
Yheeky

23.02.2011 - 12:51 Uhr

Mein Webhoster hat nur .NET 3.5 😉

23.02.2011 - 11:13 Uhr

Ok...aber da du auch drei Server hast, scheint es sich wirklich um eine sehr große Anwendung zu handeln. Dass sich in deinem Fall kein eigener Server lohnt, ist dann natürlich klar.
Kannst ich mir mal die MVC-Anwendung anschauen? Hast du die Seite online?
Meine Anwendung ist eher klein gehalten von daher sollte da ein Atom-Prozessor reichen.

22.02.2011 - 18:33 Uhr

Ok...aber gibt sicherlich auch passable Firewalls für Windows Server 2008. Muss ich mich mal schlau machen.
Hat jemand ein schönes, kleines Servergehäuse für mich (also in Form eines Links 😄).

22.02.2011 - 16:07 Uhr

Ich würde aber bei einem Rechner der wirklich 24/7 am Netz hängt einiges zur Absicherung betreiben, nicht das dir ein netter Zeitgenosse einen Tracker o.ä. drauf installiert.

Was meinst du da genau?

22.02.2011 - 15:25 Uhr

Hi Michael,

vorab...stimmt, das Preis-/Leistungsverhältnis sieht gut aus bei dem Anbieter. Dennoch gibt es ja doppelkernige Atom-Prozessoren, die zuhause mit einem Stromverbrauch von 30W auskommen...die Stromkosten dafür wären deutlich unter den Kosten die ein gemieteter Server verursachen würde.
Mein Upload liegt bei 5Mbit, denke das reicht für meine Zwecke...ich biete schließlich keine Downloads an, sondern nur eine "einfache" Webseite 😃
Genau, eine feste IP müsste ich mir noch holen.
Irgendwie finde ich die Variante doch recht reizvoll...hast das keiner hier mal selbst probiert? 😉

Gruß Yheeky

22.02.2011 - 13:29 Uhr

Hi,

ich hätte mal eine Frage: ich programmiere gerade eine Webanwendung mit Anbindung an eine SQL Server 2008 Datenbank. Ich benutze darüber hinaus das MVC-Framework. Momentan habe ich einen Webhoster der mich im Monat 1,5 Euro Euro kostet, allerdings habe ich auf den Server nur Zugriff über eine PLESK Oberfläche (sagt euch bestimmt was).
Das Problem ist nun, dass ich keinen Vollzugriff auf den Webserver habe und eben Frameworks - wie in meinem Fall das MVC - nicht einfach installieren kann. Ich habe mich aus dem Grund umgeschaut, ob es noch Webhosting-Alternativen mit Vollzugriff gibt. Diese sind aber verhältnismäßig sehr teuer, also kam ich auf die Idee, mir selbst einen Webserver zuhause aufzustellen.
Hat da schon jemand Erfahrung mit bzw. kann mir da jemand Tipps geben was die Ausstattung betrifft? Habe schon von kleinen HomeServern gelesen, die unter Volllast nur eta 30W verbrauchen, d.h. die Stromkosten würden auch nicht ins Unermessliche steigen.
Gültige Lizenzen habe ich auch. Das wäre beim Mieten ein weiterer Punkt, weil das ja auch in den Kosten mit verrechnet ist.

Wäre für jegliche Tipps und Hilfe dankbar.

Gruß Yheeky

12.02.2011 - 01:38 Uhr

Hätte doch nochmal eine Frage an dich Stipo.
Wie genau hast du das gelöst?

Ich habe in der web.config ein HttpModule hinzugefügt. Im HttpModule habe ich dann ein Init(HttpApplication context) und ein Application_BeginRequest(Object source, EventArgs e).
Ich habe ein bisschen mit einer Endlossschleife zu kämpfen. Beim jedem Request prüfe ich die Url und vergleiche, ob es sich um die Url der Wartungsseite handelt. Wenn ja, dann gehe ich mit "return" aus der Prozedure raus. Das scheint aber die Seite etwas zu verlangsamen,

Soweit mein Bericht...mich würde mal dein Code interessieren, also wie du das gelöst hast. Vielleicht kannst du mir ja weiterhelfen...wäre nett 😃

Danke und Gute Nacht!
Yheeky

11.02.2011 - 23:45 Uhr

Danke Tomot & Stipo!
Das hat mir sehr geholfen 😃

11.02.2011 - 22:45 Uhr

Hi,

ich würde gerne wissen, wie ich meine web.config ändern muss, damit ich eine Art "Wartungsfunktion" realisieren kann.
Meine Webseite soll komplett unzugänglich sein in einer gewissen Zeit, wenn ich daran arbeite d.h. alle Anfragen werden auf eine Seite, die ich angebe, umgeleitet.
Wie mache ich das in der web.config? Muss ich doch darüber machen, oder?

Danke und schon mal ein schönes Wochenende 😃
Yheeky

30.12.2010 - 15:14 Uhr

Wäre es unsauber, wenn ich das lieber über einen eigenen AuthorizeAttribute regele?
Ich würde dann bei OnAuthorization prüfen, ob der Benutzer authentisiert ist und ihn dann einfach auf die Login-Seite leiten. Das klappt auch und ich habe keine ReturnUrl...
Über ein einfaches Rollenmanagement kann ich ja jedem Controller bzw. jeder View ein Attribut zuweisen, welches nur bei vohandenen Rechten aufgerufen werden kann.

Was haltet ihr von dem Ansatz?

30.12.2010 - 13:26 Uhr

Hi,

ich habe eine Webseite und möchte gerne folgende Dinge umsetzen:

  • Login auf der Master-Page bzw. die Anzeige der Daten des eingeloggten Benutzers.
  • Klickt der Besucher auf Registrieren, wird er zur Registrieren Seite weitergeleitet.
  • Klickt der Besucher auf Nachrichten, wird er aufgefordert sich einzuloggen.

Ich habe einen Ansatz und zwar habe ich in meiner Web.config die Definition:

<authentication mode="Forms">
      <forms loginUrl="~/Home" 
             timeout="150"
             enableCrossAppRedirects="false" />
    </authentication>
    <authorization>
      <deny users="?"/>
    </authorization>

Hier habe ich immer die Zusatzinformation "ReturnUrl" in meiner Url...wozu wird diese benötigt? Sie sieht in meinen Augen unschön aus und ich hätte die da gerne raus.

Gibt es vielleicht ein gutes Tutorial, was meine Anforderung an eine Webseite bereits behandelt? Habe leider noch nicht viel in dem Bereich gemacht...

Danke und Gruß,
Yheeky

26.12.2010 - 18:36 Uhr

Du setzt Deine loginURL auf die Seite, auf der Dein Loginfeld liegt.
Optimalerweise ist das ~/Login und nicht ~/Home. Du kannst zwar einen Login von Home ermöglichen, aber solltest den Redirect nicht darauf legen.

Wieso sollte man das nicht machen? Das Login-Panel liegt in der Site.Master, da im Login-Panel (falls eingelogg) Benutzerdaten angezeigt werden sollen. Deswegen dachte ich, dass der Redirect auf ~/Home richtig wäre.

Wenn Du nun für einzelne Seiten einen Login erzwingen möchtest, dann definierst Du das direkt an der Action des Controllers.

MVC und der FormsAuth verfolgt sehr stark den Rollengedanken. Ist ein Anwender nun nicht Authentifiziert wird er an die loginURL zurückverwiesen und nach erfolgreichem Login automatisch wieder an diese Seite vermittelt.

Ich verwende eine eigene Datenbank mit eigenen Rollen etc. dafür müsste ich auch einen eigenen RoleProvider schreiben, damit ich die Authorize-Tags benutzen könnte, oder?

Edit: Was du nun hier an der Stelle vielleicht probieren kannst ist

  
<location path="Kontakt">  
  <system.web>   
    <authorization>  
      <allow roles="*" users="*" />  
    </authorization>  
   </system.web>  
</location>  
  

Cool, ja das hat geklappt. Hatte vorher "location path="Views/abc"" probiert, aber ich muss das Views einfach weglassen 😉

Danke schonmal bis hier hin...

Gruß Yheeky

26.12.2010 - 17:22 Uhr

Hi,

ich habe eine Seite mit dem MVC Framework erstellt und eine Forms Authenication implementiert. Funktioniert auch soweit, nur möchte ich nun ein paar Ausnahmen hinzufügen. Ich habe folgenden Code im meiner Web.config:

<authentication mode="Forms">
      <forms loginUrl="~/Home" 
             timeout="150" />
    </authentication>
    <authorization>
      <deny users="?"/>
    </authorization>

Jeder Versuch auf eine Seite zu kommen wird bei nicht-eingeloggtem Zustand automatisch wieder auf meine Home-Seite umgeleitet. Das ist genau so gewollt.
Nur gibt es noch ein paar andere Seite wie "Kontakt" oder "Über uns" und die können so natürlich auch nicht aufgerufen werden. Wie kann ich Seiten als Ausnahmen hinzufügen?

Danke schonmal im Voraus!

Gruß Yheeky

23.10.2010 - 12:47 Uhr

Hi,

ich habe in meiner MVC 2 Anwendung einen Ajax call eingerichtet. Der funktioniert auch, wenn ich Strings oder vordefinierte ListItems übergebe:

return Json(DateTime.Now.ToString(), JsonRequestBehavior.AllowGet);

oder

var list = new List<ListItem> 
    {
         new ListItem { Value = "1", Text = "VA" },
         new ListItem { Value = "2", Text = "MD" },
         new ListItem { Value = "3", Text = "DC" }
    };
            
return Json(list, JsonRequestBehavior.AllowGet);

Ich möchte nun aber eine eingebundene Datenbanktabelle (definiert in *.dbml Datei) zurückgeben. Dies mache ich so:

return Json(db.Autos.ToList(), JsonRequestBehavior.AllowGet);

Die Tabelle Autos enthält eine ID, MarkenID und Modell.

Ich lasse das Json result testweise als "alert" auf meiner Seite ausgeben. Bei den oeben beiden Aufrufen bekomme ich auch einen Alert angezeigt, bei dem über die DB-Tabelle allerdings nicht.
Kann mir jemand sagen, was ich falsch mache?

Gruß Yheeky

17.08.2010 - 14:02 Uhr

Ah, die Variante ist natürlich noch besser - danke! 😃

Gruß Christian

17.08.2010 - 12:11 Uhr

Hi,

ich habe eine CheckBox, welche einen Text beinhaltet. Normalerweise muss man zum an-/abwählen der Checkbox diese immer anklicken. Ich habe mir über JavaScript folgende Funktion gebastelt, die die Checkbox auch steuert, wenn man auf den Text klickt:

document.forms[0].elements['Elementname'].checked=(!document.forms[0].elements['Elementname'].checked)

Nun möchte ich das aber mit mehreren Checkboxen machen und so würde sich eine allgemeine Funktion anbieten. Ich habe das mal so versucht.

function HandleCheckBox(elementName) {
document.forms[0].elements[elementName].checked=(!document.forms[0].elements[elementName].checked)
};

Hier habe ich nun aber das Problem, dass das nicht funktioniert. Vermutlich wird "elementName" als Plaintext reingeschrieben?!

Kann mir da jemand helfen? Ist sicherlich keine große Sache 😉

Danke und Gruß,
Christian

13.08.2010 - 23:26 Uhr

Hi,

danke für die Links! Habe bisher nur kurz Zeit gehabt reinzulesen, aber hört sich wirklich super an. Habe eben mal eine kleine Anwendung mit einem UpdatePanel gemacht - ist wirklich einfach zu machen und es ist sehr übersichtlich.
Welche Frage sich nach wie vor aufwirft: verwendet man AJAX über einem UpdatePanel kann man über einfache Click-Events per C# Code einbauen (z.B. ein LINQ Statement). Das geht doch über JQuery nicht bzw. doch viel komplizierter, oder? Da muss man quasi zwei Sprachen beherrschen, wohingegen man über C# nur dies benötigt.

Gruß Christian

13.08.2010 - 17:37 Uhr

Hi,

ich hätte eine Frage bezüglich einer ASP-Anwendung.
Ich würde gerne auf meiner Seite so etwas realisieren, wie z.B. Facebook es macht, wenn man neue Dinge auf seiner Pinnwand veröffentlichen möchte. Sobald man auf "Teilen" klickt, erscheint der Beitrag auf der eigenen Pinnwand, ohne, dass die Seite neu geladen wird. Kann mir jemand sagen, wie man so etwas realisieren kann?
Ich habe so etwas schon einmal mit Javascript gemacht, allerdings ging es da nur um Designänderungen anhand von div-Tags etc. Im Fall von Facebook müssen ja auch Funktionen ausgeführt werden...würde mich mal interessieren, wie so etwas funktioniert und wie schwer es ist, so etwas in der Art umzusetzen.

Würde mich über viele Beiträge freuen!

Viele Grüße,
Christian

12.08.2010 - 15:19 Uhr

Ok, vom Ansatz habe ich es jetzt verstanden, danke 😃
Ich hätte es gerne dymanisch in meiner Seite eingebaut, aber in <% %> Blöcken funktioniert das Form.Controls.Add(); leider nicht. So ganz zufriedenstellen tut mich das Ganze leider nicht (dafür kannst du ja nichts, denn deine Funktion geht natürlich einwandfrei 😃)...

12.08.2010 - 13:34 Uhr

Hallo,

Sorry, aber da verstehe ich nur "Bahnhof" 😉 kannst du das vielleicht nochmal genauer erklären?
Ist ja nich mehr nötig, denn
Das mit dem Erstellen der Buttons über CodeBehind hat schonmal funktioniert.
Du brauchst nur eine von beiden Möglichkeiten.

Wenn Du trotzdem wissen willst, wie IPostBackEventHandler & Co funktionieren, schau bitte erst mal in die Doku zu den genannten Stellen. Bei konkreten Problemen kannst Du ja nochmal nachfragen.

Nein, ich meine ich habe die LinkButtons mit verschiedenen IDs nun hinbekommen, aber jeder von ihnen braucht ja auch ein eigenes PostBack. Das würde ich gerne wissen und ich denke das hast du mit der anderen Variante gemeint, oder?

12.08.2010 - 08:06 Uhr

Du könntest auch das IPostBackEventHandler-Interface implementieren (z.B. mit in der Page) und dann mit ClientScriptManager.GetPostBackEventReference oder ClientScriptManager.GetPostBackClientHyperlink die ensprechenden Links generieren. Bei den PostBack-Aufrufen wird dann jeweils das in den o.g. Funktionen übergebene Argument als Argument des PostBack-Handlers übertragen, so kannst Du dann die einzelnen LinkButtons auseinanderhalten.

Sorry, aber da verstehe ich nur "Bahnhof" 😉 kannst du das vielleicht nochmal genauer erklären?
Das mit dem Erstellen der Buttons über CodeBehind hat schonmal funktioniert.

Danke und Gruß,
Christian

12.08.2010 - 00:00 Uhr

Ok, schade, dass du auch nicht weiter weisst. Aber dennoch danke für deine Bemühungen!
Wie richte ich denn einen Hash-Wert in der Datenbank ein? Also welchen Datentyp muss ich da einstellen?

11.08.2010 - 23:13 Uhr

Der Hint in VS sagt "Binary".