• Webseitenerstellung und -hosting
  • .NET Anwendungsentwicklung
  • softwaregesteuerte Prozessoptimierung
  • .NET

    Programmierung

  • WebseitenErstellung

    undHosting

  • softwaregesteuerte

    Prozessoptimierung

  • Konzeption

    und Beratung

solutionS Daily Grind - Blog
solutionS

solutionS

%PM, %30. %609 %2012 %13:%Mär

Link zur Entität in einer Workflow E-Mail

Problem: Von MSCRM wird bei Datensatzerstellung automatisiert eine E-Mail verschickt. In dieser E-Mail kann man zwar sämtliche Informationen unterbringen, man hat aber keine Möglichkeit per Link dorthin zu gelangen. Microsoft stellt hier auch keine Lösung parat (zumindest nicht in Version 4 und ohne Drittanbietertools), zumal man im Workflow nicht direkt auf die ID der Entität zugreifen kann. Blöd! Man will es wieder nicht glauben. DAS GANZE INTERNET hatte keine Lösung! Ich habe eine kreiert, aber ganz ohne blauem Auge (markiert mit blauer Schrift) kommt man nicht davon. Dieser Link brachte mich auf die richtige Spur Da der Workflow bei Erstellung startet und man weder im Workflow noch im "FormSave" des Entitäsformulars (zumindest zu diesem Zeitpunkt) die ObjectID zur Verfügung hat, muss man beim Formload bereits einmal speichern. (Auge blau: Will man die Entität doch nicht anlegen und will das Formular über das X beenden wurde der Datensatz dennoch im Hintergrund bereits erstellt) Um dies nur beim ersten Aufruf zu tun lege ich ein Attribut "new_issaved" (bit) an, welches ich als variable missbrauche. Zusätzlich brauchen wir ein Attribut "new_link" welches als Datentyp nvarchar und Format URL  deklariert wird. der Aufruf im "onLoad" des Entitäsformulars eig. ist ganz simple: if (crmForm.all.new_issaved.value == null) { crmForm.Save(); } Hat man im Formular Pflichtfelder definiert kriegt man ein Problem, da er diese Felder beim Speichern im onLoad anmeckern würde. Ich habe die Pflichtfelder als "Eingabe empfohlen" gekennzeichnet, so erscheint zumindest anstelle des roten Sternchens. Die logische Prüfung erfolgt, ebenso wie die Prüfung auf das Kennzeichen "issaved", sowie die Befüllung der Link-Feldes mit der ObjectId im "onSave". In meinem Fall ist das betreff Feld ein Pflichtfeld: if (crmForm.all.new_issaved.value == null) { //null beim ersten aufruf, false beim ersten pseudo save, true beim korrekten save crmForm.all.new_issaved.value = false; } else { if (crmForm.all.new_betreff.value == "") { alert("Betreff muss gefüllt sein!"); event.returnValue = false; } else { crmForm.all.new_issaved.value = true; crmForm.all.new_link.value = "Link zum Kunden"; } } Erklärung: Setzt man den Html-Tag direkt in der Workflow-E-Mail funktioniert es leider nicht. Erst wenn der komplette Html-String im new_link Feld gespeichert wird ist der Link in der E-Mail auch wirklich anklickbar. der Backslash vor der Hochkommas dient der korrekten Html schreibweise und wird von Javascript ignoriert. Von Hinten durch die Brust ins Auge, da muss man erstmal draufkommen ;-)
%AM, %07. %477 %2012 %10:%Mär

Joomla Beitrags PDF Erstellung Fehler

Will man sich einen Beitrag im PDF Format anzeigen, erscheint folgende Fehlermeldung: Fatal error: Allowed memory size exhausted in on line .... Das Problem liegt nicht direkt an Joomla, sondern an den PHP Einstellungen des Webservers. Man suche die php.ini, meist unter usr/lib/php und ändere den Wert memory_limit auf mindestens 50MB. Mein Provider stellt dies sogar im Backend des Kunden-Centers zur Verfügung:            
%PM, %16. %595 %2011 %13:%Dez

joomla Beitrag sofort veröffentlichen

Tja, auf meiner Seite ist nicht viel los, deshalb ist es mir immer lästig Beiträge von Benutzern freizugeben und zu veröffentlichen, Ich habe volles Vertrauen in meine Autoren deshalb gibts von mir eine direkte Veröffentlichung von eingereichten Beiträgen. Sicherlich könnte man diese Auoten auch direkt zu Publishern machen, aber damit würde ich meine Benutzer überfordern. glaubt mir! man gehe also in "joomla/components/com_content/models/article.php" und ändere des Staus von 0 auf 1 $article->state = 1;
Situation: Microsoft SQL Server Integration Services 2008, ScriptTask, hinzufügen einer externen DLL Fehler:  "Es wurden keine Vorlageninformationen gefunden. Weitere Informationen erhalten Sie im Anwendungsprotokoll der Ereignisanzeige."               Dort widerum steht: "Die globalen Vorlageninformationen sind veraltet. Generieren Sie die Vorlagen erneut, indem Sie "VSTA.exe /installvstemplates" ausführen oder die Anwendung erneut installieren. Hinweis: Für die Korrekturmaßnahme sind Administratorrechte erforderlich." vermeindliche Lösung (lt.Microsoft): CMD öffnen cd "C:\Programme\microsoft visual studio 9.0\common7\ide\" VSTA.exe /installvstemplates devenv.exe /installvstemplates wenn das nichts hilft: vsta.exe /hostid SSIS_ScriptTask vsta.exe /hostid SSIS_ScriptComponent aberauch das hat bei mir nichts gebracht. Nach einer Neuinstallation des SP1 bekam ich wenigstens einen vernünftige "FilenotFoundexception" während des Debuggens des SSIS Pakets. nach der Aufnahme der DLL in den GAC funktionierte es dann!
%PM, %16. %593 %2011 %13:%Dez

gratis Joomla Templates

allen Joomla Benutzern wohl vertraut, dennoch hier ein Link zu kostenlosen templates, weil ich gar so begeistert bin ;-) http://www.joomlaos.de/joomla_template_galerie.html    
%PM, %09. %665 %2012 %14:%Mai

