Welcome to AspAdvice Sign in | Join | Help

Firefox 3.0 and (ASP.NET) caching observations

1. Have a page with code in Page_Load

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Response.Cache.SetAllowResponseInBrowserHistory(False)
        Response.Cache.SetCacheability(HttpCacheability.NoCache)
        Response.Cache.SetNoStore()
        Response.Expires = 0

        Response.Write("" & DateTime.Now.ToLongTimeString())

    End Sub


2. In aspx

...   

 <form id="form1" runat="server">
    <div>
        <asp:Wizard ID="Wizard1" runat="server">
            <WizardSteps>
                <asp:WizardStep ID="WizardStep1" runat="server" Title="Step 1">
                </asp:WizardStep>
                <asp:WizardStep ID="WizardStep2" runat="server" Title="Step 2">
                </asp:WizardStep>
                <asp:WizardStep ID="WizardStep3" runat="server" Title="Step 3">
                </asp:WizardStep>
                <asp:WizardStep ID="WizardStep4" runat="server" Title="Step 4">
                </asp:WizardStep>
                <asp:WizardStep ID="WizardStep5" runat="server" Title="Step 5">
                </asp:WizardStep>
            </WizardSteps>
        </asp:Wizard>
    </div>
    </form>
...


3. Now run the page in IE, click the links etc in the wizard and then hit Back button, IE complains that content is expired (so does FF 2 if you try with that)

4. Now run the page in FF3.0, click the links etc and then hit Back button, it just shows the previous version as if nothing is expired

Do you get the same behavior?

See also:

How to prevent Firefox 3.0 from caching
http://forums.mozillazine.org/viewtopic.php?f=25&t=673135&st=0&sk=t&sd=a

 So if you have some data that you don't want to be displayable via back button, you should probably use other means than preventing the page from being cached. For example SSL (if it is really private data when you should use SSL anyway).

Sponsor
Posted by joteke | 0 Comments
Filed under: , , , ,

What's for VB.NET in the Future, interesting to see...

By being momentarily pissed off to the level of job I needed to do with classes working with DB and business logic in a project, I made suggestion in Connect, a while ago 

Ability to specify a default method for object instance which is called when any or certain method/properties will be accessed
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=349999

Description shortly:

"For VB team (why not for C# too :-) )

Writing logic to check object's state when properties are accessed can cause quite a bit repeated code, because at least you need to duplicate the call on every property accessor.

Certainly there are other ways around this which usually is checking the state then on some method, but not on the property accessor (design guidelines state that property accessor shouldn't throw an exception), but it would be great if compiler would be able to inject a call to a "default" method which will be called when any or given property is accessed.

Properties are methods under the covers and I believe they should be allowed to throw exceptions if state of the object demands for it. For example in my scenario, it represenst an object deleted from database. One must not use the object anymore because it doesn't really exist...

"

I got a response quite fast from Jonathan Aneja, Program Manager on VB Team, here's what he said:

"Hi there,

Thanks for taking the time to file this suggestion. I've got some good news and bad news for you. The good news is the scenario you mention is one we've been thinking about a lot lately, and we have some ideas on how to address this in a big way.

The bad news is the timeframe we're thinking of for this feature is actually two releases away, not one. This is part of a much larger feature we're building that's going to take a while to build.

I'm going to resolve this as "By Design" for now, but rest assured this scenario is high on our list."

Oh, and I got also a nice community comment that I'm looking for aspect-oriented programming (with link to: http://www.bodden.de/tools/aop-dot-net/), thanks for that btw!

Point is that it's actually pretty nice to know that these things are also thought at MS. Not that I mean component and 3rd party vendors providing these as products should not exist, but I've always loved the idea that I have all the stuff in the one and only development environment, plus of course, what I use works as a product. I'm definately going to have a look at aspect-oriented programming, it indeed seems what I'm looking for. But it's important to know that the future of my toolset is going to evolve - and with VS201x I still might see something groundbreaking cool in VB.NET. :-)

When I asked the permission from Jonathan to post his comment publicly, he thought that there might not actually be much to see in his response, but I disagree. Mostly because knowing that MS thinks these scenarios also basically calls for feedback too, at the early stage (involving community in design-related tool development etc is better to happen sooner than later - not least because there are almost as many opinions as commenters)). So it's good to know there's design work going on, which community can comment on, at least it's targeted at something, even though community doesn't know what they're commenting (or MS does based on their comments). :-D

