Sergey Maskalik

Sergey Maskalik's blog

Focusing on improving tiny bit every day

If you are like me who’d rather work on your own company than come to work. Who has a lot of side projects that keep you up late at night. And you’ve read books on startups and have many more that you want to read, I think you need to know about startup weekends! Why? because I think you have been missing out on a lot of fun and opportunities to connect with people like you are.

For about a month right before the startup weekend I had to work 60-hour work weeks to make this ridiculous deadline at my current day job. I was actually thinking of not going since I was pretty tired. But I sucked it up and drove to Santa Monica on Friday night to join my coworker and about another 100 hungry for success people. It took place at the Coloft, when I got there it was packed with people. Most were drinking beers from a couple of kegs and socializing. Few people came by and introduced themselves and pitched their idea, that was actually kinda interesting to hear their ideas and pick their brain.

After dinner and beer there were few short presentations from facilitators about the whole process, and then they asked people to raise hands who wanted to pitch their idea. I think at first I only saw close to 1/4 of hands raised, I think most people got scared because when the second time they asked I saw more hands. It ended up being about 35 pitches. Each pitch was 60 seconds with no questions and at the end you were given a cup with your name, (oh yea and when you got there they gave you two tickets to vote for the idea that you liked). When I was pitching my idea I had a lot of adrenaline going. When it was over it was an awesome feeling! I actually wanted to do it again. After pitches it turned into chaos, everyone was walking around asking questions and voting for people. I think I had to repeat my idea like 10 times to different people. One nice lady voted for my idea, it was a great feeling lol! I voted for my friend’s idea and he got few other people interested so it was picked as one of 14 ideas.

After people’s ideas got picked, second round of chaos started. Picking team members was not easy. I think we were desperately looking for designer at first. I’ve solicited a couple but they ended up on other more persuasive teams. We were fortunate to end up with a great team of 5 total: two developers, two business people and one finance/database guy.

I think after we got our table we got straight to work. It kinda reminded me of Apprentice TV reality show at the beginning. I remember going back home at 12AM being exhausted not sure what to expect from this weekend, with some nervousness if I could last another two days with no rest.

On Saturday morning we got together around 9 am and started breaking down the work and figuring out minimal viable product. I’ve started setting up webserver, source control, database and I remember I was having issues with my two firewalls and ftp, and wasted a good hour on it. It was kinda stressful since we only had like one day to get things done. I think we had a lot of ups and downs on the first day, it got pretty close to almost quitting until we figured out that we can use one of the sponsors APIs (Factual) for data instead of the data that was not publicly available. I think when we started coding it was already 2PM which was extremely stressful on it’s own. It was cool to see everyone around really working hard on their projects. The energy in the Coloft was amazing, we constantly had sponsors come up and asking if we needed any help, which was very nice of them.

This is what morning looked like… Morning Startup Weekend

Everything was provided , we had breakfast, lunch, dinner, drinks, energy drinks and all kinds of other goodies. Factual gave away hacky sacks. And during the day to relieve some stress we’ve stepped out outside to enjoy the beautiful beach weather and hit up the sack. I think I was very stressed and after the 20 minute game it was all gone, I had a new flow of energy and ready to finish the Saturday strong. We called it a day after 11PM, at that time we had 2 APIs, one from Yelp and other from Factual integrated, a lot of good ideas and content for presentation.

Sunday was mostly about bug fixes and styling. I realized how much I suck at css, it was very frustrating to positing things, luckily, Aurelio, other developer was great at it and took care of most styling. A night before Coloft crew showed us a quick youtube video from Glengarry Glen Ross where Alec Baldwin gives this ball breaking speech with legendary quote “Coffee is for closers”

One of our team members stepped out during lunch to close! He got back with some encouraging results, he closed 6 restaurants out of 10 he visited. We were all pumped up, we had a minimal viable product we had closed accounts we were all set!

I think when the time came to presentations I was more relaxed than before, it was time for our business dev team members to shine giving presentations. Overall I was very happy with what we have achieved. We didn’t win the first place but we did get some interest from incubator sponsors and overall a lot of people were telling us that they’ve liked our project. The weekend in itself was a lot of fun, it did not feel like work or a chore at all. Oh yea and we won Factual’s developers challenge!! That was awesome in itself. It was an extremely satisfying weekend. I left with this renewed confidence that it is possible to succeed as long as you work hard and have same minded people along with you on. Plus I met a lot of good people and discovered a sweet place like Coloft where you can gather with your team and kick ass.

