Error-mail med Health monitor

Ett riktigt bra tips av Mads Kristensen, som förklarar hur man kan konfigurera health monotor i .NET så den skickar mail, när ett oväntat fel har uppstått i applikationen. Läs mer på MSDN.

Inställningarna i Web.config ser ut så här:

<?xml version="1.0"?>
<configuration>
   <appSettings/>
   <connectionStrings/>

   <system.web>
      <compilation debug="false" />
      <trace enabled="true" localOnly="false" />

      <healthMonitoring enabled="true">
         <providers>
            <add name="EmailProvider"
               type="System.Web.Management.SimpleMailWebEventProvider"
               from="you@domain.com"
               to="you@domain.com"
               subjectPrefix="Error: "
               buffer="true"
               bufferMode="Notification" />
         </providers>
         <rules>
            <add provider="EmailProvider" name="All App Events" eventName="All Errors" />
         </rules>
      </healthMonitoring>

   </system.web>
   <system.net>
      <mailSettings>
         <smtp from="you@domain.com">
            <network host="smtp.domain.com" />
         </smtp>
      </mailSettings>
   </system.net>
</configuration>

By Jesper Lind

Felsök: Error 15023: User, group, or role already exists in the current database

Nu är det dags för oss att börja att brottas ordentligt med SQL Server 2005, och vi håller på att flytta en del databaser från 2000.

Något som kan ställa till med problem är att de gamla användarna följer med när man importerar databaserna. Vi har tidigare visat hur man kan ändra ägare på tabeller. Enligt min erfarenhet är det bäst att alltid köra med 'dbo' som ägare.

Vid import kan det bli en del konstigheter som resulterar att man inte kan ändra rättigheter alls en användare, och man får följande felmeddelande.

User, group, or role already exists in the current database. (Microsoft SQL Server, Error: 15023)

Detta beror på att Security identification numbers (SID) förväxlade eller 'föräldrarlösa' i sysusers-tabellen, som Falafel Software förklarar.

För att se en lista på övergivna inloggningar kan man göra följade stored procedure:

exec sp_change_users_login Report

SQLAuthority har exempel på skript som kan reparera felaktigheter på databas-användare.

By Jesper Lind

Hotfix för problem med valideringsfunktioner i .NET Ajax

Validerings-funktionerna i .NET har haft en del problem genom versionerna. I en version (har för mig att det var .NET 1.1) fungerade de knappt över huvudtaget. Men i 2.0 hade Microsoft löst de första problemen.

När sen MS Ajax släpptes blev det återigen en del buggar och problem. Det märkte jag häromdan när jag försökte ha validering på en TextBox i en wizard-kontroll som i sin tur låg inom en UpdatePanel. På första steget hade jag en TextBox med validering och där fungerade den fint. På andra steget så låg javascript-funktionerna kvar utanför UpdatePanel, men textboxen hade ju redan försvunnit och då blev det error som såg ut så här:

control has no properties
ValidatorGetValue("ctl00_mainContentPH_wizard_tbOrderId")WebResource.axd (line 104)
RequiredFieldValidatorEvaluateIsValid(span#ctl00_mainContentPH_wizard_ReqFieldOrderId)WebResource.axd (line 475)
ValidatorValidate(span#ctl00_mainContentPH_wizard_ReqFieldOrderId, "", null)WebResource.axd (line 208)
Page_ClientValidate("")WebResource.axd (line 128)
WebForm_DoPostBackWithOptions(Object)WebResource.axd (line 14)
if (typeof(control.value) == "string") {
 
Microsoft har dock gjort sitt bästa för att lösa även detta problem. Först så rekommenderades att man laddade ner en Validators.dll och mappade upp mot i Web.config.
 
Genom en kommentar hos Guttrie hittade jag info om en ny hotfix. Enligt erfarenhet när jag patchade ett Windows 2003-system fungerar den väldigt bra och man slipper att gör några ändringar i Web.config.
 
Om du inte orkar trixa för mycket med det och kan vänta så kommer en Windows Update snart med lösning.  

By Jesper Lind

Håll koll på errorloggen för HTTP

Idag larmade en av våra webbservrar för att utrymmet på C:-disken höll på att ta slut. När jag var inne och letade efter utrymme att frigöra hittade jag logg-filer i [%windir%\system32\LogFiles\HTTPERR] som jag inte visste att de fanns. Och de tog relativt stort utrymme.

Här loggas alla fel som sker i HTTP och inte kan tas hand om applikationen. En intressant källa att söka i med andra ord och då kan det vara bra att ha ett verktyg för att logganalys eftersom filerna är stora. 

Det var hos Chrison.net som jag först hittade dessa tips. Hos Microsoft kan man läsa mer om errorloggen för HTTP API och där finns även instruktioner för hur man byter plats på loggfilerna. I mitt fall vill jag hellre ha dem på en disk som är dedikerad för loggfiler och inte på huvuddisken som innehåller operativsystemet.

By Jesper Lind

Debugga AJAX med Nikhil's Web Development Helper

Att programmera AJAX är roligt, men när något går fel är det inte lika kul längre. Den vanliga tracern i .NET går ju inte att köra samtidigt. Sökte lite efter tips hur man kunde felsöka lättare och hittade ScottGu's inlägg om Nikhil's Web Development Helper.

Det handlar om ett suveränt tillägg till Internet Explorer som är till stor hjälp när man felsöker Ajax-applikationer. Läs mer om det hos Nikhil och kolla även in dokumentationen (PDF).

By Jesper Lind

Billigt webbhotell med lite mailstrul

Vi har tyvärr haft lite problem med att ta emot email den senaste veckan, fast bara på vår engelska domän (codeodyssey.com). Kontaktformuläret har dock inte fungerat på någon av våra två sajter, så har ni försökt ta kontakta det senaste så ber vi er försöka igen.

Det hela verkar bero på att vårt webbhotell, Web10.se, har en del problem när de genomfört ett byte av mailservrar. De har fortfarande inte löst det helt.

Men jag kan konstatera att det nya webbmail som är baserad på Sun Java System Communications Express 6 2005Q4 verkar riktigt bra. Förhoppningsvis ska mailen leveraras lite snabbare nu också. Innan har vi märkt en fördröjning på 10-20 minuter.

Sen verkar det som att vi äntligen fått en spamfilter på mailservern. Har sett att jobbiga mail markeras med [!RBLs] i ämnesraden. Har inte kollat något mer ingående på detta men ett spamfilter är verkligen uppskattat.

Om de även kan installera ASP.NET AJAX på servrarna, så kommer vi nog ligga kvar där ett tag till.

Kan verkligen rekommendera Web10.se för er som letar efter ett lite billigare webbhotell men ändå med väldigt bra support.

By Jesper Lind

Ny Internet Explorer Developer Toolbar-beta

Fick reda på genom Robert Folkessons blog att beta 3 av Internet Explorer Developer Toolbar finns att ladda hem. Nyheter i denna är:

  • validering av HTML, CSS, WAI och RSS-feeds
  • visning av bildstorlekar, filstorlekar och sökvägar
  • linjal för att mäta objekt på en sida, praktiskt för att kunna linjera saker mer exakt
  • rensa cachen för en enskild domän - mycket användbart när man vill vara säker på att man har senaste innehållet från just den sidan, men inte vill sopa bort allt annat i cachen

Jag lyckades till slut få igång den den men blev lite besviken på att man var tvungen att avinstallera beta 2 genom "Lägg till eller/ta bort program". En sån extra manöver kan man ju alltid leva med när det rör sig om beta-versioner. Om det fungerar...

Jag kunde inte avinstallera min förra beta pga att jag har städat bort installeraren. Den hade lagt sig i temporära internet filer (ingen bra plats för viktiga filer).

Efter en sökning hittade jag dock tråden om betan i IEBloggen att en del andra haft liknade problem. Genom denna hittade jag filerna till den gamla installeraren. Dessa finns på PlanetMirror, de jag behövde var iedevtbar.msi och IEDevToolBarSetup.msi. Efter att sen döpt om dem till iedevtbar[1].msi och IEDevToolBarSetup[1].msi för att matcha infon i min installering så kunde jag avinstallera den gamla betan. Hoppas att detta kan hjälpa andra som har liknande problem.

Provkörde just den nya betan av toolbaren och det ser riktigt bra ut. Nu börjar man verkligen ge Firefox en match på smidiga verktyg för utvecklare.

By Jesper Lind

Klass-referenser till dynamiska instanser av User Controls

User Controls är smidiga att använda i .NET och ofta vill man ladda in dem dynamiskt. Då måste man referera till dem med deras egna klasstyp.

I version 1.1 var det lättare än i version 2.0 eftersom alla referenser fanns i samma assembly. Man kunde då använda kod som enligt följande.

MyUserControl_ascx myUserControl = (MyUserControl_ascx)LoadControl("MyUserControl.ascx");
myUserControl.IntProperty = 123;
myPlaceHolder.Controls.Add(myUserControl);

På många projekt som jag konverterar från 1.1 till 2.0 får jag felet:

Det gick inte att hitta typ- eller namnområdesnamnet MyUserControl_ascx (saknas ett using-direktiv eller en sammansättningsreferens?

I version 2.0 har nämligen komplileringsmodellen gjorts om en hel del och varje sida och kontroll kompileras i egna assemblys. Man måste nu tänka på att lägga in en referens på de sidorna som ska kunna använda kontrollens klasstyp. En alternativ lösning kan vara att lägga kontrollen i den speciella App_Code-mappen, men då kan man endast använda "inline-code"-modellen.

Jag tänkte nu visa några ett exempel på hur man kan referera till dynamiskt laddade User Controls, tilldela dem egenskaper och lägga till dem på sidan i en PlaceHolder. Exemplet visar hur man gör detta med både "code behind"- och "inline"-modell.

Det som är viktigt att tänka på är att referera till kontrollen med "Reference"-taggen som i mitt exempel ligger i mappen "ctrl". Observera också att när om kontrollen använder inline-kod så måste prefixet "ASP." användas på referensen till instansen.

Default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Reference Control="ctrl/WebUserControl_InlineCode.ascx" %>
<%@ Reference Control="ctrl/WebUserControl_CodeBehind.ascx" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Set Properties to dynamicly loaded UserControls</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:PlaceHolder ID="ph" runat="server" />
</div>
</form>
</body>
</html>

Default.aspx.cs


using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Control ctrl = LoadControl("ctrl/WebUserControl_CodeBehind.ascx");
((WebUserControl_CodeBehind)ctrl).StrProperty = "First string";
ph.Controls.Add(ctrl);

//Add linebreak
ph.Controls.Add(new LiteralControl("<br />"));

Control ctrl2 = LoadControl("ctrl/WebUserControl_InlineCode.ascx");
((ASP.WebUserControl_InlineCode)ctrl2).StrProperty = "Second string";
ph.Controls.Add(ctrl2);
}
}

ctrl/WebUserControl_InlineCode.ascx

<%@ Control Language="C#" ClassName="WebUserControl_InlineCode" %>

<script runat="server">

string strProperty = string.Empty;

public string StrProperty
{
get { return strProperty; }
set { strProperty = value; }
}
void Page_Load()
{
lbl.Text = "Property from inline-code User Control: " + strProperty;
}

</script>
<asp:Label ID="lbl" runat="server" />

ctrl/WebUserControl_CodeBehind.ascx

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="WebUserControl_CodeBehind.ascx.cs" Inherits="WebUserControl_CodeBehind" %>
<asp:Label ID="lbl" runat="server" />

ctrl/WebUserControl_CodeBehind.ascx.cs

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class WebUserControl_CodeBehind : System.Web.UI.UserControl
{
string strProperty = string.Empty;

public string StrProperty
{
get { return strProperty; }
set { strProperty = value; }
}
void Page_Load()
{
lbl.Text = "Property from code-behind User Control: " + strProperty;
}
}


MSDN: "Creating Instances of User Controls Programmatically"

 

By Jesper Lind

Felsök: Could not find schema ...NetConfiguration/v2.0:configuration

Fick detta felet i VS intellisense, och det tyder på någon misskonfiguration i Visual Studio.

Could not find schema information for the element 'http://schemas.microsoft.com/.NetConfiguration/v2.0:configuration'.

Som en snabb fix bytte jag ut:

<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">

Mot:

<configuration>
<!-- xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0"-->

Man kan läsa mer om det här och här.

By Jesper Lind

Felsök: Request.Form-värdet som identifierats från klienten ... kan vara skadligt

Detta är ett fel som man kan få om man skriver in html-kod i en textruta och postar det med Asp.Net. Det behöver inte ens vara html. .NET-Ramverket känner av ifall man har skrivit större-än eller mindre-än tecknet ("<...>").

Hela felmeddelandet:

Beskrivning: Vid verifiering av begäran identifierades ett indatavärde från klienten som kan vara skadligt. Behandlingen av begäran har avslutats. Det här värdet kan indikera ett försök att kompromettera säkerheten för tillämpningsprogrammet, till exempel en skriptattack över webbplatsen. Du kan inaktivera verifiering av begäran genom att ange validateRequest=false i Page-direktivet eller -konfigurationsavsnittet. Du bör emellertid låta tillämpningsprogrammet kontrollera alla indata i det här fallet.

Undantagsinformation: System.Web.HttpRequestValidationException: Request.Form-värdet som identifierats från klienten (ctl00$mainContentPH$fvFaq$tbFaqBody_sv-SE="...the link &lt;a href="http://www....") kan vara skadligt.

Botemedel
För att stänga av valideringen kan man göra på två sätt.

1. Stänga av i konfigurationen

<system.web>
<pages ValidateRequest="false"/>
</system.web>

2. Stänga av på en enskild sida

<%@ Page ValidateRequest="false" ... %>

En varning för injektion
Valideringen finns där av ett skäl, tänk på att om den stängs av så kan besökarna t ex posta javascript som ser ut så här. Och det är inte ofta man vill...

<script>alert('I am posting some dangerous code')</script>

Mer info finns på Brian Cryer's hemsida.

By Jesper Lind