Certainly, this is something that language team is now designing for the future, so how wide can that feature be, without it falling out of the context or needing already coordination and cowork with other teams? Hard to say as Jonathan didn't tell more about what they are thinking at the moment. But I hope they reveal it on one day. :-)

What comes to the idea itself, what I proposed, is one thing I'm looking for eagerly and it's great they gonna solve it somehow (although years will pass before it's out), but is there something else someone would want to see in VB.NET in the Future? Suggesting that in Connect might be a good idea.

Sponsor
Posted by joteke | 2 Comments
Filed under: ,

Using the information your (development) environment provides - is allowed!

Huge title while the subject or the example in this case is actually very simple and straightforward. I saw a question on newsgroups which went something like:

- poster states he doesn't know much about control events
- he/she asked if he/she had a method like

 protected void tbPreRender(object sender, EventArgs e)
    {
        tb1.Attributes["value"] = tb1.Text;
        tb2.Attributes["value"] = tb2.Text;
    }

wired to two separate TextBoxes Prerender event, is it fired twice? He/she hoped that ASP.NET would deal this somehow that it would be called only once, like SQL Server does with subqueries.

First thing to note in this case of course is that ASP.NET cannot do much assumptions, due to its generality, it does what it can in the most common case, and that definately is all. So this logic (UI logic) is up to the page developer right away. Second thing is that SQL Server is totally another beast, important though and lots used with ASP.NET, but it's not really comparable in that sense, that ASP.NET would somehow reuse similar logic. ASP.NET does what's needed to abstract HTTP, and SQL Server does the same for relational database and its additional featureset stuff. Third is that you can write the previous case like:

//Wiring events somewhere
tb1.PreRender += new EventHandler(tbPreRender);
tb2.PreRender += new EventHandler(tbPreRender);


  protected void tbPreRender(object sender, EventArgs e)
    {
        //Use the knowledge that control raising the event is available via
sender argument
        TextBox tb=(TextBox)sender;
        tb.Attributes["value"] = tb.Text;
    }

when you basically take use of the knowledge what the environment does, in this case, how ASP.NET exposes events and what's available via them.

Sounds like I'm patronizing and ditting the i's and crossing the t's, but my point is that this is normal unawareness for newbies , but emphasizes how important it really is that you learn to know the "landscape" of technologies you're working on, what each one of them does and what's each one's responsibility. Kind of think it as understanding your personal development architecture. It doesn't mean you need to know everything (measuring what one does or doesn't need to know is actually a hell of a problem for any developer these days, be it newbie or not) but you should be comfortable with the environment, especially if you earn your living by using it. You can learn while working - work is the best teacher - but you cannot be blind.

In this case, reading a good book, or looking at the documentation or definately asking someone mor eexperienced, of course brings lights on - learning always starts from somewhere, but be prepared that you'll do that rest of your life, at least in this profession. :-)

 

Sponsor
Posted by joteke | 0 Comments

Book Review: C# In Depth by Jon Skeet (Manning)

Author: Jon Skeet
Publisher: Manning Publications Co.
ISBN: 1933988363
April 2008, 424 pages
http://www.manning.com/skeet/

The book focuses on C# 2 and C# 3, but goes a bit relevant things on building on C# 1. It is targeted at developers familiar with C# 1 and making the move to C# 2 and C# 3. The book is not syntax reference -like, and focuses more on the aspects and use of the language while of course, introducing the new and exciting features in C# 2 and C# 3.

 

 

 

Table of Contents

foreword xvii
preface xix
acknowledgments xxi
about this book xxiii
about the cover illustration xxviii
comments from the tech review xxix

Part 1 Preparing for the journey

1 The changing face of C# development
1.1 Evolution in action: examples of code change
1.2 A brief history of C# (and related technologies)
1.3 The .NET platform
1.4 Fully functional code in snippet form
1.5 Summary

2 Core foundations: building on C# 1
2.1 Delegates
2.2 Type system characteristics
2.3 Value types and reference types
2.4 C# 2 and 3: new features on a solid base
2.5 Summary


Part 2 C# 2: solving the issues of C# 1

3 Parameterized typing with generics
3.1 Why generics are necessary
3.2 Simple generics for everyday use
3.3 Beyond the basics
3.4 Advanced generics
3.5 Generic collection classes in .NET 2.0
3.6 Limitations of generics in C# and other languages
3.7 Summary

4 Saying nothing with nullable types
4.1 What do you do when you just don’t have a value?
4.2 System.Nullable and System.Nullable
4.3 C# 2’s syntactic sugar for nullable types
4.4 Novel uses of nullable types

5 Fast-tracked delegates
5.1 Saying goodbye to awkward delegate syntax
5.2 Method group conversions
5.3 Covariance and contravariance
5/4 Inline delegate actions with anonymous methods
5.5 Capturing variables in anonymous methods
5.6 Summary

6 Implementing iterators the easy way
6.1 C# 1: the pain of handwritten iterators
6.2 C# 2: simple iterators with yield statements
6.3 Real-life example: iterating over ranges
6.4 Pseudo-synchronous code with the Concurrency and Coordination Runtime
6.5 Summary

7 Concluding C# 2: the final features
7.1 Partial types
7.2 Static classes
7.3 Separate getter/setter property access
7.4 Namespace aliases
7.5 Pragma directives
7.6 Fixed-size buffers in unsafe code
7.7 Exposing internal members to selected assemblies
7.8 Summary

Part 3 C# 3—revolutionizing how we code

8 Cutting fluff with a smart compiler
8.1 Automatically implemented properties
8.2 Implicit typing of local variables
8.3 Simplified initialization
8.4 Implicitly typed arrays
8.5 Anonymous types
8.6 Summary

9 Lambda expressions and expression trees
9/1 Lambda expressions as delegates
9.2 Simple examples using List and events
9.3 Expression trees
9.4 Changes to type inference and overload resolution
9.5 Summary

10 Extension methods
10.1 Life before extension methods
10.2 Extension method syntax
10.3 Extension methods in .NET 3.5
10.4 Usage ideas and guidelines
10.5 Summary

11 Query expressions and LINQ to Objects
11.1 Introducing LINQ
11/2 Simple beginnings: selecting elements
11.3 Filtering and ordering a sequence
11.4 Let clauses and transparent identifiers
11.5 Joins
11.6 Groupings and continuations
11.7 Summary

12 LINQ beyond collections
12.1 LINQ to SQL
12.2 Translations using IQueryable and IQueryProvider
12.3 LINQ to DataSet
12.4 LINQ to XML
12.5 LINQ beyond .NET 3.5
12.6 Summary

13 Elegant code in the new era
13.1 The changing nature of language preferences
13.2 Delegation as the new inheritance
13.3 Readability of results over implementation
13.4 Life in a parallel universe
13.5 Farewell
 
appendix: LINQ standard query operators
index

My opinion:

This is a great book for anyone taking their first steps with C# 2 and C# 3. It's not a syntax reference book, so don't expect seeing pages after pages of endless tables describing what can be told in the documentation. In this book Jon Skeet provides deep insight into C#. His experience is nicely included in the writing as he goes on the topics with great care -  and the result is this -, a first-class book about C#.

Sponsor
Posted by joteke | 1 Comments
Filed under: ,

VB.NET or C# - which one to choose? I choose BOTH :-)

Joe Stagner discusses in a blog post based on reader feedback, if one should choose VB.NET or C# and he ends with that it doesn't matter. Well, I sort of disagree, but let me first explain in which way I disagree, before you judge me and burn me in the eternal fire. :-) It's semantical difference in thinking, as in straight terms, Joe is 100% right.

I've started my career as a VB and VBScript (classic ASP) "programmist" ;-) , and when .NET came I jumped on it, and of course went with VB.NET. It was easy step - .NET I mean - and has been the one correct choice ever since. But in the early days, I was also forced to learn C# due to some aspects in ASP.NET 1.0's server controls and bug in VB.NET - which forced me to write my controls in C#. And it was definately the best thing that has happened to me since. It forced me to:

