HowTo: Bilder mit CKEditor und ASP.NET MVC hochladen

Ich hatte gerade das Problem, dass ich mit dem WYSIWYG-Editor CKEditor Bilder hoch laden möchte, um sie direkt in meinen Text einzupflegen.
Dazu wird irgendwo im View der Editor definiert:

  <script type="text/javascript">
      window.onload = function() {
          CKEDITOR.replace('ckEditor', {
            skin: 'office2003',            
            filebrowserUploadUrl: '<%=Url.Action("UploadImage") %>'
      });
  };
  
</script>

Wichtig ist hier der Parameter „filebrowserUploadUrl“. Dies ist der Pfad, wohin das Bild beim Upload gesendet wird.
Im Controller wird das ganze nun verarbeitet:

        [AcceptVerbs(HttpVerbs.Post)]
        public string UploadImage()
        {
            // Datei speichern
            var identifier = Guid.NewGuid();
            string[] fileExt = Request.Files[0].FileName.Split('.');
            string safeFile = identifier + "." + fileExt[fileExt.Length - 1];
            Request.Files[0].SaveAs(Path.Combine(HostingEnvironment.MapPath("~/UploadedImages/"), safeFile));
            
            // Daten an CKEditor zurück geben
            string result = "<script type=\"text/javascript\">";
            result += "window.parent.CKEDITOR.tools.callFunction(" + Request.QueryString["CKEditorFuncNum"] + ", \"" +
                      Path.Combine(Url.Content("~/UploadedImages/"), safeFile) + "\",\"\");</script>";
            return result;
        }

Erst speicher ich das Bild irgendwo und gebe dann den Pfad per Javascript zurück. Da ich nur das JS ausführen lassen muss, gebe ich kein komplettes View zurück. Die Url wird dann korrekt an CKEditor übergeben (siehe Screenshots). Der letzte Parameter des callFunction()-Aufrufes kann für Fehlermeldungen genutzt werden, Bild zu groß o.ä.
Mich hat dieser kleine Aufruf bestimmt eine Stunde gekostet!

CKEditor - Datei auswählen, Hochladen CKEditor - Datei hochgeladen und Pfad übergeben

Linq: Group By mit mehren Werten

Um bei einer Seite auf alte News zu greifen zu können, wollte ich eine Liste wie hier im Blog anhand „Monat Jahr“ bekommen. Daher musste ich nach zwei Werten gruppieren, dies geht am einfachsten mit einem anonymen Wertetyp:

            var dateListe = from dateStamps in this.DataList
                             group dateStamps by
                                 new {dateStamps.PostedTime.Year, dateStamps.PostedTime.Month}
                             into g
                                 select new
                                           {
                                               Year = g.Key.Year,
                                               Month = g.Key.Month,
                                               Count = g.Count()
                                           };

Habe mir kurz als Debugmeldung einen String daraus gebastelt:

            foreach (var liste in linkListe)
            {
                ViewData["test"] += "Datum: " + liste.Month + " " + liste.Year + " Anzah: " + liste.Count + "<br />";
            }

Als Rückgabe erhaltet ihr eine Liste:

Datum: 1 2006 Anzah: 1
Datum: 3 2006 Anzah: 2

Damit kann man Arbeiten 🙂

ASP.NET: Eigenen RoleProvider schreiben

Da ich nun einen eigenen MembershipProvider nutze, möchte ich auch entsprechenden meinen RoleProvider anpassen.
Dies ist eigentlich ähnlich einfach, wie der MembershipProvider. Dazu wird eine eigene Klasse von System.Web.Security.RoleProvider abgeleitet. Auch könnt ihr hier wieder mit dem Überschreiben der Methode „Initialize()“ Werte aus der „web.config“ übergeben. Wo ihr die Daten ablegt, bleibt euch auch hier wieder überlassen.

Das Einbinden in die „web.config“ erfolgt über folgenden Eintrag:

    <roleManager enabled="true" defaultProvider="MyPersonalRoleProvider">
      <providers>
        <clear />
        <add name="MyPersonalRoleProvider" type="MyApp.PersonalRoleProvider" connectionStringName="MSPConnString" />
      </providers>
   </roleManager>

Wichtig ist die erste Zeile. Standardmäßig steht „enabled“ nämlich auf false!
Der RoleProvider ist nun fertig zum Einsatz! In eurem ASP.NET Projekt könnt ihr auf die Daten über die Standardmethoden wie etwa „Role.IsUserInRole()“ etc. zugreifen. Mehr dazu steht in der MSDN.

ASP.NET: Eigenen MembershipProvider schreiben

Manchmal kann es Sinn machen, nicht den standardmäßigen ASP.NET MembershipProvider zu nutzen. Daher möchte ich euch kurz erklären, wie ihr einen eigenen MembershipProvider schreiben könnt. Dabei ist es letztendlich euch überlassen, wo die Daten gespeichert sind.

Ich benutze bei einem Projekt etwa eine SQL-Datenbank und speicher bzw. lese die Daten per Stored-Procedures. Man könnte die Daten aber auch in einer XML-Datei speichern oder direkt hardcoded in der Klasse.
ASP.NET: Eigenen MembershipProvider schreiben weiterlesen

Linq to Entity – Many to Many Relationship Problem

Aktuell habe ich folgendes Problem.
Ich habe eine Tabelle Rollen und eine Tabelle Benutzer, beide stehen über eine dritte Tabelle in einer m:m-Beziehung. Per Linq-to-Entity, also über ein ADO.NET Modell hole ich mir die Daten. Jedoch kann ich keine Relationen speichern.
Aktuell bekomme ich die Fehlermeldung:

EntitySet 'UserInRole' kann nicht aktualisiert werden, denn es hat eine DefiningQuery, und im <ModificationFunctionMapping>-Element ist kein <InsertFunction>-Element zur Unterstützung des aktuellen Vorgangs vorhanden.

Eine Suche im Netz bring mich nicht wirklich weiter. Dort hieß es, ich soll für die m:m-Tabelle einen Primary-Key setzen. Habe ich über beide Felder getan, Ergebnis war das selbe.
Bei dem Beispiel kann ich es über den Role-Provider lösen, aber so richtig weiter bringt es mich dann an anderer Stelle nicht.
Ich werde weiter berichten.