Entity Framework Insert

Beim Insert in die Datenbank über Entity Framework erscheint folgende Fehlermeldung: EntitySet 'errorlog' kann nicht aktualisiert werden, denn es hat eine DefiningQuery, und im -Element ist kein -Element zur Unterstützung des aktuellen Vorgangs vorhanden. Da diese nicht wirklich aussagekräftig ist poste ich diese mal hier, da das Problem schlciht und einfach ein fehlender Primary-Key in der Tabelle ist. Da ich diesen hier nicht wirklich brauche, da es eine "Standalone" Tabelle ist, löse ich das einfach mit einem auto-increment-uniqidentifier.                   Code-Snippet des Inserts:

Using db As New Entities

Dim errE As New errorlog

errE.benutzer = usrBenutzer.Login

errE.domain = usrBenutzer.Domain

errE.computer = usrBenutzer.Computer

errE.datum = Now

errE.fehlertext = err.Message

errE.quelle = err.Source

errE.stacktrace= err.StackTrace

db.AddToerrorlog(errE)

db.SaveChanges()

End Using

%AM, %12. %484 %2012 %10:%Jul

Entity Framework Fehler

Nachtrag: hier die Fehlermeldung auf Deutsch: Der Wert einer Eigenschaft, die zum Schlüssel eines Objekts gehört, stimmt nicht mit dem entsprechenden Wert der Eigenschaft überein, die im ObjectContext gespeichert ist. The value of a property that is part of an object's key does not match the corresponding property value stored in the ObjectContext. Kein wirklich aussagekräftiger Fehler wenn man die Lösung kennt: EntityFramework verlangt  rigoros PrimaryKeys in jeder Tabelle. (den Fehler könnte man aber auch anders formulieren, zumindest so dass es ein dummer Mensch wie ich versteht). Ich für meinen Teil hab hier jetzt 30 Tabellen in denen ich nicht wirklich einen Primärschlüssel brauche, da es sich um Referenztabellen handelt. Nun gut, ich löse das wie bereits 2 Beiträge weiter unten über einen uniquidentifier der den Standardwert newid() besitzt und trage diese ID als Primärschlüssel in meine Tabellen ein (Fleissarbeit). Aber danach scheint es sauber zu funktionieren. Nachtrag: Ein Scheiss funktioniert, zumindest nicht in Sichten!!! Hierzu gibt es ein Microsoft Ticket leider gibt es keine Fehlerbehebung, lediglich einen Workaround. Das Problem ist, dass EntityFramework alle Felder einer Sicht als EntityKey festlegt, was absoluter Quatsch ist! Dies muss man manuell beheben. Selten so einen Dreck von MS gesehen und glaube nicht, dass das gewollt ist.   Nachtrag: abgesehen davon, dass die Sache an sich ein absolutes Unding ist gibt es eine vermutlich bessere Lösung, ohne das autom. generierte EntityModel (evtl jedesmal) anzupassen. Im View den Feldern die Funktion NULLIF voranstellen, damit anstelle Leerstrings ein NULL übergeben wird, was anscheinend dieses Mysterium verursacht. (Vorsicht ISNULL verursacht natürlich genau das Gegenteil!) http://stackoverflow.com/questions/1013333/entity-framework-and-sql-server-view-question
Da solche Funktionen erst mit EF5 bzw. .NET 4.5 halbwegs vernünftig zur Verfügung stehen ("AsNoTracking") hier eine Möglichkeit um Entitäten zu klonen (als Extension :-))

;
Public Function Clone(Of t As EntityObject)(entity As t, ctx As oraEntities, Optional copyKeys As Boolean = True) As t
Try
Dim cloneE As t = ctx.CreateObject(Of t)()
Dim pis As PropertyInfo() = entity.GetType.GetProperties()

For Each pi As PropertyInfo In pis
Dim attrs As EdmScalarPropertyAttribute() = DirectCast(pi.GetCustomAttributes(GetType(EdmScalarPropertyAttribute), False), EdmScalarPropertyAttribute())

For Each attr As EdmScalarPropertyAttribute In attrs
If Not copyKeys AndAlso attr.EntityKeyProperty Then
Continue For
End If
'Strung und NULL abfangen, wird trotz Standardwert im SQL Server nicht imgesetzt
Dim objVal As Object
If pi.PropertyType = GetType(String) And pi.GetValue(entity, Nothing) Is Nothing Then
objVal = ""
Else
objVal = pi.GetValue(entity, Nothing)
End If
pi.SetValue(cloneE, objVal, Nothing)
Next
Next
Return cloneE
Catch ex As Exception
Throw ex
End Try
End Function


und zu vergleichen


;
Public Function Compare(Of t As EntityObject)(entityOriginal As t, entityCopy As t) As Boolean
Try
'Um Änderungen einer Entität festzustellen (t.equals funktioniert aufgrund der Abhängigkeiten mit anderen Tabellen nicht)
Dim pisOrig As PropertyInfo() = entityOriginal.GetType.GetProperties()

For Each piOrig As PropertyInfo In pisOrig
Dim attrs As EdmScalarPropertyAttribute() = DirectCast(piOrig.GetCustomAttributes(GetType(EdmScalarPropertyAttribute), False), EdmScalarPropertyAttribute())
If attrs.Count > 0 Then 'Fremdschlüsseltabellen ausschliessen
Dim objOrig As Object = If(GetType(t).GetProperty(piOrig.Name).GetValue(entityOriginal, Nothing) Is Nothing, "", GetType(t).GetProperty(piOrig.Name).GetValue(entityOriginal, Nothing))
Dim objCopy As Object = If(GetType(t).GetProperty(piOrig.Name).GetValue(entityCopy, Nothing) Is Nothing, "", GetType(t).GetProperty(piOrig.Name).GetValue(entityCopy, Nothing))
If Not objOrig.Equals(objCopy) Then
Return False
End If
End If
Next

Return True
Catch ex As Exception
Throw ex
End Try
End Function


Verknüfte Tabellen werden dabei allerdings nicht übernommen!			  

oder auf Englisch: New transaction is not allowed because there are other threads running in the session. Szenario: In einer Schleife werden Objekte einer Tabelle verarbeitet und nach erfolreicher verarbeitung als "verarbeitet" markiert. Dabei schlägt der context.savechanges des Enityty Frameworks fehl. der Grund ist sowohl simple als auch, zumindest für mich, anfänglich nicht ganz verständlich, da ich eben an dieser Stelle speichern möchte. Die verwendete EF Connection behält die Änderungen des Objects bei und setzt diese auf "modified", so dass ein einmaliges savechanges genügt um alle Objekte zu speichern. Das Kuriose ist, dass es EF das nicht einmal zulässt, selbst wenn man die schlechtere Performance in Kauf nehmen wollte. Schuld ist die Schleife, die Objekte zur Laufzeit aus dem Context liest und so eine Änderung nicht zulässt...

 Using db as new EF_Context Dim jobs = From w In db.jobs Where Not w.verarbeitet.HasValue For Each job In jobs 'Verarbeitung If verarbeite_job(job) = true then 'abhaken job.verarbeitet = now 'db.savechanges 'SCHLÄGT FEHL!!! else 'loggen endif Next db.SaveChanges 'HIER ISSES RICHTIG End Using 

%AM, %04. %531 %2013 %11:%Jun

Docuware GAPI ClickOnce

Docuware bietet auf seiner Homepage leider nur eine verinfachte Dokumentation. Entweder hat bisher niemand sein Tool welches die Docuware GAPI verwendet per Clickonce zu veröffentlichen oder ich mache etwas falsch. Da ich keine Fehler mache ergänze ich die Docuware Dokumentation für alle die evtl auf das gleiche problem stoßen. HIER beschreibt Docuware zwar wie man mit xcopy (!) in der Debug Umgebung in Visual Studio alles wunderbar zum laufen kriegt. Will man allerdings kein Setup genrieren da man die Vorteile der ClickOnce Bereitstellung nutzen möchte wird man erstmal mit Fehlermeldungen beworfen. Grund hierfür sind fehlende Dateien und das Mysterium, dass das Instanziieren eines neuen DWClients, anders als in der Debug Umgebung, sofort die Settings der settings.datei verwenden will, unabhängig davon, dass man die Einstellungen manuell im Code setzt dwClient = Gapi.Client.Gapi.newClient(False) 'Hier bereits Zugriff auf die Settings -> Fehler dwClient.Options.ASConnectionSettings.Clear() dwClient.Options.ASConnectionSettings.Add(Gapi.Client.Gapi.newConnectionSetting("noname", Stammdaten.docserver, Stammdaten.docport.ToInt, Stammdaten.docorganisation)) Lösung: manuelles hinzufügen benötgiter Dateien. Config und Settings Dateien müssen als externe Datei ins Projekt eingeschlossen werden, fehlende Referenzen als Verweis hinzugefügt werden.
Seite 5 von 6