Coming to work on Monday was not hard at all, surprisingly I was not tired at all and full of startup weekend energy!!! I have one advice, don’t let the day job drag you down, keep working on your projects, get together with people like you and no doubt you will succeed. Good luck!

P.S. We are continuing our project after the weekend, which is exciting on it’s own. I will update on progress in the future posts.

We don’t always get to work on the cool stuff like ASP.NET MVC. So for those unfortunate ones we’ll explore some things that can make ASP.NET User Controls follow some patterns and in the end make Web Forms world a better place :)

In ASP.NET, User Controls if designed properly, can play a role of reusable UI components and decrease number of code and markup. It should also make your web project easier to maintain by centralizing code in one location.

Parent Page Contract

I think the most important and challenging task that developer faces when building a user control is to make it independent from the page. For simple controls that don’t require any input or don’t communicate with the page that job is extremely easy.

Traditional way:

On the other hand, most of the controls that we build will require some kind of input from the page. The easiest way is to make a public property on the control and have page set it like so:

public partial class SimpleControl : UserControl
{
    public int MaximumResults { get; set; }
    protected void Page_Load(object sender, EventArgs e)
    {
        for (int i = 0; i < MaximumResults; i++)
        {
            litResults.Text += i.ToString();
        }
    }
}

And set it on the page:

public partial class Default : Page
{
    protected override void OnLoad(EventArgs e)
    {
        ctlSimpleControl.MaximumResults = 5;
        base.OnLoad(e);
    }
}

There is one problem with this, the control requires you to supply that maximum results number and if some other developer than you tries to use this control he will have to read through the code, which won’t be as simple as above and figure out what properties it needs to set. We can improve the situation a little by throwing an exception during OnLoad