- use both of the languages fluently
- choose the one language over the other based on the task
- not to do my decisions based on some general "bee in one's bonnet" or just for attitudinal reasons

I've grown to think that in .NET you really should master all the mainstream languages in a way that it actually makes it non-important thing what language you use or choose. With .NET it means thinking in terms of the Framework, 'seeing the trees for the Forest'. To access its services languages are just one of the tools (very important ones, of course). Your customers don't give a crap what tool you actually use - at least if they aren't technically-oriented, and not sure if your bosses do either unless it is some general decision of IT management or something  - which it might be, though. There can be limiting factors, and they belong to life. :-)

Anyways, if the choice is yours as a developer - responsible for customer's satisfaction, responsible for your and your family's income and responsible company's success :-), you probably don't want to fall on language choice when there is your ass on the line in any case. You use what's best to use to get the job done, efficiently but correctly.

The VB vs C# debate has been there since .NET's first days. Partly, because MS's language teams basically compete with each other, and C# was promised to be the language, or at least was marketed as such. The debate has probably matured a bit over the years, but it's also healthy aspect in a way that it benefits not just language communities, but the entire framework (usually a new feature in a language spreads fast to the others in a way or another). Therefore it's good that the discussion goes on as long as it brings good results.

Sponsor
Posted by joteke | 2 Comments
Filed under:

Free eBook: Foundations of Programming by Karl Sequin

View and download at: http://codebetter.com/files/folders/codebetter_downloads/entry179694.aspx

 

Sponsor
Posted by joteke | 0 Comments
Filed under:

Hyper-V for W2008 is in RTM

See: http://blogs.technet.com/virtualworld/archive/2008/06/26/ittttttt-s-heeeeeeerrrrreeee-hyper-v-rtm.aspx

:-)

Sponsor
Posted by joteke | 0 Comments
Filed under:

Microsoft's "Velocity" project

Some skillful people at Microsoft have started yet one interesting project to increase our toolbox. It's "Velocity" which targets to help dealing with caching - local and distributed - through all the .NET application types, not just ASP.NET.

From: http://msdn.microsoft.com/fi-fi/library/cc645013(en-us).aspx

“Velocity” is a distributed in-memory application cache platform for developing scalable, available, and high-performance applications. “Velocity” fuses memory across multiple computers to give a single unified cache view to applications. Applications can store any serializable CLR object without worrying about where the object gets stored. Scalability can be achieved by simply adding more computers on demand. “Velocity” also allows for copies of data to be stored across the cluster, thus protecting data against failures. “Velocity” can be configured to run as a service accessed over the network or can be run embedded with the distributed application. “Velocity” includes an ASP.NET session provider object that enables ASP.NET session objects to be stored in the distributed cache without having to write to databases. This increases the performance and scalability of ASP.NET applications

See also:

Team Blog
http://blogs.msdn.com/velocity

Forum
http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=2142&SiteID=1

Download
http://www.microsoft.com/downloads/details.aspx?FamilyId=B24C3708-EEFF-4055-A867-19B5851E7CD2&displaylang=en

Of course at first I'm thinking that does this bring anything added value compared to 3rd party products - price is one likely, of course - or to Caching Application Block. Push based notifications is a big wish for this sort of tool, and I strongly think pretty well reasoned too.

Sponsor
Posted by joteke | 1 Comments
Filed under: ,

Scott Hanselman releases BabySmash

http://www.hanselman.com/blog/IntroducingBabySmashAWPFExperiment.aspx

BabySmash is an application - written with WPF - for all the kids who share interest in computing (or keyboards :-) ) and for their parents trying to keep the machine safe. Application "sounds, shows letters and numbers while ostensibly protecting the machine (the software at least) from the kids". I've used BabyMash, oldie but goldie, and all my three kids have loved it while in diaper age, and the youngest one - still in that age - likes BabySmash too.

While Scott has done BabySmash to test WPF and to entertain his kids and wants to share the result, it's also indication how in-the-end small things can make things better for our children - and how its creative to combine fun and real objectives . After all, I suppose kids are meaning of the life (or watching while grandchildren play) . :-)

Sponsor
Posted by joteke | 0 Comments
Filed under: ,

Repairing SQL 2005 Business Intelligence Studio after uninstalling VS2005

I've lately crushed on SQL2005's business intelligence. See, it's nice to learn the greatest features of a product when new version is almost out there. :-)

Well, as probably many others, I almost instantly uninstalled VS2005 after VS2008 was in RTM and running on my machine. Of course, because I also had SQL2005 Developer Edition on here, this meant that SQL Server's BI Studio shortcut wasn't working anymore. Now, fixing that became a priority.

With quick Googling for step-by-step best practise instructions, how to repair the SQL2k5 BI installation, I found some information on Leon Zandman's blog. Unfortunately those steps didn't work for me, it did install VS2005 Premium Partner Edition, but the product itself didn't work. It complained about corrupted packages etc. So instead what I did was:

- I went to edit the SQL2005 installation (in XP: Add/Remove programs, picking SQL2005 and Change)
- I chose SQL Server 2005 Common Components->Workstation Components
- On to change the installed components, I picked first the Business Intelligence Development Studio to be removed and let the installer do the job
- Then same steps and switching the BI Development Studio back to be installed (Entire feature on the local hard drive)

E.g basically simple uninstall/install steps for the specific part of the product and voila, all was working fine. Yes, it means that SQL2k5 BI doesn't work within VS2008, but in VS2005 "shell". I suppose this is fine till SQL2008 comes out.

Sponsor
Posted by joteke | 0 Comments
Filed under: , ,

VS2008 and .NET 3.5 Service Pack 1 Beta now available

See: http://blogs.msdn.com/somasegar/archive/2008/05/12/visual-studio-2008-and-net-fx-3-5-sp1-beta-available-now.aspx

Edit: ScottGu has also a post about the SP: http://weblogs.asp.net/scottgu/archive/2008/05/12/visual-studio-2008-and-net-framework-3-5-service-pack-1-beta.aspx

There are lots of stuff in that SP...

Summary

Web

-ASP.NET Data Scaffolding Support (ASP.NET Dynamic Data)
-ASP.NET Routing Engine (System.Web.Routing)
-ASP.NET AJAX Back/Forward Button History Support
-ASP.NET AJAX Script Combining Support
-Visual Studio 2008 Performance Improvements HTML Designer and HTML Source Editor
-Visual Studio 2008 JavaScript Script Formatting and Code Preferences
-Better Visual Studio Javascript Intellisense for Multiple Javascript/AJAX Frameworks
-Visual Studio Refactoring Support for WCF Services in ASP.NET Projects
-Visual Studio Support for Classic ASP Intellisense and Debugging
-Visual Web Developer Express Edition support for Class Library and Web Application Projects

Client

-Application Startup and Working Set Performance Improvements
-New .NET Framework Client Profile Setup Package
-New .NET Framework Setup Bootstrapper for Client Applications
-ClickOnce Client Application Deployment Improvements
-Windows Forms Controls (Printing, DataRepeater...)
-WPF Performance Improvements
-WPF Data Improvements
-WPF Extensible Shader Effects
-WPF Interoperability with Direct3D
-VS 2008 for WPF Improvements

Data

-SQL 2008 Support
-ADO.NET Entity Framework and LINQ to Entities
-ADO.NET Data Services (formerly code-named "Astoria")

General

-WCF Development Improvements
-VB and C# Improvements
-TFS Improvements

 

Sponsor
Posted by joteke | 0 Comments
Filed under: , ,

A word of warning related to Session variables

I see a lot on forums and newsgroups that Session variables are constantly recommended to pass state between ASP.NET pages. Yes, it is simple mechanism, reliable with out-of-process modes and really nice to customize with the providers. Session is very familiar for developers working with various web technologies (not just Microsoft ones), and one could say that Session is one of the (few) true friends of the web developer.

But have you ever thought that Session variables can also be dangerous if you aren't careful? That's because Session variables are global in users context - the very same feature you usually take advantage of - and if you have small bug or something which allows the same page to be opened twice, you can overwrite variables in manner that you didn't really expect.

Consider this simple ASP.NET page:

<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

    protected void Page_Load(object sender, EventArgs e)
    {
        //This type of line (IsPostback check and setting to Session) is already a warning sign!
        if (!Page.IsPostBack)
            Session["demonstrationvalue"] = Guid.NewGuid().ToString();   
    }
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <a href="sessiondemo.aspx" target="_blank">Open this same page to a new window</a><br />
    Session["demonstrationvalue"] = <%=Session["demonstrationvalue"].ToString() %>.<br />
     <asp:Button ID="btnShowWhatsOnSession" runat="server" Text="Update the view." />
    </div>
    </form>
</body>
</html>

That's a simple page. Now follow these steps:

1. Run the page in your VS2005 or VS2008 so that it opens in your favorite browser and shows you something like:

Open this same page to a new window
Session["demonstrationvalue"] = 9cefe013-59b8-4273-abc5-6ef4ae591a67.

2. Click the link which opens the same page in a new window, you'll see that the session variable now has another value, for example
Session["demonstrationvalue"] = a00de96a-0417-48bd-b8df-9ed26f2d955c.

3. Now switch to the browser window you opened in step 1 and click the "Update the View" button, you'll see that page too now shows
Session["demonstrationvalue"] = a00de96a-0417-48bd-b8df-9ed26f2d955c.

Ok, so what? Well, think if your page would do something like that but having temporary ids whatever in session variables. Yeah, if you haven't thought it out, maybe not your fault but having some legacy code given to you by the boss as previous employee just left, that *is* dangerous. And if your page would have logic to update something to database directly based on that session id, you could be in trouble, updating something that you didn't expect that could happen.

I just want to mention that that one of the worst bugs in my early career was caused by missing this type of little thing (not getting all the possible execution paths of the page clear to myself) :-). A page just got bit complicated eventually, and it was legacy code with lousy structure - which I got for modification - , which made it really, really difficult to spot. Nevertheless, it was 100% my fault, as I should have noticed it (well, I *really* should have done the full rewrite of the application instead of letting it be as it was, but that's another story...).

Now, I hope you don't make the same mistake as I did by then.

Sponsor
Posted by joteke | 2 Comments
Filed under: , ,

I have Framework 3.5 installed, why does my IIS show only ASP.NET 1.1/2.0?

I've replied a lot to these questions lately. 

I'm not going to go to very deep with this, Scott Hanselman has excellent post covering this, see that:

How to set an IIS Application or AppPool to use ASP.NET 3.5 rather than 2.0
http://www.hanselman.com/blog/HowToSetAnIISApplicationOrAppPoolToUseASPNET35RatherThan20.aspx

Simple way is also to think that 3.0 and 3.5 bring "a few more" dlls to 2.0 runtime (which is 2.0 SP 1 in practise). So basically 3.5 is not really that big upgrade to vanilla ASP.NET 2.0, although it certainly isn't any minor upgrade.

Sponsor
Posted by joteke | 0 Comments
Filed under: , ,

DDD Ireland

I promised to spread the word. :-)

Phil and his peers have a developer event, DDD Ireland, in Ireland on 3rd of May. And here's the "official poster" :-)

Developer Event? Ah go on, go on, go on.

DDD Ireland

Check it out at www.DDDIreland.com

Sponsor
Posted by joteke | 0 Comments
Filed under: , , , ,

Unspecified Error with MSDN Library for VS2008 in IE7

My MSDN for VS2008 started suddenly to raise this error.

and I had no idea why. This occurred on my home machine which is XP Pro with latest upgrades. 

I tried following steps:

- I uninstalled and reinstalled entire MSDN Library for VS2008
- I tried to repair IE (basically by reinstalling IE7)
- I even deleted everything from C:\Program Files\Common Files\Microsoft Shared\Help and C:\Program Files\Common Files\Microsoft Shared\Help9 and then un/reinstalled help

Nothing helped.

But I got help on a private discussion list, to try to delete all Temporary Internet Files. And doh! It started to work again... 

Trying to clear all the IE temp file content didn't cross my mind although I've seen weird issues related to it before this. For example hyperlinks sometimes link in totally weird way when IE has "enough" those temporary files, frames might open inside themselves (repeating the opened content) or nothing just happens. Clearing temporary files solves that with no exception.

Sponsor
Posted by joteke | 1 Comments
Filed under: , , ,
More Posts Next page »