ASP.NET FileAccessWeb Sample, část 1

Jan Holan       10. 7. 2012       ASP.NET/IIS       9448 zobrazení

V této čtyř dílné sérii budu postupně popisovat postup vytvoření jednoduché ASP.NET aplikace pro umožnění přístupu k souborům pro přihlášené uživatele. Nepůjde jen o aplikaci samotnou, ale hlavně si ukážeme některé záležitosti dnešních ASP.NET WebForms aplikací. Některé řešené věci budou určitě využitelné i v jiných aplikacích. Také je možné, že některé tyto záležitosti mnozí z vás znáte (nebo je řešíte trochu jinak), ale věřím, že někteří si některé novinky z této série odnesou.

Zadání aplikace

Popíšeme si co od naší vzorové aplikace očekáváme.

Jedná se o aplikaci, která bude hlídat a zajišťovat přistup k souborů v určené složce. Po vstupu do aplikace bude po uživateli nejprve na přihlašovací stránce požadováno přihlášení. Po úspěšném přihlášení uživatele bude povolen přístup ke hlavní stránce aplikace, která nabídne seznam souborů ze složky a umožní jejich stahování.

FileAccessWeb

Abychom nemuseli uživatele, kteří budou mít přístup k souborům někde spravovat a udržovat (například v databázi), budeme v příkladu uživatele ověřovat proti Windows účtům. K tomu zde s výhodou využijeme technologii WIF (podle postupu z příspěvku Windows Identity Foundation: Náhrada za Forms autentizaci).

Z obecných požadavků na aplikaci ještě doplním:

  • Použité technologie .NET 4.0ASP.NET WebForms, IIS 7/7.5
  • Aplikace bude používat URL Routing a URL budou bez přípon .aspx.
  • Aplikace bude přizpůsobena pro přístup z Internetu (budeme implementovat několik málo SEO principů).
  • Aplikace bude pro design používat jednoduché HTML/CSS a kde to bude možné tak bez nutnosti Javascriptu tj. bez jquery-ui a podobných Frameworků. (V aplikaci bude na jednom místě Javascript použit).
  • Případné chyby v aplikaci budeme logovat a uživateli zobrazíme pouze informaci, že došlo k neočekávané chybě.

Kompletní zdrojové soubory celé aplikace jsou k dispozici zde. Na některé soubory z tohoto archivu, které by neměli cenu celé popisovat, se budu v textu této série pouze odkazovat.

Vytvoření projektu

Začneme vytvořením nového projektu ve Visual Studiu (2010 nebo 2012). Zvolíme .NET Framework 4.0 a šablonu ASP.NET Empty Web Application, aplikaci nazveme například FileAccessWeb.

Pozn.: Volíme šablonu ASP.NET Empty Web Application ze dvou důvodů. Jednak je pro pochopení funkčnosti jednodušší konkrétní věci postupně přidávat, a jednak se mi v poslední době výchozí šablona Web Application zdá již poměrně moc obsáhlá věcmi, které většinou nepotřebuji, nebo dělám jinak.

Ve vlastnostech projektu dále nastavíme spouštění z lokálního IIS (7 / 7.5), případně IISExpress. (V případě IIS můžeme použít výchozí ASP.NET v4.0 pool).

Hlavní stránka Master Page

Vytvoříme hlavní stránku Master Page s názvem Site.Master. A v HTML vytvoříme hlavní layout celé aplikace.

<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs" Inherits="FileAccessWeb.Site" %>
<!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 id="Head" runat="server">
    <meta http-equiv="X-UA-Compatible" content="IE=9" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="author" content="All: IMP spol. s r. o." />
    <meta name="copyright" content="(C) 2012 IMP spol. s r. o." />
    <link rel="shortcut icon" href="favicon.ico" />

    <link rel="stylesheet" type="text/css" media="screen" href="css/Site.css" />
    <link rel="stylesheet" type="text/css" media="screen" href="css/StyleSheet.css" />

    <asp:ContentPlaceHolder ID="HeadContent" runat="server">
    </asp:ContentPlaceHolder>
