NET - Software & DotNetNuke (DNN) Blog



      NET - Software & DotNetNuke (DNN) Blog
http://www.dotnetnukeblog.de/

Typ/Viewer: RSS/ RSS-ReaderAktualisiert: 10.02.2012Aufrufe: 758

Kategorie: Computer, Technik > Programmierung & Programmiersprachen

NET Software Entwicklung DotNetNuke Spezialist DNN E-Commerce Business-Develoment Online-Marketing

Nachrichten aus dem RSS-Feed: NET - Software & DotNetNuke (DNN) Blog
DotNetNuke speichern von Zugangsdaten der Benutzer
(Tue, 22 Nov 2011 17:29:45 GMT)  DotNetNuke bietet drei Möglichkeiten die Passwörter von Benutzern zu speichern. Diese können im Klartext, als verschlüsselte Zeichenfolge oder als Hashwert in der Datenbank gespeichert werden. Das die erste Variante höchtens für Test- und Entwicklungsinstallationen in Frage kommt, muss wohl nicht weiter diskutiert werden. Konfiguiert wird die Behandlung von Passwörtern in der web.config direkt bei den Einstellungen des MembershipProvider: <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="SiteSqlServer" enablePasswordRetrieval="true" enablePasswordReset="true" requiresQuestionAndAnswer="false" minRequiredPasswordLength="7" minRequiredNonalphanumericCharacters="0" requiresUniqueEmail="false" passwordFormat="Encrypted" applicationName="DotNetNuke" /> Worin besteht aber der genau Unterschied zwischen veschlüsselt und hashed? Verschlüsselte Zeichenfolgen Bei diesem Modus werden die Passwörter durch einen Verschlüsselungsalgorithmus unleserlich gemacht, so das bei einem Auslesen der Tabelle, die Passwörter nicht im Klartext zur Verfügung stehen. DotNetNuke bzw. jedes DNN-Module ist in der Lage die Passwörter ohne Probleme zu lesen. Hashwerte Wenn man als Modus "Hashed" wählt, dann wird nur ein Hashwert vom Passwort abgespeichert und nicht das eigentliche Passwort. Aus dem Hashwert kann man das Passwort nicht mehr in Klartext umwandeln und somit hat auch kein Module mehr Zugriff auf die Passwörter. Das bedeutet aber auch, dass die "Passwort zusenden"-Funktion nicht mehr das Passwort dem Benutzer zur Verfügung stellen kann. Ob das eine Anwendung überhaupt machen sollte ist eine ganz andere Diskussion. Die Funktion "Passwort vergessen" funktioniert aber natürlich trotzdem, in diesem Modus wird von DotNetNuke einfach ein neues Zufallspasswort erzeugt. Welche Variante Es gibt keine klare Empfehlung für eine der verfügbaren Methode. Für die Auswahl sollten im Vorfeld Überlegungen angestellt werden, ob man das Passwort wirklich jemals im Klartext benötigt. Aus der Perspektive eines Datenschützers wäre eigentlich nur die Möglichkeit "als Hashwert" akzeptable.
DotNetNuke Performance Optimierung
(Thu, 17 Nov 2011 11:11:25 GMT)  Die Performance einer Webseite ist heute aus vielen Gründen - die hier nicht weiter aufgeführt werden müssen - wichtig. DotNetNuke selber bietet eine Vielzahl von Einstellungen, die direkten Einfluss auf die Performance der Webseite haben können. Es gibt auf Codeplex ein Projekt, dass durch ein paar SQL Scripts die Einstellungen einer DotNetNuke Installation so modifiziert, das eine maximale Performance möglich ist. Natürlich muss man im Einzelfall über manche Einstellung extra entscheiden aber als Startpunkt für eine Optimierung finde ich das sehr gelungen. Das Projekt findet man unter http://dnnperformance.codeplex.com
Die web.config bei der Installation eines Modules verändern
(Thu, 27 Oct 2011 17:04:00 GMT)  Je nach Modul gibt es schon mal die Anforderung, dass neue Einträge in die web.config geschrieben werden müssen. Dieses kann man entweder im SourceCode erledigen oder aber die Änderungen in dem DNN Modul Manifest / Definitionsdatei (meinmodule.dnn) definieren. Verfügbar ist das ab der Version 5 von DotNetNuke. Um das zu nutzen, muss man in der Manifest-Datei folgendes hinzufügen: <component type="Config"> <config> <configFile>web.config</configFile> <install> <configuration> <nodes> ..... </nodes> </configuration> </install> <uninstall> <configuration> <nodes /> </configuration> </uninstall> </config> </component>Wie man sieht gibt es zwei Bereiche. Der Bereich <install> wird während der Installation und der Bereich <uninstall> wird be der Deinstallation von dem DNN Modul ausgeführt. Innerhalb des Tags <nodes> können dann die entsprechenden Einträge hinzugefügt werden. Hier ein Beispiel womit ein HttpHandler hinzugefügt wird: <node path="/configuration/system.web/httpHandlers" action="update" key="path" collision="overwrite"> <add verb="*" path="myhandler.axd" validate="false" type="DNN.Module.Shop.MyHandler, DNN.Module.Shop" /> </node> Weiter Informationen findet man im Wiki auf www.dotnetnuke.com
Conditional Stylesheets oder CSS hacks
(Wed, 19 Oct 2011 13:43:52 GMT)  Jeder der sich schon mal mit dem Thema Webdesign beschäftigt hat, kennt die Probleme der unterschiedlichen Browser. Besonders der Internet Explorer ist ein Kandidat, bei dem man sehr schnell graue Haare bekommt kann. Meistens werden Hacks verwendet, die nur von bestimmten Versionen / Browsern erkannt bzw. akzeptiert werden und von den anderen als Fehler ignoriert. Das Problem von solchen Hacks ist unter anderem dafür sorgen das eine CSS nicht mehr validiert werden kann. Um dieses Problem zu umgehen verwenden viele Conditional Stylesheets, die dann vom jeweiligen Browser erkannt und geladen werden. Das sieht dann so aus: <link rel="stylesheet" type="text/css" media="screen" href="skin/css/style.css" /> <!--[if IE 7]><link rel="stylesheet" type="text/css" media="screen" href="skin/css/ie7.css" />< ![endif]--> <!--[if IE 6]><link rel="stylesheet" type="text/css" media="screen" href="skin/css/ie6.css" />< ![endif]-->Nun kann man für die verschiedenen Browser(versionen) die entsprecheden CSS-Definitionen sauber überschreiben. Ist doch super oder? Diese Variante ist schon deutlich besser als die Verwendung von Hacks im eigentlichen CSS aber hat den großen Nachteil das noch mehr Dateien vom Server geladen werden müssen. Eine deutlich besser Lösung sieht so aus: <!--[if lt IE 7 ]> <html class="ie6"> <![endif]--> <!--[if IE 7 ]> <html class="ie7"> <![endif]--> <!--[if IE 8 ]> <html class="ie8"> <![endif]--> <!--[if IE 9 ]> <html class="ie9"> <![endif]--> <!--[if (gt IE 9)|!(IE)]><!--> <html class=""> <!--<![endif]-->Hier wird nun in Abhängigkeit von der Browserversion das Tag HTML mit einer CSS-Klasse versehen und man kann nun ganz sauber und ohne Hacks für die div. Versionen CSS-Definitionen erstellen, dass dann z.B. so aussieht:: div.contentpane { width: 510px; } .ie6 div.contentpane { width: 500px; } Diese Technik wird z.B. auch vom bekannten http://html5boilerplate.com/ verwendet.
URI schema constant
(Thu, 04 Aug 2011 08:38:59 GMT)  Immer wiedermal muss man in seinem Code überprüfen welches Schema die URI (URL) besitzt. Daher sieht man oft solche Codezeilen:if (httpRequest.Uri.Scheme == "https")Ich bin absolut kein Freund von solchen Abfragen, die auf einen String-Wert vergleichen, den man selber schreiben muss. Das ist einfach viel zu Fehleranfällig und verleitet auch durch Copy & Paste und zu schnelles Tippen einfach Fehler zu machen... die Abfrage ist ja auch wirklich zu einfach um länger drüber nachzudenken. Dabei kann man sich das Leben auch einfacher machen und zumindest in meinen Augen auch den Code richtig schreiben durch die Verwendung einer Konstanten aus dem .NET Framework. Die Klasse URI besitzt nämlich schon bereits diese Konstanten! Der Code von oben sieht dann plötzlich wie folgt aus: if (httpRequest.Uri.Scheme == Uri.UriSchemeHttps)Hier einen Auszug der vordefinierten Werte: UriSchemeFtp: URI für FTP (File Transfer Protocol). UriSchemeHttp: URI für HTTP (Hypertext Transfer Protocol) UriSchemeHttps: URI für HTTPS (Secure Hypertext Transfer Protocol). UriSchemeMailto: Gibt an, dass der URI eine E-Mail-Adresse ist und der Zugriff über SMTP (Simple Mail Transport Protocol) erfolgt. UriSchemeNetPipe: Gibt an, dass auf den URI über das von Windows Communication Foundation (WCF) verwendete NetPipe-Schema zugegriffen wird. UriSchemeNetTcp: Gibt an, dass auf den URI über das von Windows Communication Foundation (WCF) verwendete NetTcp-Schema zugegriffen wird. UriSchemeNntp: URI für eine Internetnewsgroup, auf die über NNTP (Network News Transport Protocol) zugegriffen wird Details gibt es hier.
ASP 0131 Unzulaessiger Pfad zum uebergeordneten Verzeichnis
(Sun, 31 Jul 2011 12:12:56 GMT)  Bei dem Versuch eine alte ASP (classic asp) Anwendung auf einem Windows 2008 R2 System und damit auf einem IIS 7.5 funktionsfähig zu bekommen bestand das Problem das die Seite immer nur einen HTTP Errorcode 500 zurück gibt. Einen Blick in die Logs von IIS ergab die Fehlermeldung: "|23|ASP_0131|Unzulässiger_Pfad_zum_übergeordneten_Verzeichnis" Ursache dieses Problems ist das Standardmäßig der übergeordneten ASP-Pfade für eine Website oder Anwendung bei gleichzeitiger Verwendung relativer übergeordneter Pfade in einer Include-Anweisung nicht erlaubt / deaktiviert ist. Empfohl ist die Einbindungen von <!--#include file="../dbconn.inc"--> auf <!--#include virtual="/<virtual path>/dbconn.inc"--> zu verändern. Alternativ kann man aber auch den Internet Information Server so einstellen, dass die übergeordneten ASP-Pfade erlaubt sind. Dafür muss man beim IIS auf das entsprechende Web klicken und in der rechten Seite unter ASP die Konfiguration öffnen. Dort gibt es dann die Option "Übergeordnete Pfade aktivieren" der Wert muss von False auf True umgestellt werden.
Microsoft SQL Server Error: 15138 drop user account
(Wed, 22 Jun 2011 22:16:40 GMT)  Gerade habe ich eine ältere Sicherung in den Mircosoft SQL Express 2008 eingespielt. Dabei wollte ich ein wenig aufräumen und die nicht benötigten Benutzerkonten löschen. Jedoch habe ich bei dem Versuch immer die Fehlermeldung "The database principal owns a schema in the database, and cannot be dropped. (Microsoft SQL Server, Error: 15138)." bekommen. Die Lösung für dieses Problem ist recht einfach: Wenn für den Benutzeraccount ein Schema angelegt wurde, muss zunächst das Schema aus der SQL Server Datenbank entfernt werden. Um zu überprüfen, ob es ein Schema für den Benutzer gibt, kann man mit dem SQL Server Manager bei der entsprechenden Datenbank unter Sicherheit => Schema nachschauen. Wenn kein Schema mehr von diesem Benutzer existiert, lässt sich auch das Benutzerkonto ohne Fehlermeldung löschen.
API REST Html-Helppage display Json requestsample
(Tue, 15 Mar 2011 10:13:49 GMT)   Für mein aktuelles API Projekt erstelle ich eigene Helppages auf denen ich auch Requestbeispiele für Xml und Json anzeige. Die Erstellung eines Request-Beispiel wird durch Xsd erstellt und das resultierende Xml wird dann durch Json.NET in Json konvertiert. Der Aufruf dazu sah wie folgt aus: var jsonSample = JsonConvert.SerializeXNode(xmlSampelRequest); Als Ergebnis wurde auch Json ausgebeben, leider aber ohne Zeilenumbrüche, was die Darstellung und Lesbarkeit doch stark reduziert. Damit der Json-String auch "vernüftig" formatiert wird, kann man bei der Serializierung noch einen Parameter setzen und damit die Formatierung erzwingen: Formatting.Indented Der Aufruf sieht dann wie folgt aus: var jsonSample = JsonConvert.SerializeXNode(xmlSampelRequest, Newtonsoft.Json.Formatting.Indented);
Automapper custom TypeConverter Exceptionhandling
(Fri, 11 Mar 2011 12:44:49 GMT)  In einem Projekt verwende ich aktuell die Komponente AutoMapper (automapper.codeplex.com), im zwischen den externen Datacontracts und den internen Entities zu mappen. Teilweise habe ich dafür auch eigenen TypeConverter entwickelt. Wenn man in diesem TypeConverter eine eigene Exception auslöst, dann erhält man beim aufrufenden Code immer eine AutoMapperMappingException. Da ich in dem Projekt ein globales ErrorHandling habe (WCF bzw. Implementierung vom IErrorHandler), möchte ich aber die konkrete Exception gerne aus dem TypeConverter in mein Errorhandling weitergeben. Damit das funktioniert baut man sich am besten einen Wrapper für den Aufruf vom Automapper, um dort zu entscheiden, welche Exception man weitergeben möchte. Die eigene Exception wird als InnerException vom AutoMapperMappingException mitgeliefiert. Durch überprüfung der InnerException kann man als feststellen, wie die aktuelle Exception zu bahandeln ist. Hier ein Beispiel: public class AutoMapperWrapper { public static U Map<T, U>( T source) { try { return Mapper.Map<T, U>(source); } catch (Exception e) { while (e is AutoMapperMappingException) e = e.InnerException; if (e == null) throw; else throw e; } } }
WCF OperationContract nicht optionale Prameter im Wsdl
(Wed, 02 Mar 2011 13:53:16 GMT)  Wenn man mit der WCF einen Service definiert und dabei Nachrichtenbasiert kommunizieren möchte, sieht kann die Definition z.B. so aussehen: [ServiceContract(Namespace = APICommon.DefaultSOAPNameSpace)] public interface ICartSoapService { [OperationContract] ProcessCartResponse ProcessCart(ProcessCartRequest request); } [DataContract] public class ProcessCartRequest { [DataMember(IsRequired = true)] public Cart Cart { get; set; } } [DataContract] public class ProcessCartResponse : BaseResponseMessage { [DataMember(IsRequired = true)] public ProcessResultType ProcessResult { get; set; } }Die WCF erzeugt auch brav eine passendes Wsdl Datei für diese Beschreibung. Allerdings hat die "Standardausgabe" der WCF datei den Nachteil, das der Parameter "request" der Methode ProcessCart immer optionaler Parameter ist bzw. in der Wsdl Datei wird das Element mit den Attribute minOccurs="0" gekennezichnet. Da ohne den Parameter die Methode aber nicht vernüftig abgearbeitet werden kann, müsste im Wsdl eigentlich ein minOccurs="1" stehen ...also kein optionaler Parameter. Leider gibt es bei den Standardattributen der WCF keine Möglichkeit, diese Verhalten oder viel mehr die Wsdl-Generierung zu beinflussen. Trotzdem kann man durch ein eigenes Attribute das gewünschte Verhalten sehr schnell der WCF beibringen. Dafür muss man lediglich ein Attribute anlegen und die Interfaces IContractBehavior + IWsdlExportExtension mit hinzufügen. Die vollständige Implementierung sieht so aus: [AttributeUsage(AttributeTargets.Interface)] public class OperationsParametersAreRequiredAttribute : Attribute, IContractBehavior, IWsdlExportExtension { private List<RequiredOperationParameter> _requiredOperationParameters; public void AddBindingParameters( ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) { } public void ApplyClientBehavior( ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime) { } public void ApplyDispatchBehavior( ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.DispatchRuntime dispatchRuntime) { } public void ExportContract( WsdlExporter exporter, WsdlContractConversionContext context) { if (_requiredOperationParameters == null) _requiredOperationParameters = new List<RequiredOperationParameter>(); foreach (var operation in context.Contract.Operations) { var requestMessage = operation.Messages.Where(m => m.Direction == MessageDirection.Input).FirstOrDefault(); var parameters = operation.SyncMethod.GetParameters(); Debug.Assert(parameters.Length == requestMessage.Body.Parts.Count); for (var iLoop = 0; iLoop < parameters.Length; iLoop++) { var attributes = parameters[iLoop].GetCustomAttributes( typeof(OperationParameterIsOptionalAttribute), false); if (attributes.Length == 0) { _requiredOperationParameters.Add(new RequiredOperationParameter { Namespace = requestMessage.Body.Parts[iLoop].Namespace, Name = requestMessage.Body.Parts[iLoop].Name, Message = operation.Name }); } } } } public void ExportEndpoint( WsdlExporter exporter, WsdlEndpointConversionContext context) { foreach (var requiredParamter in _requiredOperationParameters) { var schemas = exporter.GeneratedXmlSchemas.Schemas(requiredParamter.Namespace); foreach (XmlSchema schema in schemas) { var message = schema.Elements[requiredParamter.XmlName] as XmlSchemaElement; var complexType = message.ElementSchemaType as XmlSchemaComplexType; var sequence = complexType.Particle as XmlSchemaSequence; foreach (XmlSchemaElement schemaElement in sequence.Items) { if (schemaElement.Name == requiredParamter.Name) { schemaElement.MinOccurs = 1; schemaElement.MinOccursString = "1"; break; } } } } _requiredOperationParameters.Clear(); } public void Validate( ContractDescription contractDescription, ServiceEndpoint endpoint) { } internal class RequiredOperationParameter { public string Message { get; set; } public string Name { get; set; } public string Namespace { get;set;} public XmlQualifiedName XmlName { get { return new XmlQualifiedName(Message, Namespace); } } } }
WCF REST Could not load file or assembly 'System.ServiceModel.Activation'
(Wed, 19 Jan 2011 10:44:55 GMT)  Bei dem Versuch HTTP Basic Auth für einen REST Dienst zu implementieren (der wiederrum durch Konfiguration per serviceActivations in der .config und eigenere factory gestartet wird) bekam ich die Fehlermeldung bei der Umstellung vom Attribute aspNetCompatibilityEnabled von "false" auf "true" das die Assembly 'System.ServiceModel.Activation' nicht gefunden werden konnte. Hier die genaue Fehlermeldung: System.IO.FileNotFoundException: Could not load file or assembly 'System.ServiceModel.Activation' or one of its dependencies. The system cannot find the file specified. File name: 'System.ServiceModel.Activation' at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMarkHandle stackMark, Boolean loadTypeFromPartialName, ObjectHandleOnStack type) at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark, Boolean loadTypeFromPartialName) at System.Type.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase) at System.Web.Compilation.BuildManager.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase) at System.Web.Configuration.HandlerFactoryCache.GetTypeWithAssert(String type) at System.Web.Configuration.HandlerFactoryCache.GetHandlerType(String type) at System.Web.Configuration.HandlerFactoryCache..ctor(String type) at System.Web.HttpApplication.GetFactory(String type) at System.Web.HttpApplication.MaterializeHandlerExecutionStep.System.Web. HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) === Pre-bind state information === LOG: User = user LOG: DisplayName = System.ServiceModel.Activation (Partial) WRN: Partial binding information was supplied for an assembly: WRN: Assembly Name: System.ServiceModel.Activation | Domain ID: 2 WRN: A partial bind occurs when only part of the assembly display name is provided. WRN: This might result in the binder loading an incorrect assembly. WRN: It is recommended to provide a fully specified textual identity for the assembly, WRN: that consists of the simple name, version, culture, and public key token. WRN: See whitepaper http://go.microsoft.com/fwlink/?LinkId=109270 for more information and common solutions to this issue. LOG: Appbase = file:///xxxxx/ LOG: Initial PrivatePath xxxx\bin Calling assembly : (Unknown). === LOG: This bind starts in default load context. LOG: Using application configuration file: xxxx\web.config LOG: Using host configuration file: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet.config LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config. LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind). LOG: Attempting download of new URL file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/Temporary ASP.NET Files/root/3d7bd35f/452e5631/System.ServiceModel.Activation.DLL. LOG: Attempting download of new URL file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/Temporary ASP.NET Files/root/3d7bd35f/452e5631/System.ServiceModel.Activation/System.ServiceModel.Activation.DLL. LOG: Attempting download of new URL file:///xxxx/bin/System.ServiceModel.Activation.DLL. LOG: Attempting download of new URL file:///Dxxxx/bin/System.ServiceModel.Activation/System.ServiceModel.Activation.DLL. LOG: Attempting download of new URL file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/Temporary ASP.NET Files/root/3d7bd35f/452e5631/System.ServiceModel.Activation.EXE. LOG: Attempting download of new URL file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/Temporary ASP.NET Files/root/3d7bd35f/452e5631/System.ServiceModel.Activation/System.ServiceModel.Activation.EXE. LOG: Attempting download of new URL file:///xxxx/bin/System.ServiceModel.Activation.EXE. LOG: Attempting download of new URL file:///xxxxx/bin/System.ServiceModel.Activation/System.ServiceModel.Activation.EXE. - Thread: 15 Das Problem liegt an einem Eintrag in der web.config, denn dort hatte ich unter system.webserver -> handlers folgenden Eintrag hinzugefügt: <add name="svc" path="*.svc" verb="*" type=" System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel.Activation"/>Nach dem Ändern bzw. Ergänzen diesers Eintrages: <add name="svc" path="*.svc" verb="*" type=" System.ServiceModel.Activation.ServiceHttpHandlerFactory,System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" />Funktioniert auch wieder die Aktivierung vom WCF basierten REST Service.
WCF Http API REST XML Custom ErrorHandler
(Fri, 07 Jan 2011 13:59:38 GMT)  Im Augenblick entwickel ich eine Architektur für eine WEB-API basierend auf der WCF. Als Grundlage habe ich das WCF Http Projekt (das auf Codeplex zu finde ist) genommen. Mir gefällt dort insbesondere der Ansatz der MediaTypeProcessor, womit sich die Request- und Response-Formate sehr schön beeinflussen lassen. Ein wichtier Aspekt bei jeder Architektur ist das Thema Exceptionhandling. Leider gibt es für das oben genannte Projekt noch keinen eigenen Exceptionhandler, der auch die MediaTypeProcessors nutzt, um eine Exception im angeforderten Format zurück zu geben. Das kann z.B. XML, Json aber theoretisch auch ein Bild oder Wav Dateien sein. Daher habe ich heute mal einen Exceptionhandler geschrieben, der mit dem Projekt zusammenarbeitet. Als Basis wird hierbei natürlich das Interface der WCF IErrorHandler genutzt und eine generelle Basisimplementierung aus dem Projekt. Ich bin noch nicht 100% glücklich mit der Lösung aber im Augenblick funktioniert das so ganz gut. Werde die Implementierung auch auf Codeplex posten und hoffe dort vielleicht weitern Input zu finden. Aber auch per E-Mail freue ich mich über konstruktive Beiträge! Here we go: public class RESTMessageErrorHandler : HttpMessageErrorHandler, IErrorHandler { // Public Methods #region HandleError public override bool HandleError( Exception error) { Logging.Error("API Exception", error); return true; } #endregion // Protected Methods #region ProvideResponse protected override void ProvideResponse( Exception exception, Microsoft.Http.HttpResponseMessage response) { APIBaseException apiException = null; if (exception is APIBaseException) apiException = exception as APIBaseException; else apiException = new APIBaseException(System.Net.HttpStatusCode.InternalServerError, "An error has occured processing your request."); var supportedMediaTypes = new List<string>(); var httpMessageProperty = OperationContext.Current. IncomingMessageProperties[HttpMessageProperty.Name] as HttpMessageProperty; var httpRequest = httpMessageProperty.Request as HttpRequestMessage; var contentType = httpRequest.Headers.ContentType; var uriMatch = httpRequest.Properties.First( p => p.GetType() == typeof(UriTemplateMatch)) as UriTemplateMatch; var endpoint = OperationContext.Current.Host.Description.Endpoints.Find( OperationContext.Current.EndpointDispatcher.EndpointAddress.Uri); var dispatchOperation = OperationContext.Current.EndpointDispatcher.DispatchRuntime. Operations.Where(op => op.Name == uriMatch.Data).First(); var operationDescription = endpoint.Contract.Operations.Find(dispatchOperation.Name); //get the contenttype of the request var httpBehavoir = endpoint.Behaviors.Find<HttpEndpointBehavior>(); var processors = httpBehavoir.GetResponseProcessors( operationDescription.ToHttpOperationDescription()).ToList<Processor>(); //Fallback for empty contenttype if (string.IsNullOrEmpty(contentType)) { foreach (var processor in processors) { var mediaTypeProcessor = processor as MediaTypeProcessor; if (mediaTypeProcessor == null) continue; supportedMediaTypes.AddRange(mediaTypeProcessor.SupportedMediaTypes); } contentType = ContentNegotiationHelper.GetBestMatch(httpRequest.Headers.Accept.ToString(), supportedMediaTypes).MediaType; if (string.IsNullOrEmpty(contentType)) contentType = "text/plain"; } //set http-header and status code response.Headers.ContentType = contentType; response.StatusCode = apiException.Status; //search processor for the output-serialization foreach (var processor in processors) { var mediaTypeProcessor = processor as MediaTypeProcessor; if (mediaTypeProcessor == null) continue; if (mediaTypeProcessor.SupportedMediaTypes.Contains<string>(contentType)) { response.Content = HttpContent.Create(s => mediaTypeProcessor. WriteToStream(new APIExceptionContract(apiException), s, httpRequest)); break; } } //if no processor found use plain text if (response.Content == null) response.Content = HttpContent.Create(apiException.Description); } #endregion }
HttpRequestValidationException 0x80004005 A potentially dangerous Request.Form value was detected from the client
(Fri, 07 Jan 2011 08:44:20 GMT)  Bei der Umstellung eines ASP.NET Projektes auf das Framework 4.0 wurde bei bestimmten Eingabedaten immer der Fehler geworfen: System.Web.HttpRequestValidationException (0x80004005): A potentially dangerous Request.Form value was detected from the client (_dataTextBox="...bitkarte (<print template="pay..."). at System.Web.HttpRequest.ValidateString(String value, String collectionKey, RequestValidationSource requestCollection) at System.Web.HttpRequest.ValidateNameValueCollection(NameValueCollection nvc, RequestValidationSource requestCollection) at System.Web.HttpRequest.get_Form() Dieses konnte man unter ASP.NET 2.0 durch ein @pagedirektive unterdrücken bzw. die Filterung ausschalten. Bei ASP.NET 4.0 ist dieses per @pagedirektive aber nicht mehr per Default möglich, es gibt aber die Möglichkeit die RequestValidierung per Eintrag in die web.config wieder in den Modus "ASP.NET 2.0" zu versetzen, damit das Verhalten gleich bleibt. Dafür ergänzt man die web.config wie folgt: <httpRuntime requestValidationMode="2.0" /> Weiter Informationen gibt es in der MSDN.
HTTP Error 404.11 IIS7 verarbeitet keine URLs mit +
(Wed, 05 Jan 2011 17:17:50 GMT)  Bei dem IIS 7.5 hatte ich gerade das Problem, dass eine Url die Whitespaces als "+" codiert (auch wenn es nichht optimal ist aber leider nicht zu ändern aktuell) immer mit dem Fehler http Statuscode 404.11 und der Nachricht The request filtering module is configured to deny a request that contains a double escape sequence. beendet wurde. Der Grund für die Ablenhung der Url ist, dass "+" als ein gefährliches Zeichen eingestuft wird. Hierbei handelt es sich also um eine Sicherheitseinstellung. Wenn man nun solche Urls aber weiter verarbeiten möchte, dann kann man diesen Requestfilter einfach deaktivieren über folgenden Aufruf: %windir%System32\inetsrv>appcmd set config -section:system.webServer/security/requestfiltering -allowDoubleEscaping:true Weitere Informationen zum RequestFiltering gibt es auch hier IIS Security RequestFiltering.
Install ASP.NET 1.1 with IIS7 on Windows 2008
(Tue, 04 Jan 2011 12:54:47 GMT)  In einer Evaluierungsphase habe ich gerade mal probiert eine alte ASP.Net 1.1 Anwendung auf einem Windows Server 2008 zu installieren. Per Default wird allerdings ASP.NET 1.1 nicht mehr auf einem Windows 2008 Server unterstützt, so das ein wenig manuelle Arbeit notwendig ist. Als erstes muss man die "IIS Metabase Compatibility" installieren und das geht durch die Schritte: "Start" -> "Server Manager" -> "Manage Roles" -> "Web Server (IIS)" -> "Add Role Services". Der zweite Schritt ist die Installation vom .Net Framework 1.1. Hier die Downloadlinks: .NET Framework Version 1.1 Redistributable Package .NET Framework Version 1.1 Service Pack 1 ASP.NET Security Update for .NET Framework 1.1 SP1 Wenn man das Setup ausführt, dann bekommt man vom Windows Server 2008 den Hinweis das es möglicherweise Kompatibilitätsprobleme geben könnte. Diese Meldung einfach mit "Ausführen" / "run programm" überspringen. Anschließend muss das alte .Net Framework noch im IIS registriert werden. Dafür kann man folgenden Behfel ausführen: %windir%\Microsoft.NET\Framework\v1.1.4322\aspnet_regiis -enable Ein Änderung in der machine.config (unter %windir%\Microsoft.NET\Framework\v1.1.4322\config\machine.config) muss noch gemacht werden. Vor dem schließenden Tag </configSection> muss folgendes hinzhugefügt werden: <section name="system.webServer" type="System.Configuration.IgnoreSectionHandler, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> Einen neue ApplicationPool - der unter .Net 1.1 läuft - kann man nun mit folgendem Befehl anlegen: %windir%\system32\inetsrv\appcmd add apppool /name:"Pool1-1" /managedRuntimeVersion:"v1.1" Bei einem 64bit Betriebsystem muss man nun noch ein Verzeichnis erstellen: md %windir%\Microsoft.net\Framework64\v1.1.4322\config und copy %windir%\Microsoft.net\Framework\v1.1.4322\Config\machine.config %windir%\Microsoft.net\Framework64\v1.1.4322\config\machine.config
IIS Manager Error: The process cannot access the file because it is being used by another process. (Exception from HRESULT: 0×80070020)
(Thu, 30 Dec 2010 10:31:54 GMT)  Heute habe ich versucht bei mir lokal ein SSL Zertifikat zu installieren. So etwas habe ich nicht zum ersten mal gemacht aber heute wollte es einfach nicht funktionieren. Immer wenn ich den IIS entsprechend konfiguriert hatte (Zertifikat importiert, Binding bzw. Hostheader erstellt, etc.) kam beim Versuch den IIS zu starten immer die Meldung: IIS Manager Error: The process cannot access the file because it is being used by another process. (Exception from HRESULT: 0×80070020) Nach der Analyse habe ich dann festgestellt, dass ein Prozess bereits den Port 443 nutzt und daher der IIS mit einem https-Binding natürlich nicht mehr richtig starten konnte. Herausfinden welcher Port aktuell genutzt wird kann man im übrigen über "netstart -ano" im Cmd-Prompt. Der Befehl "Tasklist" hat mir dann den notwendigen Hinweis gegeben. Skype ist der "Bösewicht" der den Port 443 nutzt. Dieses kann man aber per Konfiguration ausschalten. Danach funktioniert auch der Start vom IIS mit einem htts-Binding
WCF URL Rewriting entfernen der Endung "svc"
(Tue, 26 Oct 2010 12:21:09 GMT)  Bei dem Standardverhalten, wenn ein WCF Service über den IIS veröffentlicht wird ist, dass der Endpunkt die Datei von Service ist mit der Dateiendung ".svc". Dieses sieht aber - gerade im Bezug auf ein REST-basiertes System nicht besonders elegant aus. Bei dem Einsatz von IIS 7.0 ist es sehr einfach die Dateiendung zu entfernen, ohne dabei viel Code zu schreiben. Für das URL Rewriting gibt eine Erweiterung, die man dem IIS 7.0 hinzufügen kann. Dadurch ist es sehr schön möglich z.B. über Regular Expressions ein URL Rewriting durchzuführen. Nach der Installation dieser Erweiterung muss nur noch folgende Regel definiert werden: 1. Name: Entfernen der Dateiendung svc 2. Request URL: Matches the pattern 3. Using: Regular Expressions 4. Pattern: ^([0-9a-zA-Z\-]+)/([0-9a-zA-Z\-\.\/\(\)]+) 5. Ignore Cases: true 6. Action Type: Rewrite 7. Rewrite URL: {R:1}.svc/{R:2} 8. Append Querystring: true Fertig ;-) Per Eintrag in der web.config sieht das dann alternativ so aus: <system.webServer> <modules runAllManagedModulesForAllRequests="true" /> <rewrite> <rules> <rule name="Remove Svc Extension"> <match url="^([0-9a-zA-Z\-]+)/([0-9a-zA-Z\-\.\/\(\)]+)" /> <action type="Rewrite" url="{R:1}.svc/{R:2}" /> </rule> </rules> </rewrite> </system.webServer>
WCF WSDL replace http://tempuri.org
(Tue, 26 Oct 2010 09:48:45 GMT)  Jeder Webservice sollte einen eindeutigen Namespace verwenden, um im Web auf jeden Fall eindeutig zu sein. Als Standardnamespace wird von ASP.NET Webservices (und auch von der WCF) folgender Namespace verwendet: http://tempuri.org Dieses sollte als erstes modifiziert werden, damit man erst gar nicht mit einem solchen Namespace online geht. Das Problem bei der WCF ist nun leider, dass der Namespace an drei verschiedenen Stellen angegeben werden muss, damit auch im WSDL der gewünschte Namespace durchgängig verwendet wird. Als erstes muss man dem Namespace beim der Servicebeschreibung dem [ServiceContract] angeben: [ServiceContract(Namespace = "http://dotnetnukeblog.de")] public interface IPostService Die zweite Stelle ist bei der Serviceimplementierung: [ServiceBehavior(Namespace = "http://dotnetnukeblog.de")] class PostService : IPostService Die letzte Stelle ist bei der Konfiguration des Endpoints mit dem Attribute bindingNamespace: <endpoint binding="basicHttpBinding" bindingNamespace="http://dotnetnukeblog.de".... Erst wenn an allen drei Stellen der Namespace gesetzt wurde, wird dieser auch durchgängig bei der WSDL Erzeugung genutzt.
WCF, IIS and 404.3 Errors
(Wed, 20 Oct 2010 13:21:55 GMT)  Nachdem ich an einem jungfräulichen Rechner sitze und gerade einen WCF Service debuggen wolte, bekam ich ständig vom IIS den Fehlercode 404.3. Schnell habe ich herausgefunden das die verwendete Endung ".svc" nicht einem Handler zugeordnet ist. Um dieses aber nicht manuel machen zu müssen gibt es bei der WCF ein Tool, dass die Registrierung übernimmt. Das Tool findet man unter %Windows%\Microsoft.Net\Framework\v3.0\Windows Communication Foundation\ und heißt ServiceModelReg.exe. Das muss mit dem Parameter "-i" aufgerufen werden und anschließend funktioniert auch das Hosting im IIS.
asp.net viewstate analyzer
(Tue, 28 Sep 2010 12:53:12 GMT)  Es gibt immer wieder mal Fälle, wo man sich gerne den von ASP.NET erzeugten Viewstate anschauen möchte, um zu sehen, welche Kompontenten dort etwas reinschreiben, zur Optimierung, etc. Für das Pflichttool (zumindest für Webentwickler) Fiddler gibt es genau für diese Aufgabe eine sehr schöne Erweiterung: Den ASP.NET ViewState Helper Damit kann man sich den decodierten Viewstate innerhalb vom Fiddler anschauen und sehr schön erkennen, was dort zum Client übertragen wurde. Diese Erweiterung ist kostefrei und sehr einfach zu installieren. Dafür muss man lediglich die Software runterladen und anschließend die Datei in das Unterverzeichnis "Inspectors" kopieren. Schon hat man nach dem nächsten Start von Fiddler einen neuen Tab-Reiter mit dem decodierten Viewstate.
Internet Explorer zeigt eine leere Seite / IE blank page
(Thu, 23 Sep 2010 18:05:00 GMT)  Beim Testen eines Redesign hatte ich das Problem das die neue Seite in allen Browsern angezeigt wurde, nur nicht im Internet-Explorer (auf jeden Fall im IE 7 und 8). Im IE sah ich eine leere Seite / blank page. Durch den Einsatz vom vom HTTP Debugging Tool Fiddler konnte ich aber sehen das der komplette Inhalt zum Browser übertragen wurde, habe ich mir den Quellcode anzeigen lassen, war auch alles in Ordnung. Allerdings zeigten mir die Entwicklertools - genau wie der Browser selber - auch kein Ergebnis an. Nachdem ich mir dann den Quellcode etwas näher angeschaut habe, musste ich festestellen, dass der Code unsauber war. Im Head-Bereich habe ich das Standard-Tag title verwendet aber leider sah das so aus: <title>Meine tolle Seite<title> Das Tag wurde leider nicht geschlossen. Das scheint dem IE überhaupt nicht zu schmecken und verursacht, dass die Seite komplett nicht angezeigt wird. Nachdem ich den Fehler behoben habe und das title-Tag ordnungsgemäß geschlossen hatte, wurde auch die Seite endlich im IE angezeigt.
jQuery autocomplete und aufruf eines asmx webservice per get
(Wed, 22 Sep 2010 17:42:49 GMT)  Beschäftige mich aktuell intensiver mit dem System Umbraco. Dabei versuch ich einen Datentyp für die Administration zu entwicklen, der per AJAX Daten aus einer Datenbank lädt. Ein Datentyp in Umbraco ist z.B. ein Textfeld, Checkbox oder ähnliches um im Adminbereich das System mit Inhalten zu befüllen. Bei meiner Suche bin ich dann auf ein jQuery-Plugin namens autocomplete aufmerksam geworden. Damit kann man eine Textbox via JavaScript mit einer autocomplete-Funktion erweitern. Da ich die Daten aber nicht per JSON direkt mit zum Client übertragen wollte, habe ich dafür einen asmx-Webservice geschrieben. Die Einbindung via jQuery ist denkbar einfach und sieht in C# z.B. so aus: private void _BuildAutoCompletedScript() { StringBuilder clientScript = new StringBuilder(); clientScript.Append(" <script type='text/javascript'>"); clientScript.Append(" $(document).ready(function() { "); clientScript.AppendFormat(" $(\"#{0}\").autocomplete( ", this.autoCompleteTextbox.ClientID); clientScript.Append(" \"/umbraco/webservices/api/mywebserive.asmx/mymethod\", "); clientScript.Append(" { delay:10, minChars:2, matchContains:1, cacheLength:10, autoFill:true } "); clientScript.Append(" ); "); clientScript.Append(" }); "); clientScript.Append(" </script>"); this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), this.ClientID + "_autocompleteData", clientScript.ToString()); this.Page.ClientScript.RegisterClientScriptInclude("jquery.autocomplete", "/umbraco_client/Application/JQuery/jquery.autocomplete.js");Auf der Serverseite wird dann eine Web-Servicemethode definiert: [WebService(Namespace = "uri:umbraco-irgendwas")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [System.Web.Script.Services.ScriptService] public class mywebservice : System.Web.Services.WebService { [WebMethod] public string mymethod(string q, int limit) { return "Hello World" + q; } }Die Parameter q und limit wird vom Plugin automatisch beim Aufruf als Parameter übergeben. Dabei ist q der Inhalt aus dem Textfeld und limit ist die maximale Anzahl an Datensätzen, die zurück geliefert werden sollen. So weit so einfach, doch leider habe ich beim Aufruf immer einen http-Fehlercode 500 bekommen. Die Lösung habe ich noch einiger Recherche dann gefunden. Die web.config muss um folgendes ergänzt werden: <webServices> <protocols> <add name="HttpGet"/> <add name="HttpPost"/> <add name="HttpSoap"/> </protocols> </webServices> sonst kann der Web-Service nicht via GET aufgerufen werden.
Hinweis: Der Feed "NET - Software & DotNetNuke (DNN) Blog" und dessen hier dargestellten RSS-Inhalte liegen urheberrechtlich beim Autor der Betreiber-URL (siehe RSS-Link). Auf den Inhalt von "NET - Software & DotNetNuke (DNN) Blog" hat RSS-Nachrichten.de keinen Einfluss. (23905-4-165-1 - 0)

Passend zu diesem RSS-Feed haben wir folgenden Themen für Sie recherchiert:
Digitalkamera Powershot mit neuer Leistung
Mit der Digitalkamera Powershot ist Canon der Nachfolger der SX20 IS gelungen. Die neue Kamera heißt XS10 und sie zeigt unter anderem deutlich mehr B.. mehr
Lotus Server: das Datenbanksystem
Wer einen Server benötigt, der ist mit einem Lotus Server gut beraten. Diese professionelle Einrichtung wird privat wie geschäftlich wegen seiner ho.. mehr
Datenrettung der Festplatte: selbstgemacht oder einschicken?
Die Datenrettung einer Festplatte ist fast immer möglich. Erster und wichtigster Tipp: Ruhe bewahren! Nicht nachvollziehbarer Aktionismus kann noch m.. mehr
Laptop Rucksack: für alle
Praktischer als die altbekannte Laptoptasche ist ein Laptop Rucksack. Laptop Rucksäcke sind in vielen Geschäften erhältlich und erleichtern die Mob.. mehr
Digitalkamera Zoom, dreifach optisch reicht
Digitalkamera Zoom wird oftmals zu hoch bewertet und so wird von Fachleuten oft schon vom Zoomfaktor gesprochen, der oftmals mit viel zu großer Bedeu.. mehr
 RSS Startseite ·  Nachrichten ·  RSS-Verzeichnis ·  Weblogs ·  Podcasts ·  Video-Podcasts ·  RSS-Reader ·  Podcatcher  
Was ist RSS? ·  Neuen Feed eintragen  
RSS Verzeichnis
Top-Feed des MonatsTop-Feeds des Monats aus der Kategorie: Programmierung & ProgrammiersprachenJava MagazinInformatikerboard - Informatik online verstehenNET - Software & DotNetNuke (DNN) BlogTSQL News, C#, Visual Basic, C++, ASP Tipps und TricksMyWebsolution.de: Tutorials, Workshops, Tipps und Artikelpbhub.deActiveVB - NewsVB .Net News - http://www.visual-basic5.dezerbit.de News-FeedPHP Link Directory - PHP Link VerzeichnisArchiv2012 | 2011 | 2010 | 2009 | 2008 | 2007 | 2006 | 2005Aus diesem BereichMagnetkartenleser - Zugang zu geheimen DatenDas PDA DisplayDrucker, Scanner, Fax in Einem kaufenLaptop Docking StationTWAIN Scanner: Erfolgreich arbeitenVergleich von DigitalkamerasLaptop kaufen: vorher gut informierenDas RAID System - effiziente ArbeitMini Laptop die Alternative zum Notebook Scanner Software sollte Qualitätsware seinOriginal DruckerpatronenMobile Scanner für alle LebenslagenCompactflash Speicherkarten: superflach und langlebig!TFT Displays schlierenfrei, gestochen scharf!Die richtige Laptop BatterieNeue ThemenPrepaid-Handytarife: Günstig und flexibel telefonierenNikolausgeschenke - was kommt in den Sack?Wandkalender 2011 - öfter mal was NeuesPassende Schiebegardinen günstig im Internet erwerbenCocktail- oder Abendkleid: große Größen kein ProblemErholung und Entspannung mit einem Wellness WochenendeDSL ohne Schufa: Angebote im Internet vergleichenVisitenkarten erstellen und sich präsentierenKredit für Haus und Eigentumswohnung dank niedriger ZinsenVor- und Nachteile von einem Forex Managed AccountMit der Fritz-Box ins InternetProfessionelles Daytrading online lernenGünstige Hypothekenzinsen sichernMit einer Raumspartreppe Platz sparenSofortkredit ohne Schufa
RSS · Nachrichten · RSS Reader · Podcatcher · RSSFeed eintragen · Verzeichnis
Impressum · AGBs & Nutzungsbedingungenn · Partnerprogramme · Sitemap


· Diese Seite wurde generiert in 1.23428 Sekunden ·
© 2004-2012 RSS Nachrichten -