protected void Page_Load(object sender, EventArgs e)
{
    if(MaximumResults == 0)
        throw new ConfigurationErrorsException("Missing maximum results");

Programming to an interface:

Another was it to create a “contract” between page and user control, so if anyone wants to use the user control they must implement an interface on the page.

public interface ISimpleControl
{
    int MaximumResults { get; set; }
    int Heigh { get; set; }
    int Width { get; set; }
}

And our user control will communicate with the parent page through that interface, and throw exception if interface is not implemented.

public partial class BetterControl : System.Web.UI.UserControl
{
    public IBetterControl PageContract { get; set; }
    protected override void OnLoad(EventArgs eventArgs)
    {
        PageContract = Page as IBetterControl;
        if (PageContract == null)
        {
            throw new Exception("Parent page does not implement IBetterControl interface");
        }

        for (int i = 0; i < PageContract.MaximumResults; i++)
        {
            litResults.Text += i.ToString();
        }
        base.OnLoad(e);
    }
}

Now if another developer slaps your control on the page without implementing an interface he will get an exception which will let him know what he needs to implement in order for this control to properly work. Like so:

public partial class BetterPage : Page, IBetterControl
{
    public int MaximumResults { get; set; }
    public int Heigh { get; set; }
    public int Width { get; set; }

    protected override void OnLoad(EventArgs e)
    {
        MaximumResults = 4;
        base.OnLoad(e);
    }
}

This way if user intentionally leaves a 0 for MaximumResults property, User Control will work as intended.

Exposing events in your user control.

Let’s say your user control is doing account authentication, it’s always nice if it provides an event to which a parent page can subscribe and act. For example when user successfully authenticates page would execute a method which will redirect to some other page. That way your User Control stays independent from implementation and does only one thing that it meant to do.

public event EventHandler SuccessfulLogin;
protected void OnLoginButtonClick(object sender, EventArgs e)
{
    if(txtUsername.Text == "user" && txtPassword.Text == "password")
    {
        FormsAuthentication.SetAuthCookie("user",true);
        if (SuccessfulLogin != null)
            SuccessfulLogin(this, EventArgs.Empty);
    }
}

Subscribing:

<uc:LoginControl runat="server" OnSuccessfulLogin="OnSuccessfulLogin"></uc:LoginControl>

And implementing on page

public partial class Login : System.Web.UI.Page
{
    protected void OnSuccessfulLogin(object sender, EventArgs e)
    {
        Response.Redirect(FormsAuthentication.DefaultUrl);
    }
}

You can also create a method in the interface similar to the first part with properties. And that’s fine if you must force a page to execute some method. If the event is optional then I think eventhandlers are the way to go.

Other thoughts:

Keep it simple

On a general note, it’s better to keep user controls simple. If your complexity grows and you get lost in settings that your control requires, it’s probably a good time to rethink your design and split some of the code into a page or another user control.

Put code behind into separate libraries

If you are going to be sharing code between projects. It’s a good idea to put code behind into a separate code project, that way if any of the logic changes it will impact all projects.

Create an internal NuGet package

This is definitely a nice way to publish your user control markup and make it updatable with one simple command.

NuGet Creating Packages

Embed your javascript as webresource

If you have a javascript on your user control with some logic, it would not be a bad idea to move that javascript into a code library and make it a webresource. That way javascript code is also centralized and easier to maintain.

Walkthrough: Embedding a JavaScript File as a Resource in an Assembly

Minimize your control’s viewstate.

There is an awesome article that can help you do that here:

TRULY UNDERSTANDING VIEWSTATE

Let me know what you think, or if you have some other ideas please share!

kick it on DotNetKicks.com

I think it’s awesome when sites allow you to stay logged in for long periods of time. As well as asking to re-login when I try to go to some pages where higher level security is needed like account or credit cart pages. It makes me feel warm and secure inside.

Currently one of such examples is Amazon. Once you I log in and lets say come back in few days it will still say a cheerful “Hello Sergey, we have recommendations for you!”, but if I try to go to account page it will ask me to relogin.

In this post I’d like to show how simple and straight forward it is to create “dual” sessions in ASP.NET. One long term not critical session which is always there and doesn’t require SSL, and another which is secure. And if you haven’t logged in for short amount of time will ask you to re-login.

First we have to look at how ASP.NET handles authentication. If you don’t have forms authentication enabled you turn it on like this in web.config

<authentication mode="Forms" />

By default asp.net binds a series of modules in the machine.config that fires depending on your configuration settings. So when the above statement is included it will first run a System.Web.Security.FormsAuthenticationModule on every request which will look if the authentication cookie is there. If cookie is not there default module creates an empty HttpContext.User. And if cookie exists it will decrypt value from the cookie and setup HttpContext.User with that information.

So that’s all nice and standard but how do we have two sessions and create a custom identity that will tell us non secure user information like name as well as keep track if user has a secure session.

Asp.net provides the following authentication extensibility points in order of execution:

  1. HttpModules can subscribe to AuthenticateRequest event of the context
  2. In Global.asax Application_AuthenticateRequest method will get executed once the user identity has been validated.

FormsAuthenticationModule will set a default identity if HttpContext.User in not set in one of those modules.

Let’s begin, first lets create a custom static helper class which will abstract SignIn functionality and creating of two sessions. We’ll call it CustomAuthentication.

public class CustomAuthentication
{
    public static void SetAuthCookies(string userName, string fullName)
    {
        var context = HttpContext.Current;

        FormsAuthenticationTicket identityTicket = new FormsAuthenticationTicket(1, userName, DateTime.Now, DateTime.Now.AddDays(60), true, fullName);
        string encryptedIdentityTicket = FormsAuthentication.Encrypt(identityTicket);
        var identityCookie = new HttpCookie("ASPXIDENT", encryptedIdentityTicket);
        identityCookie.Expires = DateTime.Now.AddDays(60);
        HttpContext.Current.Response.Cookies.Add(identityCookie);

        FormsAuthentication.SetAuthCookie(userName,false);
    }
}

In this method we first create an “identity” cookie which is our long lived cookie, and not designed to be SSL secure but is still encrypted. It has additional data like full name of the person. And we also call regular FormsAuthentication.SetAuthCookie to create an authentication cookie which we set as secure in our web.config and will have 30 minutes expiration.

<authentication mode="Forms">
    <forms loginUrl="~/Account/Login.aspx" timeout="30" requireSSL="true" />
</authentication>

Ok so now on our login page if we call this method we’ll have 2 cookies created a default authentication and identity cookie.

public partial class Login : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        RegisterHyperLink.NavigateUrl = "Register.aspx?ReturnUrl=" + HttpUtility.UrlEncode(Request.QueryString["ReturnUrl"]);
    }

    public void OnLoginClick(object sender, EventArgs e)
    {
        if(true) // this is where you would check if user is valid
        {
            CustomAuthentication.SetAuthCookies("mercury2269", "Sergey Maskalik");
            Response.Redirect("/");
        }
    }

So now when we login we have two cookies one for identity and one for authentication. If you are going to be running a sample project, make sure you set up IIS Express to use ssl, which is pretty easy by clicking on the project name and pressing F4 to project properties and enabling SSL. The login page would not work otherwise.

When we login, we’ll now see two cookies:

Authentication Cookies

So, if we leave it right now we’ll have a generic identity which will expire in 30 minutes. But We want to override it with our own new born identity, so we’ll create a custom identity and HttpModule to get this done.

public class CustomIdentity : GenericIdentity
{
    private string _fullName;

    public CustomIdentity(string userName, string fullName) : base (userName)
    {
        _fullName = fullName;
    }

    public bool HasIdentity
    {
        get { return !string.IsNullOrWhiteSpace(_fullName); }
    }

    public string FullName
    {
        get { return _fullName; }
    }

    public static CustomIdentity EmptyIdentity
    {
        get { return new CustomIdentity("", ""); }
    }
}

We’ll reuse default established identity since that work is already done for us, and basically add two more properties which will say if current user has identity and if it has full name. And since identity cannot be null we’ll create a static helper property to return an empty identity.

public void OnAuthenticateRequest(object sender, EventArgs e)
{
    string identityCookieName = "ASPXIDENT";
    HttpApplication app = (HttpApplication)sender;

    // Get the authentication cookie
    HttpCookie identityCookie = app.Context.Request.Cookies[identityCookieName];

    // If the cookie can't be found don't issue custom authentication
    if (identityCookie == null)
        return;

    // decrypt identity ticket
    FormsAuthenticationTicket identityTicket = (FormsAuthenticationTicket)null;
    try
    {
        identityTicket = FormsAuthentication.Decrypt(identityCookie.Value);
    }
    catch
    {
        app.Context.Request.Cookies.Remove(identityCookieName);
        return;
    }

    string name = "";
    HttpCookie authCookie = app.Context.Request.Cookies[FormsAuthentication.FormsCookieName];
    if (authCookie != null)
    {
        try
        {
            FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
            if (authTicket.Name != identityTicket.Name) return;
            name = authTicket.Name;
        }
        catch
        {
            app.Context.Request.Cookies.Remove(FormsAuthentication.FormsCookieName);
            return;
        }
    }

    var customIdentity = new CustomIdentity(name, identityTicket.UserData);
    var userPrincipal = new GenericPrincipal(customIdentity, new string[0]);
    app.Context.User = userPrincipal;
}

Ok so now when user is logged in we will have a custom identity set, which can be access on pages like so:

(CustomIdentity)HttpContext.Current.User.Identity

We’ll create a helper method to abstract this for us and make it nice and tidy.

public class IdentityHelper
{
    public static CustomIdentity CurrentUser
    {
        get
        {
            if (HttpContext.Current.User.Identity is CustomIdentity)
                return (CustomIdentity)HttpContext.Current.User.Identity;

            return CustomIdentity.EmptyIdentity;
        }
    }
}

Now we’ll add module to web.config

<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
    <add name="CustomAuthentication" type="CustomAuthenticationSample.Application.CustomAuthenticationModule, CustomAuthenticationSample"/>
</modules>

And that’s it! We can now access our new custom identity by simply calling our IdentityHelper class and make decisions based on it.

if(IdentityHelper.CurrentUser.HasIdentity)
{
    lblIdentityInfo.Text = "Whoo hoo User has identity, full name is: " + IdentityHelper.CurrentUser.FullName;
}

if(IdentityHelper.CurrentUser.IsAuthenticated)
{
    lblIdentityInfo.Text += "<br />User has secure authentication session";
}

Now when we login on secure page we’ll have secure pages

And if secure session is expired or not over https unsecure pages

So now we have a long lived session that will persist for 60 days and a secure session which will expire in 30 minutes.

I’d like to hear your opinion and please post comments if you have any questions!

Project code sample

kick it on DotNetKicks.com