</head>
<body>
<form id="form" runat="server">
    <div id="header">
        <div id="main" class="clearfix">
            <div id="header_inner">
                <table id="headertable" cellpadding="0" cellspacing="0">
                    <tr>
                        <td>
                            <h1><asp:Label ID="PageTitleLabel" runat="server" ViewStateMode="Disabled"></asp:Label></h1>
                        </td>
                        <td id="header_right">
                            <asp:LoginView ID="loginView" runat="server" ViewStateMode="Disabled">
                                <LoggedInTemplate>
                                    <asp:Label ID="UserNameLabel" runat="server"></asp:Label><br />
                                    <asp:LoginStatus ID="loginStatus" LogoutText="Odhlásit" CssClass="signout" runat="server" OnLoggingOut="loginStatus_LoggingOut"/>
                                </LoggedInTemplate>
                            </asp:LoginView>
                        </td>
                    </tr>
                </table>
            </div>
            <div id="container">
                <asp:ContentPlaceHolder ID="MainContent" runat="server" />
            </div>
        </div>
    </div>
    <div id="footer">
        <div id="footer_inner" class="clearfix">
            <div id="cleft">
                Vytvořil: <a href="http://www.imp.cz" target="_blank" title="Přejít na IMP / www.imp.cz">&copy; 2012 IMP spol. s r.o.</a>
            </div>
            <div id="cright">
                <a href="http://blog.imp.cz" title="" target="_blank">http://blog.imp.cz</a>
            </div>
        </div>
    </div>
</form>
</body>
</html>

V hlavičce jsou nastaveny dva CSS soubory. Zatím budeme ale potřebovat pouze Site.css. Vytvoříme tedy podadresář Css a Site.css do adresáře zkopírujte (naleznete ho v archivu celé aplikace, nebo si ho můžete prohlédnou zde). Do souboru Site.css jsem kromě stylů použité ve stránce Site.Master umístil i další základní styly aplikace. Při tvorbě webové aplikace se dnes totiž nemůžeme spoléhat na výchozí hodnoty elementů CSS, protože každý prohlížeč je má jiné. Musíme tedy vždy nastavit i těmto elementům jako html, body, form, a, h1, h2, h3, h4, h5 základní styly jako margin, padding, font-size, line-height atd. Neuvedení těchto stylů základních elementů je mnohdy důvod velkých rozdílů v zobrazování stránek v různých prohlížečích.

Pozn.: Pokud často testujete zobrazení stránky ve více prohlížečích, doporučuji se také podívat na projekt http://multi-browser.com.

Za zmínku stojí také nastavení http-equiv meta tagu X-UA-Compatible. Ten určuje compatibility level pro IE prohlížeče. Jedná se o to, že v některých prostředí, konkrétně intranetové prostředí s doménou, je u IE ve výchozím nastavením automaticky zapínán compatibility view mód a tím je stránka zobrazena leckdy špatně (je dokonce ignorován i nastavený DOCTYPE). Popravdě nechápu smysl této funkce, když jsem to viděl poprvé, tak jsme nemohl dlouho přijít na důvod, proč je stránka po nasazení na produkční prostředí  nejednou zobrazována jinak. Každopádně nastavením X-UA-Compatible se IE compatibility view mód potlačí (zároveň se skryje i tlačítko, které ho umožňuje zapnout ručně). Více o volbě v IE zde a o nastavení meta tagu zde.

Do projektu dále také z archivu celé aplikace přidáme další odkazované soubory jako favicon.icoImages/headerside.png (odkazovaný ve stylu #header).

Layout stránky je rozdělen na části headermain a footer. V hlavičce je vlevo vypisován titulek jednotlivých stránek a doprava je umístěn kontrol LoginView , který bude zobrazovat jméno přihlášeného uživatele a odkaz na odhlášení. Do code behind Master page pro toto doplníme potřebný kód
(kód loginStatus_LoggingOut doplníme později):

public partial class Site : System.Web.UI.MasterPage
{
    protected override void OnPreRender(EventArgs e)
    {
        PageTitleLabel.Text = Page.Title;
    }

    protected void loginStatus_LoggingOut(object sender, LoginCancelEventArgs e)
    {
    }
}

Abychom mohli layout vyzkoušet, vytvoříme novou prázdnou stránku, volbou Web Form using Master Page a vybereme naší Site.Master, stránku pojmenujeme Default.aspx. Do ní nám zatím stačí doplnit Title jak v hlavičce, tak i v definici Page, odkud se kódem v Master page vypisuje.

<%@ Page Title="File Access Web" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="FileAccessWeb.Default" %>
<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server">
    <title>File Access Web</title>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
</asp:Content>

Stejným postupem ještě založíme jednu stránku s názvem Login.aspx a opět vyplníme titulek například na “File Access Web – Login”.

Routing

Poslední věcí co v této části provedeme bude zavedení routingu na stránky aplikace. To provedeme v souboru Global.asax, který do projektu vytvoříme. V Application_Start provedeme registraci výchozí (prázdné) adresy a adresy Login.

Soubor bude vypadat takto:

public class Global : System.Web.HttpApplication
{
    #region event handlers
    protected void Application_Start(object sender, EventArgs e)
    {
        //Register routes
        RouteTable.Routes.MapPageRoute("Default", "", "~/Default.aspx");
        RouteTable.Routes.MapPageRoute("Login", "Login", "~/Login.aspx");
    }

    protected void Application_BeginRequest(Object sender, EventArgs e)
    {
        if (HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath == "~/" && !HttpContext.Current.Request.Path.EndsWith("/"))
        {
            Response.RedirectToRoute("");
            return;
        }

        if (HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath.Equals("~/default.aspx", StringComparison.OrdinalIgnoreCase))
        {
            Response.RedirectToRoute("");
            return;
        }
    }
    #endregion
}

Ještě si vysvětlíme přidaný kód v Application_BeginRequest, ten se nám postará o to, že pokud jdeme na web adresou stránky default.aspx (http://FileAccessWeb/Default.aspx), tak provedeme redirect výchozí routou a tím skončíme na adrese http://FileAccessWeb/. Horní část kódu ještě ošetřuje přístup adresou http://FileAccessWeb (bez lomítka), přejde opět na http://FileAccessWeb/.

Abychom stránky nemohli vyvolávat pomoci adresy s jejich fyzickém umístěním (například http://FileAccessWeb/Login.aspx), zablokujeme přístup na soubory podle přípony .aspx. Provedeme to nastavením ve Web.config souboru, do kterého přidáme následující sekci system.webServer:

<system.webServer>
  <validation validateIntegratedModeConfiguration="false"/>
  <handlers>
    <add name="AspxBlockHandler" path="*.aspx" verb="*" type="IMP.Web.NotFoundHandler" />
  </handlers>

  <defaultDocument>
    <files>
      <clear />
      <add value="Default" />
    </files>
  </defaultDocument>
</system.webServer>

Důležitá je zde podsekce handlers , ve které zaregistrujeme cestu *.aspx. Pro ní budeme volat náš handler NotFoundHandler, ten bude pouze vracet StatusCode 404 (stránka nenalezena). Tuto třídu handleru vložíme do projektu.

public class NotFoundHandler : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        context.Response.StatusCode = 404;
        context.Response.StatusDescription = "Not Found";
    }

    public bool IsReusable
    {
        get { return true; }
    }
}

Nyní nám tedy v aplikaci fungují dvě stránky – výchozí přes URL http://FileAccessWeb/  a také adresou http://FileAccessWeb/Default.aspx, kdy dojde k přesměrování na /. Druhá stránka pro přihlášení je přístupná na adrese http://FileAccessWeb/Login a adresa na fyzický soubor login.aspx nám vrací požadovanou chybu
404 - Not Found.

Příště budeme pokračovat zavedením mechanizmu pro autentizaci uživatelů.

 

hodnocení článku

0       Hodnotit mohou jen registrované uživatelé.

 

Nový příspěvek

 

Dalsie podobne serie?

Ako som pisal v prispevku vyssie, velmi dobra seria. Osobne by som rad uvital viac podobnych dalsich serii.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Velmi pekny pripad pouzitia viacerych vlastnosti ASP.NET

Tato seria 1-4 v sebe spaja viacere vlastnoti a principy ASP.NET, ktore su dobre vysvetlene. Nadchlo ma to natolko, ze po precitani tejto serie, som precital mnozstvo vasich dalsich clankov. A tak som nahodou objavil tuto aplikaciu upravenu pre .NET 4.5

Len by som chcel podotknut, ze k tomuto clanku by sa hodilo zverejnit aj odkaz na http://www.dotnetportal.cz/blogy/15/Null...

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.

Nyní zakládáte pod článkem nové diskusní vlákno.
Pokud chcete reagovat na jiný příspěvek, klikněte na tlačítko "Odpovědět" u některého diskusního příspěvku.

Nyní odpovídáte na příspěvek pod článkem. Nebo chcete raději založit nové vlákno?

 

  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:  
Heslo:  

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback