<?xml version="1.0" encoding="utf-8"?>
<rss
  version="2.0">
  <channel>
    <title>Posts</title>
    <link>https://volaresoftware.com/en</link>
    <description>Volare Software</description>
    <lastBuildDate>Tue, 08 Aug 2023 17:49:16 Z</lastBuildDate>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/articles/unlocking-the-power-of-custom-software-is-it-worth-the-investment</guid>
      <link>https://volaresoftware.com/en/articles/unlocking-the-power-of-custom-software-is-it-worth-the-investment</link>
      <title>Unlocking the Power of Custom Software: Is It Worth the Investment?</title>
      <description>&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;p&gt;In a world driven by technological advancements, companies are constantly looking for innovative solutions to gain a competitive edge. Many companies consider custom software, but concerns about cost can make decision-makers hesitate. Like a carefully tailored bespoke suit, custom software comes with a price tag. However, custom software is an investment that can provide a significant return on investment by saving money and generating significant revenue. Let's explore the value of custom software development and why it's a worthwhile investment for many companies.&lt;/p&gt;
&lt;h3 id="the-expense-of-custom-software-development"&gt;The Expense of Custom Software Development&lt;/h3&gt;
&lt;p&gt;Custom software development involves the creation of tailored solutions to meet specific business needs. This level of customization requires time, expertise, and resources, resulting in a higher upfront cost compared to off-the-shelf software solutions. However, it's important to understand that the cost of custom software is relative to the long-term benefits it brings to an organization.&lt;/p&gt;
&lt;h3 id="the-value-of-custom-software-as-an-investment"&gt;The Value of Custom Software as an Investment&lt;/h3&gt;
&lt;h4 id="cost-savings"&gt;Cost Savings&lt;/h4&gt;
&lt;p&gt;While the initial cost may seem daunting, custom software can actually save businesses a significant amount of money in the long run. By streamlining processes, automating repetitive tasks, and eliminating the need for multiple software licenses, companies can reduce operating costs and increase efficiency. Custom software is designed to fit seamlessly into existing workflows, eliminating the need for costly workarounds or manual intervention.&lt;/p&gt;
&lt;h4 id="increased-revenue-generation"&gt;Increased Revenue Generation&lt;/h4&gt;
&lt;p&gt;Custom software has the potential to create new revenue streams and accelerate business growth. By tailoring software to meet unique business needs, companies can enhance their ability to deliver exceptional customer experiences, increase productivity, and seize new market opportunities. The ability to provide personalized services, adapt to changing customer demands, and differentiate from competitors can lead to increased customer satisfaction, loyalty, and ultimately, increased revenue.&lt;/p&gt;
&lt;h3 id="factors-influencing-the-cost-of-custom-software"&gt;Factors Influencing the Cost of Custom Software&lt;/h3&gt;
&lt;h4 id="complexity"&gt;Complexity&lt;/h4&gt;
&lt;p&gt;The complexity of the software solution is a critical factor in determining the total cost. Projects with complex functionality, integration with existing systems, or extensive scalability requirements may require more time and resources to develop, resulting in a higher investment.&lt;/p&gt;
&lt;h4 id="development-team-expertise"&gt;Development Team Expertise&lt;/h4&gt;
&lt;p&gt;The skills and experience of the development team play an important role in estimating costs. Highly skilled professionals with expertise in specific technologies may have higher rates, but their skills can ensure a more efficient and effective development process, reducing overall project costs.&lt;/p&gt;
&lt;h4 id="development-team-location"&gt;Development Team Location&lt;/h4&gt;
&lt;p&gt;Consider offshore outsourcing as an alternative to reduce custom software development costs. Check out this article to explore some pros and cons of offshore outsourcing.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;While custom software development may involve a higher initial investment, it's important to view it as a strategic business decision. Like a bespoke suit that fits perfectly, custom software is tailored to meet the unique needs of your business. By reducing costs, increasing operational efficiency, and driving revenue growth, custom software becomes a valuable asset that can help your business thrive. Embrace the power of custom software and experience the transformation it can bring to your organization's productivity, competitiveness, and profitability.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://volaresoftware.com/en/contact"&gt;Contact Volare Software today&lt;/a&gt; for more information about &lt;a href="https://volaresoftware.com/en/services/custom-software-development"&gt;tailoring custom software&lt;/a&gt; to your business.&lt;/p&gt;
</description>
      <pubDate>Tue, 08 Aug 2023 17:49:16 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/articles/advantages-of-hiring-a-business-driven-custom-software-consultancy</guid>
      <link>https://volaresoftware.com/en/articles/advantages-of-hiring-a-business-driven-custom-software-consultancy</link>
      <title>Advantages of hiring a business-driven custom software consultancy</title>
      <description>&lt;p&gt;In the fast-paced world of tech, everyone talks about coding skills, and rightly so. But what if I told you that to make your custom software truly shine, you need more than just a whiz with code? Let's explore why having a software consultancy that understands your business can make all the difference.&lt;/p&gt;
&lt;p&gt;Coding may top everyone's list, but the real magic happens when it is paired with a deep understanding of your business. A software consultancy with hands-on experience in your industry isn't just about making the code work; it's about tailoring it to fit your unique needs. This special understanding ensures that the software isn't just functional; it aligns perfectly with what makes your business tick.&lt;/p&gt;
&lt;p&gt;Now, envision possessing a software solution that not only resolves your current challenges but also evolves hand in hand with your business growth. A software consultant with business experience doesn't stop at coding; they architect solutions for enduring efficiency. It's not just about saving money; it's about sparing you time and the headaches of constant fixes. By aligning your software with your business strategy, they create a robust foundation that adapts and grows with you, providing you with peace of mind and saving you from costly disruptions down the line.&lt;/p&gt;
&lt;p&gt;Engaging with a software consultancy with business experience brings a refreshing perspective. External consultants offer innovative ideas and solutions that your in-house team might overlook. They act as guides, foreseeing potential roadblocks and steering your software development journey toward success. Their diverse experiences enhance problem-solving, making your team more adaptable and creative, leading to a software product that not only meets but exceeds your expectations.&lt;/p&gt;
&lt;p&gt;An experienced business leader in your software development team forms a bridge between the technical details and your big-picture business goals. It's not just about writing code; it's about crafting a software solution that aligns precisely with your vision, goals, and the expectations of your customers and employees. An adept business-savvy developer ensures your team stays on track, preventing any deviation from your goals.&lt;/p&gt;
&lt;p&gt;In this world where every line of code propels progress, business experience in custom software consultancy becomes the secret ingredient. Coding remains essential, but understanding your business emerges as the heartbeat of your project. Now, as a customer, you have the opportunity to choose a partner who doesn't just write code but engineers solutions that not only drive your business toward success but also leaves you feeling empowered, relieved, and confident in the transformative impact on your organization. With business-savvy custom software, you receive not only a technological solution but a catalyst for elevated customer praise, organizational efficiency, and an overall sense of peace on your business journey.&lt;/p&gt;
</description>
      <pubDate>Sun, 28 Apr 2024 19:49:26 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/articles/should-you-go-with-an-offshore-team-for-your-custom-software-development-project</guid>
      <link>https://volaresoftware.com/en/articles/should-you-go-with-an-offshore-team-for-your-custom-software-development-project</link>
      <title>Should you go with an offshore team for your custom software development project?</title>
      <description>&lt;p&gt;Are you trying to decide whether to work with an offshore team for your next software development project?&lt;/p&gt;
&lt;p&gt;Offshore teams offer cost savings and the ability to work with a larger team, but there are potential risks to consider. Language barriers, cultural differences, and time zone differences can all hinder the project's success.&lt;/p&gt;
&lt;p&gt;We'll explore the advantages and disadvantages of working with an offshore team and how to mitigate the potential risks.&lt;/p&gt;
&lt;h3 id="advantages-cost-savings-and-a-larger-team"&gt;Advantages: Cost Savings and a Larger Team&lt;/h3&gt;
&lt;p&gt;One of the most significant advantages of working with an offshore team is cost savings. Offshore teams are generally much cheaper than US-based or western Europe-based teams due to lower labor costs in other countries. This cost savings allow companies to invest more resources into other areas of their business, making it an attractive option for those looking to maximize their budget.&lt;/p&gt;
&lt;p&gt;Another benefit of offshore teams is the ability to work with a larger team. Offshore teams can provide access to a more extensive pool of talent, allowing companies to take on more significant projects or multiple projects simultaneously. This can be particularly useful for businesses that need to scale their development efforts quickly.&lt;/p&gt;
&lt;h3 id="disadvantages-languages-cultures-and-time-zones"&gt;Disadvantages: Languages, Cultures, and Time Zones&lt;/h3&gt;
&lt;p&gt;One of the primary disadvantages of working with an offshore team is the potential for language, culture, and time zone differences. These factors can make communication difficult, which can lead to delays in delivery and potentially hinder the project's success.This can lead to rework, additional costs, and ultimately delay the project's delivery.&lt;/p&gt;
&lt;h3 id="how-to-mitigate-the-risks"&gt;How to Mitigate the Risks&lt;/h3&gt;
&lt;p&gt;While there are potential risks to working with an offshore team, there are ways to mitigate them.&lt;/p&gt;
&lt;p&gt;First, companies should choose a reputable software development partner with a proven track record and good references. Working with an established team can reduce the risk of communication problems and delays.&lt;/p&gt;
&lt;p&gt;Establish clear communication protocols and use technology to bridge the distance. Video conferencing, chat software, and project management tools can help keep everyone on the same page.&lt;/p&gt;
&lt;p&gt;Finally, companies can ensure the quality of the work by providing clear project requirements, reviewing the code in progress during development, and providing feeback to the team to ensure the software built matches your needs.&lt;/p&gt;
&lt;h3 id="conclusion"&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;At Volare Software, we understand the importance of choosing the right development team for your custom software project. That's why we offer US-based, western Europe-based, and offshore teams to fit your specific business and project needs.&lt;/p&gt;
&lt;p&gt;We prioritize communication and transparency to ensure the success of your project, and you will see working software demonstated at the end of every iteration (usually every 1-3 weeks). We ask for your feedback on the in-progress software so we can make adjustments to build exactly the software you need.&lt;/p&gt;
&lt;p&gt;So if you're struggling to decide about hiring an offshore team, let Volare Software help guide you to the best decision for your business. &lt;a href="https://volaresoftware.com/en/contact"&gt;Contact us today&lt;/a&gt; to learn more.&lt;/p&gt;
</description>
      <pubDate>Sun, 02 Apr 2023 18:25:24 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/mocking-calls-with-jasmine</guid>
      <link>https://volaresoftware.com/en/technical-posts/mocking-calls-with-jasmine</link>
      <title>Mocking calls with Jasmine</title>
      <description>&lt;p&gt;This post and the examples have been updated to the latest release of Jasmine, which is currently 3.5.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://jasmine.github.io/"&gt;Jasmine&lt;/a&gt; is a simple, &lt;a href="https://en.wikipedia.org/wiki/Behavior-driven_development"&gt;BDD&lt;/a&gt;-style JavaScript testing framework, but to benefit from the full power out of the framework, you need to know how to mock calls the Jasmine way.&lt;/p&gt;
&lt;p&gt;Jasmine uses &lt;a href="https://jasmine.github.io/api/edge/global.html#spyOn"&gt;spies&lt;/a&gt; to mock asynchronous and synchronous function calls. As with most mocking frameworks, you can set the externally observed behavior of the code you are mocking.&lt;/p&gt;
&lt;h2 id="using-jasmine-spies-to-mock-code"&gt;Using Jasmine spies to mock code&lt;/h2&gt;
&lt;p&gt;Jasmine spies are easy to set up.  You set the object and function you want to spy on, and that code won't be executed.&lt;/p&gt;
&lt;p&gt;In the code below, we have a &lt;code&gt;MyApp&lt;/code&gt; module with a flag property and a &lt;code&gt;setFlag()&lt;/code&gt; function exposed.  We also have an instance of that module called &lt;code&gt;myApp&lt;/code&gt; in the test.  To spy on the &lt;code&gt;myApp.setFlag()&lt;/code&gt; function, we use:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;spyOn(myApp, &amp;quot;setFlag&amp;quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It's a little strange that in Jasmine, you have to put the function you want to spy on in quotes, but that's the API.&lt;/p&gt;
&lt;p&gt;When you spy on a function &lt;a href="https://jsfiddle.net/joewilson0/z739u7LL/"&gt;like this&lt;/a&gt;, the original code is not executed.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;// Code under test
var MyApp = function () {
    var testAsync = function () {
        // Do something that takes a long time...
    };
&lt;pre&gt;&lt;code&gt;var callSomethingThatUsesAsync = function () {
    // Get a jQuery deferred
    var deferred = $.Deferred();

    // Make an async call and do something when it's completed based on success/failure
    this.testAsync()
    .done(function () {
        // Resolve the deferred
        deferred.resolve(&amp;amp;quot;The async call succeeded&amp;amp;quot;);
    })
    .fail(function () {
        // Reject the deferred
        deferred.reject(&amp;amp;quot;The async call failed&amp;amp;quot;);
    });

    return deferred.promise();
};

return {
    testAsync: testAsync,
    callSomethingThatUsesAsync: callSomethingThatUsesAsync
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;};&lt;/p&gt;
&lt;p&gt;// Test helpers
var JasmineHelpers = function () {&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var deferredSuccess = function (args) {
    var d = $.Deferred();
    d.resolve(args);
    return d.promise();
};

var deferredFailure = function (args) {
    var d = $.Deferred();
    d.reject(args);
    return d.promise();
};

return {
    deferredSuccess: deferredSuccess,
    deferredFailure: deferredFailure
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;};&lt;/p&gt;
&lt;p&gt;// Specs
describe(&amp;quot;Testing spies&amp;quot;, function () {
var jasmineHelpers = new JasmineHelpers();&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;it(&amp;amp;quot;Should spy on async calls and use helpers to mock success/failure&amp;amp;quot;, function () {
    // Arrange
    var myApp = new MyApp();
    spyOn(myApp, &amp;amp;quot;testAsync&amp;amp;quot;).and.callFake(function () {
        return jasmineHelpers.deferredSuccess();
    });

    // Act
    myApp.callSomethingThatUsesAsync()
    .always(function (result) {
        // Assert
        expect(result).toEqual(&amp;amp;quot;The async call succeeded&amp;amp;quot;);
    });
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;});
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="returning-values-from-jasmine-spies"&gt;Returning values from Jasmine spies&lt;/h2&gt;
&lt;p&gt;Most of the time when setting up mocks, you want to set return values so you can test a specific code path. Again, this is easy to do with Jasmine.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://jsfiddle.net/joewilson0/cvo1nps5/"&gt;Here&lt;/a&gt;, I show setting the return value of a function so we can test specific branches in the code and skip over the real &lt;code&gt;getFlag()&lt;/code&gt; function, which is hard-coded to return false.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;// Code under test
var MyApp = function () {
    var getFlag = function () {
        return false;
    };
&lt;pre&gt;&lt;code&gt;var useFlagForSomething = function () {
    if (this.getFlag() === true) {
        return &amp;amp;quot;It was true&amp;amp;quot;;
    } else {
        return &amp;amp;quot;It was false&amp;amp;quot;;
    }
};

return {
    getFlag: getFlag,
    useFlagForSomething: useFlagForSomething
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;};&lt;/p&gt;
&lt;p&gt;// Specs
describe(&amp;quot;Testing spies&amp;quot;, function () {&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;it(&amp;amp;quot;Should replace the return value of function being spied on&amp;amp;quot;, function () {
    // Arrange
    var myApp = new MyApp();
    spyOn(myApp, &amp;amp;quot;getFlag&amp;amp;quot;).and.returnValue(true);

    // Act
    var result = myApp.useFlagForSomething();

    // Assert
    expect(result).toEqual(&amp;amp;quot;It was true&amp;amp;quot;);
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;});
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;The key piece is intercepting the &lt;code&gt;getFlag()&lt;/code&gt; function with the spy and setting the value the substituted function returns:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;spyOn(myApp, &amp;quot;getFlag&amp;quot;).and.returnValue(true);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sometimes, setting a &lt;code&gt;returnValue&lt;/code&gt; isn't enough. If you need to replace the function you are mocking, you can use:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;spyOn(myApp, &amp;quot;useFlagForSomething&amp;quot;).and.callFake(function() {
    return &amp;quot;I'm replacing the real function with this&amp;quot;;
});
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="using-jasmine-spies-to-verify-code-was-called"&gt;Using Jasmine spies to verify code was called&lt;/h2&gt;
&lt;p&gt;You can also call the original code with a spy. This may sound pointless (why set up a mock and then call the real code?) unless you think about interaction testing, where it's important to know that a function was or was not called.&lt;/p&gt;
&lt;p&gt;The syntax to call the original code but still spy on the function is:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;spyOn(myApp, &amp;quot;getFlag&amp;quot;).and.callThrough();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The code below shows how you can verify a spied on function was called. We have a new function called &lt;code&gt;reallyImportantProcess()&lt;/code&gt;.  We have to test to make sure it's being run under the right conditions, and we know it should run when &lt;code&gt;getFlag()&lt;/code&gt; returns &lt;code&gt;false&lt;/code&gt;, which is the default value. So we don't need to mock or change &lt;code&gt;getFalse()&lt;/code&gt; to take this code branch, but we do need to &lt;code&gt;spyOn reallyImportantProcess()&lt;/code&gt; to verify it gets called.&lt;/p&gt;
&lt;p&gt;In &lt;a href="https://jsfiddle.net/joewilson0/Lucxt850/"&gt;this spy&lt;/a&gt;, we have lots of options. We could skip calling the real code, as we do below, or we could set up specific return values or substitute our own function for that function, or we could call the original code with &lt;code&gt;callThrough()&lt;/code&gt;. When you set up Jasmine spies, you can use any spy configuration and still see if it was called later with and &lt;code&gt;toHaveBeenCalled()&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;// Code under test
var MyApp = function () {
    var getFlag = function () {
        return false;
    };
&lt;pre&gt;&lt;code&gt;var reallyImporatantProcess = function () {
    // Do something really important
};

var useFlagForSomething = function () {
    if (this.getFlag() === true) {
        return &amp;amp;quot;It was true&amp;amp;quot;;
    } else {
        this.reallyImporatantProcess();
        return &amp;amp;quot;It was false&amp;amp;quot;;
    }
};

return {
    getFlag: getFlag,
    reallyImporatantProcess: reallyImporatantProcess,
    useFlagForSomething: useFlagForSomething
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;};&lt;/p&gt;
&lt;p&gt;// Specs
describe(&amp;quot;Testing spies&amp;quot;, function () {&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;it(&amp;amp;quot;Should verify a spy was called&amp;amp;quot;, function () {
    // Arrange
    var myApp = new MyApp();
    spyOn(myApp, &amp;amp;quot;reallyImporatantProcess&amp;amp;quot;);

    // Act
    var result = myApp.useFlagForSomething();

    // Assert
    expect(myApp.reallyImporatantProcess).toHaveBeenCalled();
    expect(result).toEqual(&amp;amp;quot;It was false&amp;amp;quot;);
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;});
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;You can also test that a spied on function was NOT called with:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;expect(myApp.reallyImportantProcess).not.toHaveBeenCalled();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or you can go further with your interaction testing to assert on the spied on function being called with specific arguments like:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;expect(myApp.reallyImportantProcess).toHaveBeenCalledWith(123, &amp;quot;abc&amp;quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="testing-async-calls-in-jasmine-with-jquerys-deferred-and-helpers"&gt;Testing async calls in Jasmine with jQuery's Deferred and helpers&lt;/h2&gt;
&lt;p&gt;Async calls are a big part of JavaScript.  Most code dealing with async calls these day works through promises or callbacks.&lt;/p&gt;
&lt;p&gt;Here, some test helper code can be used to mock promises being returned from an async call. I'm using &lt;a href="https://api.jquery.com/category/deferred-object/"&gt;jQuery's $.Deferred() object&lt;/a&gt;, but any promise framework should work the same.&lt;/p&gt;
&lt;p&gt;You can mock an async success or failure, pass in anything you want the mocked async call to return, and test how your code handles it:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;var JasmineHelpers = function () {
&lt;pre&gt;&lt;code&gt;var deferredSuccess = function (args) {
    var d = $.Deferred();
    d.resolve(args);
    return d.promise();
};

var deferredFailure = function (args) {
    var d = $.Deferred();
    d.reject(args);
    return d.promise();
};

return {
    deferredSuccess: deferredSuccess,
    deferredFailure: deferredFailure
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;};
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Here is some Jasmine spy code using these async helpers. Again, we use jQuery &lt;code&gt;$.Deferred()&lt;/code&gt; object to set up a function that calls out to a pretend async call named &lt;code&gt;testAsync()&lt;/code&gt;.  It's invoked by &lt;code&gt;callSomethingThatUsesAsync()&lt;/code&gt;, which is the function we're testing.  We want to mock the &lt;code&gt;testAsync()&lt;/code&gt; call (maybe it goes off to the database and takes a while), and we want to assert that when that &lt;code&gt;testAsync()&lt;/code&gt; call succeeds, &lt;code&gt;callSomethingThatUsesAsync()&lt;/code&gt; goes on to give us a text message saying it succeeded.&lt;/p&gt;
&lt;p&gt;Since the function under test is using a promise, we need to wait until the promise has completed before we can start asserting, but we want to assert whether it fails or succeeds, so we'll put our assert code in the &lt;code&gt;always()&lt;/code&gt; function.  The &lt;code&gt;done()&lt;/code&gt;, &lt;code&gt;fail()&lt;/code&gt;, and &lt;code&gt;always()&lt;/code&gt; functions are promise code - (actually, jQuery &lt;code&gt;$.Deferred&lt;/code&gt; code if you want to be technical) they are not specific to Jasmine.&lt;/p&gt;
&lt;h2 id="testing-async-calls-in-jasmine-with-jasmines-done-callback"&gt;Testing async calls in Jasmine with Jasmine's done() callback&lt;/h2&gt;
&lt;p&gt;Testing synchronous specs is easy, but asynchronous testing requires some additional work.&lt;/p&gt;
&lt;p&gt;For example, &lt;a href="https://jsfiddle.net/joewilson0/yt13dnrt/"&gt;the code below&lt;/a&gt; fails because Jasmine evaluates the &lt;code&gt;expect()&lt;/code&gt; piece before the &lt;code&gt;testAsync()&lt;/code&gt; function has finished its work.  The &lt;code&gt;setTimeout()&lt;/code&gt; call forces a two second delay, but Jasmine has already moved on and failed the test before the &lt;code&gt;setTimeout()&lt;/code&gt; completes:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;// Code under test
var flag = false;
&lt;p flag="true;"&gt;function testAsync(done) {
// Wait two seconds, then set the flag to true
setTimeout(function () , 2000);
}&lt;/p&gt;
&lt;p&gt;// Specs
describe(&amp;quot;Testing async calls&amp;quot;, function () {&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;it(&amp;amp;quot;Should be true if the async call has completed&amp;amp;quot;, function () {
    expect(flag).toEqual(true);
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;});
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;With Jasmine async testing, we have to call the async code in the &lt;code&gt;beforeEach()&lt;/code&gt; function that runs before each &lt;code&gt;it()&lt;/code&gt; function block within a &lt;code&gt;describe()&lt;/code&gt; function block.&lt;/p&gt;
&lt;p&gt;We also have to let Jasmine know when the async function has completed by calling the special &lt;code&gt;done()&lt;/code&gt; callback function Jasmine provides. &lt;a href="https://jsfiddle.net/joewilson0/5bcr0uro/"&gt;Here&lt;/a&gt;, we are passing this special &lt;code&gt;done()&lt;/code&gt; callback around so our code under test can invoke it.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;// Code under test
var flag = false;
&lt;p&gt;function testAsync(done) {
// Wait two seconds, then set the flag to true
setTimeout(function () {
flag = true;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    // Invoke the special done callback
    done();
}, 2000);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;// Specs
describe(&amp;quot;Testing async calls with beforeEach and passing the special done callback around&amp;quot;, function () {&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;beforeEach(function (done) {
    // Make an async call, passing the special done callback        
    testAsync(done);
});

it(&amp;amp;quot;Should be true if the async call has completed&amp;amp;quot;, function () {
    expect(flag).toEqual(true);
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;});
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;This works, but changing the code under test to accept the &lt;code&gt;done()&lt;/code&gt; callback argument and invoke it may not be realistic. Why would you change your code under test just to make the testing framework happy?&lt;/p&gt;
&lt;p&gt;Instead, you can use promises and call the special Jasmine &lt;code&gt;done()&lt;/code&gt; callback when your promise has resolved. Note that the Jasmine &lt;code&gt;done()&lt;/code&gt; callback is NOT the same as the promise's &lt;code&gt;done()&lt;/code&gt; callback. They just use the same function name.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://jsfiddle.net/joewilson0/yf8Lnfma/"&gt;Here&lt;/a&gt;, I'm using &lt;a href="https://api.jquery.com/category/deferred-object/"&gt;jQuery's $.Deferred() object&lt;/a&gt; for the promises, but this approach should work with any promises library.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;// Code under test
var flag = false;
&lt;p&gt;function testAsyncWithDeferred() {
// Get a jQuery deferred
var deferred = $.Deferred();&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Wait two seconds, then set the flag to true
setTimeout(function () {
    flag = true;

    // Resolve the deferred
    deferred.resolve();
}, 2000);

// Return the deferred promise
return deferred.promise();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;// Specs
describe(&amp;quot;Testing async calls with beforeEach and invoking the special done callback in the promise's done callback&amp;quot;, function () {&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;beforeEach(function(done) {
    testAsyncWithDeferred()
    .done(function (result) {
        // Invoke the special done callback
        done();
    });
});
           
it(&amp;amp;quot;Should be true if the async call has completed&amp;amp;quot;, function () {
    expect(flag).toEqual(true);
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;});
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;You can even use the data returned from the promise in the test once it is resolved. &lt;a href="https://jsfiddle.net/joewilson0/b5vft6xy/"&gt;Here&lt;/a&gt; we are passing the return value in the &lt;code&gt;deferred.resolve()&lt;/code&gt; call:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;// Code under test
function testAsyncWithDeferredReturnValue() {
    // Get a jQuery deferred
    var deferred = $.Deferred();
&lt;pre&gt;&lt;code&gt;// Wait two seconds, then set the return true
setTimeout(function () {
    // Resolve the deferred
    deferred.resolve(true);
}, 2000);

// Return the deferred promise
return deferred.promise();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;// Specs
describe(&amp;quot;Testing async calls with beforeEach and invoking the special done callback in the promise's done callback and using the promise's return data&amp;quot;, function () {
var flag = false;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;beforeEach(function (done) {
    testAsyncWithDeferredReturnValue()
    .done(function (result) {
        flag = result;
        
        // Invoke the special done callback
        done();
    });
});

it(&amp;amp;quot;Should be true if the async call has completed&amp;amp;quot;, function () {
    expect(flag).toEqual(true);
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;});
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;But of course, real-world applications can't get away with simply testing with &lt;code&gt;setTimeout&lt;/code&gt; and &lt;code&gt;true&lt;/code&gt;/&lt;code&gt;false&lt;/code&gt; flags, so &lt;a href="https://jsfiddle.net/joewilson0/k45Lypwo/"&gt;here&lt;/a&gt; is a more real-world example.&lt;/p&gt;
&lt;p&gt;It calls &lt;code&gt;$.getJSON()&lt;/code&gt; to go fetch some public JSON data in the &lt;code&gt;beforeEach()&lt;/code&gt; function, and then tests the returned JSON in the &lt;code&gt;it()&lt;/code&gt; block to make sure it isn't an empty object or undefined.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;// Code under test
function testAsyncRealWorld() {
    // Get a jQuery deferred
    var deferred = $.Deferred();
    
    // Real world data call
    var data = $.getJSON(&amp;quot;https://data.colorado.gov/resource/4ykn-tg5h.json&amp;quot;, function() {
    	deferred.resolve(true);
    });
    
    // Return the deferred promise
    return deferred.promise();
}
&lt;p&gt;// Specs
describe(&amp;quot;Testing async calls with real-world data&amp;quot;, function () {
var data = null;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;beforeEach(function (done) {
    testAsyncRealWorld()
    .done(function (result) {
        data = result;
        
        // Invoke the special done callback
        done();
    });
});

it(&amp;amp;quot;Should have result if the async call has completed&amp;amp;quot;, function () {
    expect(data).not.toBeNull();
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;});
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="testing-async-calls-in-jasmine-with-asyncawait"&gt;Testing async calls in Jasmine with async/await&lt;/h2&gt;
&lt;p&gt;With version 2.8 and later of Jasmine and your compiler that supports async/await (e.g., Babel, TypeScript), you can change this to be more readable:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;describe(&amp;quot;Testing async functions&amp;quot;, () =&amp;gt; {
  
  it(&amp;quot;Should work with async/await&amp;quot;, async () =&amp;gt; {
    // Arrange
    let flag = false;
&lt;pre&gt;&lt;code&gt;// Act
flag = await returnTrueAsync();

// Assert
expect(flag).toBeTruthy();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;});&lt;/p&gt;
&lt;p&gt;});&lt;/p&gt;
&lt;p&gt;function returnTrueAsync() {
return new Promise(resolve =&amp;gt; {
setTimeout(() =&amp;gt; {
resolve(true);
}, 1000);
});
}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://jsfiddle.net/joewilson0/k1wyby9m/"&gt;Much cleaner&lt;/a&gt;!&lt;/p&gt;
</description>
      <pubDate>Tue, 14 Apr 2020 06:00:00 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/autocomplete-dropdown-with-jquery-ui-and-mvc</guid>
      <link>https://volaresoftware.com/en/technical-posts/autocomplete-dropdown-with-jquery-ui-and-mvc</link>
      <title>Autocomplete dropdown with jQuery UI and MVC</title>
      <description>&lt;p&gt;You know the &lt;a href="http://jqueryui.com/demos/autocomplete/"&gt;autocomplete dropdown&lt;/a&gt;.  It has become ubiquitous, and customers now expect them in their web apps.  &amp;quot;Can't you just set autocomplete=true or something?&amp;quot;  It's not quite that easy with &lt;a href="http://www.asp.net/mvc"&gt;ASP.NET MVC&lt;/a&gt;, but it's pretty simple.&lt;/p&gt;
&lt;p&gt;We want to set up a text box on a web page that uses &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt; to call back to a controller action as the user types.  The action method will return a &lt;a href="http://www.json.org/"&gt;JSON&lt;/a&gt; array of values that match what the user has typed so far.  Each time they type and pause for a second, the screen should show the new matching records.&lt;/p&gt;
&lt;h2 id="the-view"&gt;The view&lt;/h2&gt;
&lt;p&gt;First, we'll work on the view.  Set a reference to jQuery and to &lt;a href="http://jqueryui.com/"&gt;jQuery UI&lt;/a&gt;.  These are included with new MVC 3 projects (look in the Scripts folder), or you can find a &lt;a href="http://code.google.com/apis/libraries/devguide.html#jqueryUI"&gt;CDN&lt;/a&gt; and reference them there.  I've got this in my view's head section:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Autocomplete Test &amp;lt;/title&amp;gt;
    &amp;lt;script src=&amp;quot;&amp;lt;%: Url.Content(&amp;quot;~/Scripts/jquery-1.4.4.min.js&amp;quot;)%&amp;gt;&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src=&amp;quot;&amp;lt;%: Url.Content(&amp;quot;~/Scripts/jquery-ui.min.js&amp;quot;)%&amp;gt;&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then you need a text box to tie all this too.  The search results will be shown under this text box to give the appearance of a dropdown.  This simple form should do:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;form action=&amp;quot;/Search/ProcessTheForm&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;
    &amp;lt;input id=&amp;quot;searchTerm&amp;quot; name=&amp;quot;searchTerm&amp;quot; type=&amp;quot;text&amp;quot; /&amp;gt;
    &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Go&amp;quot; /&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, you'll need to use the autocomplete function in jQuery UI like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;
    $(function () {
        $(&amp;quot;#searchTerm&amp;quot;).autocomplete({
            source: &amp;quot;/Search/AutocompleteSuggestions&amp;quot;,
            minLength: 3,
            select: function (event, ui) {
                if (ui.item) {
                    $(&amp;quot;#searchTerm&amp;quot;).val(ui.item.value);
                    $(&amp;quot;form&amp;quot;).submit();
                }
            }
        });
    });
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here we've got a jQuery selector binding the autocomplete function to the searchTerm input box(&amp;quot;#searchTerm&amp;quot;).  We then set the URL for the source for the autocomplete suggestions, which in this case, will be our controller (Search) and action method (AutocompleteSuggestions).  Then we set the number of characters the user has to type before we make the first call.  It's set to three here to prevent pulling back meaningless matches from searching too soon.&lt;/p&gt;
&lt;p&gt;Finally, we set up the autocomplete function's select event to set the selected value from the dropdown list as the value in the searchTerm input box and submit the form to the Search controller and the ProcessTheForm action method.&lt;/p&gt;
&lt;p&gt;Here's the entire view for reference:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;%@ Page Language=&amp;quot;C#&amp;quot; Inherits=&amp;quot;System.Web.Mvc.ViewPage&amp;lt;dynamic&amp;gt;&amp;quot; %&amp;gt;
&lt;p&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;title&amp;gt;Autocomplete Test&amp;lt;/title&amp;gt;
&amp;lt;script src=&amp;quot;&amp;lt;%: Url.Content(&amp;quot;&lt;sub&gt;/Scripts/jquery-1.4.4.min.js&amp;quot;)%&amp;gt;&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src=&amp;quot;&amp;lt;%: Url.Content(&amp;quot;&lt;/sub&gt;/Scripts/jquery-ui.min.js&amp;quot;)%&amp;gt;&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;form action=&amp;quot;/Search/ProcessTheForm&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;
&amp;lt;input id=&amp;quot;searchTerm&amp;quot; name=&amp;quot;searchTerm&amp;quot; type=&amp;quot;text&amp;quot; /&amp;gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Go&amp;quot; /&amp;gt;
&amp;lt;/form&amp;gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;
$(function () {
$(&amp;quot;#searchTerm&amp;quot;).autocomplete({
source: &amp;quot;/Search/AutocompleteSuggestions&amp;quot;,
minLength: 3,
select: function (event, ui) {
if (ui.item) {
$(&amp;quot;#searchTerm&amp;quot;).val(ui.item.value);
$(&amp;quot;form&amp;quot;).submit();
}
}
});
});
&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="the-controller"&gt;The controller&lt;/h2&gt;
&lt;p&gt;Now you need to write something that will return the records that match what the user has entered so far.  This might be a database call with a LIKE searchTerm + &amp;quot;%&amp;quot; (watch out for SQL injection, though) or SOUNDEX or a web service call.  Be sure you limit your returned search results to maybe the top 10 matches so you don't bog things down with too much data moving over the wire.&lt;/p&gt;
&lt;p&gt;Next, set up a controller action to invoke this back-end call and JSON up the returned list.  We've already names the controller (Search) and action (AutocompleteSuggestions) in our view.  Something like this should work, where _searchRepository is my repository call that finds matching strings, which are then converted to JSON:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public JsonResult AutocompleteSuggestions(string term)
{
    var suggestions = _searchRepository.GetAutoCompleteSearchSuggestion(term);
    return Json(suggestions, JsonRequestBehavior.AllowGet);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Don't forget the JsonRequestBehavior.AllowGet parameter in the Json call.  You won't get anything back from the action method if you leave it off.&lt;/p&gt;
&lt;p&gt;Also, the name of the parameter passed into the action method is important.  The jQuery UI autocomplete method will call your source URL with a query string like &amp;quot;?term=foo&amp;quot;.  If you set the parameter name to a string named &amp;quot;term&amp;quot;, the MVC model binder will grab the value from the query string for you.&lt;/p&gt;
&lt;p&gt;The &lt;a href="http://jqueryui.com/demos/autocomplete/"&gt;jQuery UI Autocomplete&lt;/a&gt; function has several other options and events you can use in your app, and the demos are worth checking out too.&lt;/p&gt;
</description>
      <pubDate>Sat, 05 Feb 2011 01:40:23 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/building-a-windows-8-live-tile-with-javascript</guid>
      <link>https://volaresoftware.com/en/technical-posts/building-a-windows-8-live-tile-with-javascript</link>
      <title>Building a Windows 8 Live Tile with JavaScript</title>
      <description>&lt;p&gt;If you've seen Windows 8 yet, you know it's got a tile-based start menu.  One of the cool things (or annoying things) you can do is post values on your app's tile.  This is called a &amp;quot;live tile&amp;quot; in Windows 8 world.  Your app users can turn them on or off with a right click on the tile.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2012/10/image_19.png" alt="image_19.png" /&gt;&lt;/p&gt;
&lt;p&gt;Here's how I built one with JavaScript.&lt;/p&gt;
&lt;h2 id="figure-out-what-you-want-to-display-on-your-live-tiles"&gt;Figure out what you want to display on your live tiles&lt;/h2&gt;
&lt;p&gt;This is what my tile looks like before it's &amp;quot;live&amp;quot; as both a smaller (square) and a larger (wide) tile:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2012/10/small-tile.png" alt="small-tile.png" /&gt;          &lt;img src="https://cdn.volaresoftware.com/images/posts/2012/10/wide-tile.png" alt="wide-tile.png" /&gt;&lt;/p&gt;
&lt;p&gt;The live tile concept is that you pick a style template, build up some XML, then push that XML to the tile through the notification API.  &lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh761491.aspx"&gt;These guidelines show you the different tile templates you can pick&lt;/a&gt;.  Find a square tile and a wide tile you like, and pay attention to the name of that template, since you'll use that soon.&lt;/p&gt;
&lt;p&gt;In this case, I decided I like TileSquareText01:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2012/10/square-sample.png" alt="square-sample.png" /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-xml"&gt;&amp;lt;tile&amp;gt;
  &amp;lt;visual&amp;gt;
    &amp;lt;binding template=&amp;quot;TileSquareText01&amp;quot;&amp;gt;
      &amp;lt;text id=&amp;quot;1&amp;quot;&amp;gt;Text Field 1&amp;lt;/text&amp;gt;
      &amp;lt;text id=&amp;quot;2&amp;quot;&amp;gt;Text Field 2&amp;lt;/text&amp;gt;
      &amp;lt;text id=&amp;quot;3&amp;quot;&amp;gt;Text Field 3&amp;lt;/text&amp;gt;
      &amp;lt;text id=&amp;quot;4&amp;quot;&amp;gt;Text Field 4&amp;lt;/text&amp;gt;
    &amp;lt;/binding&amp;gt;  
  &amp;lt;/visual&amp;gt;
&amp;lt;/tile&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and TileWideText01:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2012/10/wide-sample.png" alt="wide-sample.png" /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-xml"&gt;&amp;lt;tile&amp;gt;
  &amp;lt;visual&amp;gt;
    &amp;lt;binding template=&amp;quot;TileWideText01&amp;quot;&amp;gt;
      &amp;lt;text id=&amp;quot;1&amp;quot;&amp;gt;Text Header Field 1&amp;lt;/text&amp;gt;
      &amp;lt;text id=&amp;quot;2&amp;quot;&amp;gt;Text Field 2&amp;lt;/text&amp;gt;
      &amp;lt;text id=&amp;quot;3&amp;quot;&amp;gt;Text Field 3&amp;lt;/text&amp;gt;
      &amp;lt;text id=&amp;quot;4&amp;quot;&amp;gt;Text Field 4&amp;lt;/text&amp;gt;
      &amp;lt;text id=&amp;quot;5&amp;quot;&amp;gt;Text Field 5&amp;lt;/text&amp;gt;
    &amp;lt;/binding&amp;gt;  
  &amp;lt;/visual&amp;gt;
&amp;lt;/tile&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The plan is to show the users current altitude as a number on the top, larger font line, then show the units (feet or meters) under that in the smaller font.&lt;/p&gt;
&lt;p&gt;There are several rules about what you can and can't show on your tiles, so &lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh465403.aspx"&gt;check the guidelines carefully&lt;/a&gt; to be sure your idea will not get rejected by the Windows Store during the certification process.&lt;/p&gt;
&lt;h2 id="tests-for-the-correct-live-tile-xml"&gt;Tests for the correct live tile XML&lt;/h2&gt;
&lt;p&gt;Since the live tile notification is all about sending the right XML, let's start with a test of the XML we want at the end.  Here I'm using &lt;a href="http://qunitjs.com/"&gt;QUnit&lt;/a&gt; to check the XML.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;test(&amp;quot;tile&amp;quot;, function () {
    var altitude = 6071,
        altitudeUnits = &amp;quot;feet&amp;quot;,
        result,
        expected;
&lt;pre&gt;&lt;code&gt;result = tile.buildSquareTileXml(altitude, altitudeUnits);
expected = '&amp;amp;lt;tile&amp;amp;gt;' +
    '&amp;amp;lt;visual&amp;amp;gt;' +
    '&amp;amp;lt;binding template=&amp;amp;quot;TileSquareText01&amp;amp;quot; branding=&amp;amp;quot;name&amp;amp;quot;&amp;amp;gt;' +
    '&amp;amp;lt;text id=&amp;amp;quot;1&amp;amp;quot;&amp;amp;gt;6071&amp;amp;lt;/text&amp;amp;gt;' +
    '&amp;amp;lt;text id=&amp;amp;quot;2&amp;amp;quot;&amp;amp;gt;feet&amp;amp;lt;/text&amp;amp;gt;' +
    '&amp;amp;lt;text id=&amp;amp;quot;3&amp;amp;quot;&amp;amp;gt;&amp;amp;lt;/text&amp;amp;gt;' +
    '&amp;amp;lt;text id=&amp;amp;quot;4&amp;amp;quot;&amp;amp;gt;&amp;amp;lt;/text&amp;amp;gt;' +
    '&amp;amp;lt;/binding&amp;amp;gt;' +
    '&amp;amp;lt;/visual&amp;amp;gt;' +
    '&amp;amp;lt;/tile&amp;amp;gt;';
equal(result.getXml().toString(), expected, &amp;amp;quot;should get correct xml for square tile&amp;amp;quot;);

result = tile.buildWideTileXml(altitude, altitudeUnits);
expected = '&amp;amp;lt;tile&amp;amp;gt;' +
    '&amp;amp;lt;visual&amp;amp;gt;' +
    '&amp;amp;lt;binding template=&amp;amp;quot;TileWideText01&amp;amp;quot; branding=&amp;amp;quot;name&amp;amp;quot;&amp;amp;gt;' +
    '&amp;amp;lt;text id=&amp;amp;quot;1&amp;amp;quot;&amp;amp;gt;6071&amp;amp;lt;/text&amp;amp;gt;' +
    '&amp;amp;lt;text id=&amp;amp;quot;2&amp;amp;quot;&amp;amp;gt;feet&amp;amp;lt;/text&amp;amp;gt;' +
    '&amp;amp;lt;text id=&amp;amp;quot;3&amp;amp;quot;&amp;amp;gt;&amp;amp;lt;/text&amp;amp;gt;' +
    '&amp;amp;lt;text id=&amp;amp;quot;4&amp;amp;quot;&amp;amp;gt;&amp;amp;lt;/text&amp;amp;gt;' +
    '&amp;amp;lt;text id=&amp;amp;quot;5&amp;amp;quot;&amp;amp;gt;&amp;amp;lt;/text&amp;amp;gt;' +
    '&amp;amp;lt;/binding&amp;amp;gt;' +
    '&amp;amp;lt;/visual&amp;amp;gt;' +
    '&amp;amp;lt;/tile&amp;amp;gt;';
equal(result.getXml().toString(), expected, &amp;amp;quot;should get correct xml for wide tile&amp;amp;quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;});
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;These tests fail since we haven't written the functions yet, but we'll do that next.  Ignore the &amp;quot;branding&amp;quot; attribute for now.  We'll come back to that.&lt;/p&gt;
&lt;h2 id="build-up-the-live-tile-xml"&gt;Build up the live tile XML&lt;/h2&gt;
&lt;p&gt;Here's the code to get the correct XML and get those tests passing.  See those calls the &lt;code&gt;Windows.UI.Notifications.TileTemplateType&lt;/code&gt;?  That's where you plug in the name of the square and wide template you picked from the catalog.&lt;/p&gt;
&lt;p&gt;I'm building up an array of values for the different lines of text.  Use any XML or string manipulation technique you like.  I got this one from the Windows 8 SDK samples.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;function buildSquareTileXml(altitude, altitudeUnits) {
    var squareTemplate = Windows.UI.Notifications.TileTemplateType.tileSquareText01,
            squareTileLines = [
                altitude,
                altitudeUnits
            ],
            squareTileXml = Windows.UI.Notifications.TileUpdateManager.getTemplateContent(squareTemplate),
            squareTileTextAttributes = squareTileXml.getElementsByTagName(&amp;quot;text&amp;quot;);
&lt;pre&gt;&lt;code&gt;for (var i = 0; i &amp;amp;lt; squareTileLines.length; i++) {
    squareTileTextAttributes[i].appendChild(squareTileXml.createTextNode(squareTileLines[i]));
}

var squareTileBinding = squareTileXml.getElementsByTagName(&amp;amp;quot;binding&amp;amp;quot;);
if (squareTileBinding[0]) {
    squareTileBinding[0].setAttribute(&amp;amp;quot;branding&amp;amp;quot;, &amp;amp;quot;name&amp;amp;quot;);
}

return squareTileXml;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;function buildWideTileXml(altitude, altitudeUnits) {
var wideTemplate = Windows.UI.Notifications.TileTemplateType.tileWideText01,
wideTileLines = [
altitude,
altitudeUnits
],
wideTileXml = Windows.UI.Notifications.TileUpdateManager.getTemplateContent(wideTemplate),
wideTileTextAttributes = wideTileXml.getElementsByTagName(&amp;quot;text&amp;quot;);&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;for (var i = 0; i &amp;amp;lt; wideTileLines.length; i++) {
    wideTileTextAttributes[i].appendChild(wideTileXml.createTextNode(wideTileLines[i]));
}

var binding = wideTileXml.getElementsByTagName(&amp;amp;quot;binding&amp;amp;quot;);
if (binding[0]) {
    binding[0].setAttribute(&amp;amp;quot;branding&amp;amp;quot;, &amp;amp;quot;name&amp;amp;quot;);
}

return wideTileXml;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="combine-the-square-and-wide-xml"&gt;Combine the square and wide XML&lt;/h2&gt;
&lt;p&gt;Since users of your tile can toggle the smaller (square) or larger (wide) version of your tile, you want to combine the square and wide XML and send down both.  Here's how to do that.  Again, this is just XML manipulation, use any technique you like.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;function combineTileXml(wideTileXml, squareTileXml) {
    var node = wideTileXml.importNode(squareTileXml.getElementsByTagName(&amp;quot;binding&amp;quot;).item(0), true);
    wideTileXml.getElementsByTagName(&amp;quot;visual&amp;quot;).item(0).appendChild(node);
&lt;pre&gt;&lt;code&gt;return wideTileXml;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="pass-the-combined-live-tile-xml-to-the-windows-8-api"&gt;Pass the combined live tile XML to the Windows 8 API&lt;/h2&gt;
&lt;p&gt;Now that you've got the final XML you want, create a Tile Notification object and pass it to the Tile Update Manager:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;function sendTileUpdate(altitude, altitudeUnits) {
    var wideTileXml,
        squareTileXml,
        combinedTileXml,
        tileNotification;
&lt;pre&gt;&lt;code&gt;if (altitude &amp;amp;amp;amp;&amp;amp;amp;amp; altitudeUnits) {
    wideTileXml = buildWideTileXml(altitude, altitudeUnits);
    squareTileXml = buildSquareTileXml(altitude, altitudeUnits);
    combinedTileXml = combineTileXml(wideTileXml, squareTileXml);

    tileNotification = new Windows.UI.Notifications.TileNotification(combinedTileXml);
    Windows.UI.Notifications.TileUpdateManager.createTileUpdaterForApplication().update(tileNotification);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;The last two lines are doing the real work here, by using the Windows 8 notifications API.  The rest is calling the other helper functions.&lt;/p&gt;
&lt;h2 id="calling-the-notification-code"&gt;Calling the notification code&lt;/h2&gt;
&lt;p&gt;So who notifies the notifier code that we've got some new stuff to show on the line tile?  You do!  Figure out when something interesting happens in your app, and send a notification to the live tile then.  In this case, that looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;tile.sendTileUpdate(altitude, altitudeUnits);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="putting-it-all-together"&gt;Putting it all together&lt;/h2&gt;
&lt;p&gt;Here's the result for the square and wide tiles:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2012/10/smaill-live-tile.png" alt="smaill-live-tile.png" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2012/10/wide-live-tile.png" alt="wide-live-tile.png" /&gt;&lt;/p&gt;
&lt;p&gt;Here's the combined JavaScript.  I put it all in a file named it tile.js and used the WinJS namespacing function.  This is pretty much the same as the revealing module pattern, and it means I can call &lt;code&gt;tile.&amp;lt;whatever&amp;gt;&lt;/code&gt; from the tests and other JavaScript files.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;(function () {
    &amp;quot;use strict&amp;quot;;
&lt;pre&gt;&lt;code&gt;function sendTileUpdate(altitude, altitudeUnits) {
    var wideTileXml,
        squareTileXml,
        combinedTileXml,
        tileNotification;

    if (altitude &amp;amp;amp;amp;&amp;amp;amp;amp; altitudeUnits) {
        wideTileXml = buildWideTileXml(altitude, altitudeUnits);
        squareTileXml = buildSquareTileXml(altitude, altitudeUnits);
        combinedTileXml = combineTileXml(wideTileXml, squareTileXml);

        tileNotification = new Windows.UI.Notifications.TileNotification(combinedTileXml);
        Windows.UI.Notifications.TileUpdateManager.createTileUpdaterForApplication().update(tileNotification);
    }
}

function buildSquareTileXml(altitude, altitudeUnits) {
    var squareTemplate = Windows.UI.Notifications.TileTemplateType.tileSquareText01,
            squareTileLines = [
                altitude,
                altitudeUnits
            ],
            squareTileXml = Windows.UI.Notifications.TileUpdateManager.getTemplateContent(squareTemplate),
            squareTileTextAttributes = squareTileXml.getElementsByTagName(&amp;amp;quot;text&amp;amp;quot;);

    for (var i = 0; i &amp;amp;lt; squareTileLines.length; i++) {
        squareTileTextAttributes[i].appendChild(squareTileXml.createTextNode(squareTileLines[i]));
    }

    var squareTileBinding = squareTileXml.getElementsByTagName(&amp;amp;quot;binding&amp;amp;quot;);
    if (squareTileBinding[0]) {
        squareTileBinding[0].setAttribute(&amp;amp;quot;branding&amp;amp;quot;, &amp;amp;quot;name&amp;amp;quot;);
    }

    return squareTileXml;
}

function buildWideTileXml(altitude, altitudeUnits) {
    var wideTemplate = Windows.UI.Notifications.TileTemplateType.tileWideText01,
            wideTileLines = [
                altitude,
                altitudeUnits
            ],
            wideTileXml = Windows.UI.Notifications.TileUpdateManager.getTemplateContent(wideTemplate),
            wideTileTextAttributes = wideTileXml.getElementsByTagName(&amp;amp;quot;text&amp;amp;quot;);

    for (var i = 0; i &amp;amp;lt; wideTileLines.length; i++) {
        wideTileTextAttributes[i].appendChild(wideTileXml.createTextNode(wideTileLines[i]));
    }

    var binding = wideTileXml.getElementsByTagName(&amp;amp;quot;binding&amp;amp;quot;);
    if (binding[0]) {
        binding[0].setAttribute(&amp;amp;quot;branding&amp;amp;quot;, &amp;amp;quot;name&amp;amp;quot;);
    }

    return wideTileXml;
}

function combineTileXml(wideTileXml, squareTileXml) {
    var node = wideTileXml.importNode(squareTileXml.getElementsByTagName(&amp;amp;quot;binding&amp;amp;quot;).item(0), true);
    wideTileXml.getElementsByTagName(&amp;amp;quot;visual&amp;amp;quot;).item(0).appendChild(node);

    return wideTileXml;
}

WinJS.Namespace.define(&amp;amp;quot;tile&amp;amp;quot;, {
    sendTileUpdate: sendTileUpdate,
    buildWideTileXml: buildWideTileXml,
    buildSquareTileXml: buildSquareTileXml
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;})();
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="branding"&gt;Branding&lt;/h2&gt;
&lt;p&gt;In the bottom left corner of the tile, I am showing the name of the app, in this case &amp;quot;Altitude&amp;quot;, on the live tile.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2012/10/smaill-live-tile_1.png" alt="smaill-live-tile_1.png" /&gt;          &lt;img src="https://cdn.volaresoftware.com/images/posts/2012/10/wide-live-tile_1.png" alt="wide-live-tile_1.png" /&gt;&lt;/p&gt;
&lt;p&gt;If you like, you can show your logo here instead.  This comes from the 30x30 logo in your package.appxmanifest on the Application UI tab, under Tile &amp;gt; Small Logo.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2012/10/image_20.png" alt="image_20.png" /&gt;&lt;/p&gt;
&lt;p&gt;Change these lines:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;binding[0].setAttribute(&amp;quot;branding&amp;quot;, &amp;quot;name&amp;quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;to:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;binding[0].setAttribute(&amp;quot;branding&amp;quot;, &amp;quot;logo&amp;quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And you'll get this instead:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2012/10/small-live-tile-logo.png" alt="small-live-tile-logo.png" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2012/10/wide-live-tile-logo.png" alt="wide-live-tile-logo.png" /&gt;&lt;/p&gt;
&lt;p&gt;In fact, you can take out all the code around branding if you like the logo there, since that's the default behavior.  If you want neither your app name nor your logo there, you can set the branding attribute to &amp;quot;none&amp;quot;.&lt;/p&gt;
&lt;h2 id="hey-my-live-tile-doesnt-work"&gt;Hey, my Live Tile doesn't work!&lt;/h2&gt;
&lt;p&gt;I had this experience the first couple times I ran my code, too.  The most common mistake I've seen is invalid XML, so be sure you add those test first to avoid that.&lt;/p&gt;
&lt;p&gt;The other snag was using the Simulator in Visual Studio 2012 that simulates a tablet with touch and rotating.  I don't know what the issue was, but my live tile didn't update when I ran it through the Simulator.  Other live tiles could be turned on and off, but not the one for my app.  When I ran on Local Machine instead, the live tile worked fine.  So if you're not seeing your live tile work in the Simulator, switch to Local Machine and see if that fixes it for you.&lt;/p&gt;
</description>
      <pubDate>Tue, 16 Oct 2012 00:39:54 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/making-your-aspnet-mvc-app-look-decent-on-an-iphone-or-ipad</guid>
      <link>https://volaresoftware.com/en/technical-posts/making-your-aspnet-mvc-app-look-decent-on-an-iphone-or-ipad</link>
      <title>Making your ASP.NET MVC app look decent on an iPhone or iPad</title>
      <description>&lt;p&gt;I wanted to try out the &lt;a href="http://www.asp.net/mvc/tutorials/mvc-4/aspnet-mvc-4-mobile-features"&gt;new mobile features of ASP.NET MVC 4&lt;/a&gt; to convert an existing site (this one!) to a half-decent looking &lt;a href="http://www.apple.com/iphone/"&gt;iPhone&lt;/a&gt;/&lt;a href="http://www.apple.com/ipad/"&gt;iPad&lt;/a&gt; app.  It was really easy.  Here are the steps and what I learned in the process.&lt;/p&gt;
&lt;h2 id="think-about-what-your-mobile-user-will-want-to-do"&gt;Think about what your mobile user will want to do&lt;/h2&gt;
&lt;p&gt;This is the most important piece, and it's one you need to take seriously before you dive in.  If you skip it, you'll just have a mess.  You know that tablets and phones are smaller, so things that require lots of screen space won't work.  But what is the &lt;strong&gt;main&lt;/strong&gt; thing people open the site/app to do?  Optimize for that and put it front and center.  If there is more than one thing your site/app does, how will mobile user's navigate around?  When converting an existing app to mobile, you'll probably want to cut out a lot of extraneous stuff.  You could also phase in different chunks.  It doesn't have to be all or nothing.&lt;/p&gt;
&lt;h2 id="choose-your-technical-approach"&gt;Choose your technical approach&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://twitter.com/shanselman"&gt;Scott Hanselman&lt;/a&gt; has a &lt;a href="http://www.hanselman.com/blog/CreateAGreatMobileExperienceForYourWebsiteTodayPlease.aspx"&gt;nice blog post and chart showing effort compared to user experience&lt;/a&gt; across different approaches to making your app mobile.&lt;/p&gt;
&lt;p&gt;He covers responsive design (&lt;a href="http://www.w3.org/TR/css3-mediaqueries/"&gt;CSS media queries&lt;/a&gt; and resizing), using a mobile framework (like &lt;a href="http://jquerymobile.com/"&gt;jQuery Mobile&lt;/a&gt;), or going native (&lt;a href="http://en.wikipedia.org/wiki/Objective-C"&gt;Objective-C&lt;/a&gt;).  My only quibble with the Scott's chart is the green circle for native apps is too small.  I think that's WAAAAY more effort.&lt;/p&gt;
&lt;p&gt;For this post, I went with a mobile framework (jQuery Mobile).  This is the most bang for your buck.  You can learn it in less than an hour, and convert views and layouts in a half day to a day, depending on how complicated your views are.&lt;/p&gt;
&lt;h2 id="get-jquery-mobile"&gt;Get jQuery Mobile&lt;/h2&gt;
&lt;p&gt;Add the &lt;a href="http://nuget.org/packages/jquery.mobile"&gt;jQuery Mobile NuGet package&lt;/a&gt; to your web project.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2012/9/image_17.png" alt="image_17.png" /&gt;&lt;/p&gt;
&lt;p&gt;It will add the JavaScript, CSS, and sprite icon images in the /Scripts, /Content, and /Content/Images folders in your web project.  I moved the JavaScript and CSS to /Content/Scripts/Downloaded and /Content/Styles/Downloaded folders.  I prefer to do this so I can bundle scripts with wildcards like /Content/Scripts/Site/*.js. Here's my folder structure:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2012/9/image_18.png" alt="image_18.png" /&gt;&lt;/p&gt;
&lt;h2 id="bundling"&gt;Bundling&lt;/h2&gt;
&lt;p&gt;I dropped the &lt;code&gt;*.min.js&lt;/code&gt; and &lt;code&gt;*.min.css&lt;/code&gt; files since I'm combining and minifying these with the BundleConfig like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;using System.Web.Optimization;
&lt;p&gt;namespace App_Start
{
public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
// Scripts&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;        bundles.Add(new ScriptBundle(&amp;amp;quot;~/Content/Scripts/modernizr&amp;amp;quot;).Include(
            &amp;amp;quot;~/Content/Scripts/Downloaded/modernizr-2.6.2.js&amp;amp;quot;)); 

        bundles.Add(new ScriptBundle(&amp;amp;quot;~/Content/Scripts/all&amp;amp;quot;).Include(
            &amp;amp;quot;~/Content/Scripts/Downloaded/jquery-1.8.1.js&amp;amp;quot;, 
            &amp;amp;quot;~/Content/Scripts/Downloaded/jquery.unobtrusive-ajax.js&amp;amp;quot;,
            &amp;amp;quot;~/Content/Scripts/Downloaded/jquery.validate.js&amp;amp;quot;,
            &amp;amp;quot;~/Content/Scripts/Downloaded/jquery.validate.unobtrusive.js&amp;amp;quot;,
            &amp;amp;quot;~/Content/Scripts/Site/*.js&amp;amp;quot;));

        bundles.Add(new ScriptBundle(&amp;amp;quot;~/Content/Scripts/mobileall&amp;amp;quot;).Include(
            &amp;amp;quot;~/Content/Scripts/Downloaded/jquery-1.8.1.js&amp;amp;quot;,
            &amp;amp;quot;~/Content/Scripts/Downloaded/jquery.mobile-1.1.1.js&amp;amp;quot;));

        // Styles

        bundles.Add(new StyleBundle(&amp;amp;quot;~/Content/Styles/all&amp;amp;quot;).Include(
            &amp;amp;quot;~/Content/Styles/Site/Site.css&amp;amp;quot;));

        bundles.Add(new StyleBundle(&amp;amp;quot;~/Content/Styles/mobileall&amp;amp;quot;).Include(
            &amp;amp;quot;~/Content/Styles/Downloaded/jquerymobile/*.css&amp;amp;quot;,
            &amp;amp;quot;~/Content/Styles/Site/Mobile.css&amp;amp;quot;));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;The bundles created here are for the JavaScript and CSS for the desktop site (&amp;quot;all&amp;quot;) and the mobile site (&amp;quot;mobileall&amp;quot;).  The &amp;quot;modernizr&amp;quot; bundle is separate because it only works in the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; section, but the rest is loaded at the bottom of the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; tag in the Layout view so it doesn't block page loading.&lt;/p&gt;
&lt;h2 id="make-a_layout.mobile.cshtml"&gt;Make a _Layout.Mobile.cshtml&lt;/h2&gt;
&lt;p&gt;You'll want a mobile layout view. It's probably simplest to take your existing &lt;code&gt;_Layout.cshtml&lt;/code&gt;, copy/paste, and rename it to &lt;code&gt;_Layout.Mobile.cshtml&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The view engine routes &amp;quot;mobile&amp;quot; requests to the correct place.  I have mobile in quotes here because it puts iPads in that category.  Seems like it would be either &lt;code&gt;_Layout.Tablet.cshtml&lt;/code&gt; or &lt;code&gt;_Layout.Phone.cshtml&lt;/code&gt; instead of &lt;code&gt;_Layout.Mobile.cshtml&lt;/code&gt;, since those are very different form factors, but that's what you get out of the box.&lt;/p&gt;
&lt;p&gt;If you don't like that, you can add specific views for specific devices with &lt;a href="http://msdn.microsoft.com/en-us/library/jj149688.aspx"&gt;display modes&lt;/a&gt;.  I recommend looking through your web logs to see what your users are really browsing with so you spend your time making your app look its best for the most popular user agents.  Start with a generic mobile layout and go from there if it starts to break down and you're getting enough traffic from that device to warrant the extra work.&lt;/p&gt;
&lt;p&gt;You'll probably rip out pieces of your app/site in the mobile layout.  Some stuff doesn't make sense on a phone, so this is where you can take it out if it's site wide.  If it's something in a view you want to hide, see below.&lt;/p&gt;
&lt;p&gt;For the JavaScript, you can probably get away with just jQuery and jQuery Mobile.  You probably won't need Modernizr.  You may have some site-specific JavaScript you need to include in their, too.&lt;/p&gt;
&lt;p&gt;For style sheets, I recommend starting with just the jQuery Mobile CSS.  You can add your own Mobile.css (you can rename this to anything you like) referenced in your mobile layout for tweaks and overrides you need to do.  I'd leave the jQuery Mobile CSS as-is so you can upgrade later without problems.&lt;/p&gt;
&lt;p&gt;You'll also want to set your viewport to max width for every device:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;meta name=&amp;quot;viewport&amp;quot; content=&amp;quot;width=device-width&amp;quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here's my &lt;code&gt;_Layout.Mobile.cshtml&lt;/code&gt; (the relevant parts anyway):&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-aspnet"&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;quot;utf-8&amp;quot; /&amp;gt;
    &amp;lt;meta name=&amp;quot;viewport&amp;quot; content=&amp;quot;width=device-width&amp;quot;&amp;gt;
    &amp;lt;title&amp;gt;@ViewBag.Title&amp;lt;/title&amp;gt;
    @Styles.Render(&amp;quot;~/Content/Styles/mobileall&amp;quot;)
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;div data-role=&amp;quot;page&amp;quot; data-theme=&amp;quot;c&amp;quot;&amp;gt;
        &amp;lt;header data-role=&amp;quot;header&amp;quot;&amp;gt;
            &amp;lt;div&amp;gt;
                &amp;lt;a href=&amp;quot;@Url.Action(&amp;quot;Index&amp;quot;, &amp;quot;Home&amp;quot;)&amp;quot;&amp;gt;
                    &amp;lt;img src=&amp;quot;@Url.Content(&amp;quot;~/Content/Images/Logos/Logo_100px_High.png&amp;quot;)&amp;quot; alt=&amp;quot;Volare Systems, Inc.&amp;quot; width=&amp;quot;160px&amp;quot; height=&amp;quot;100px&amp;quot; /&amp;gt;
                &amp;lt;/a&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/header&amp;gt;
        &amp;lt;section id=&amp;quot;content&amp;quot; data-role=&amp;quot;content&amp;quot;&amp;gt;
            @RenderBody()
        &amp;lt;/section&amp;gt;
        &amp;lt;footer&amp;gt;
            &amp;lt;nav&amp;gt;
                &amp;lt;ul data-role=&amp;quot;listview&amp;quot; data-content-theme=&amp;quot;c&amp;quot; data-divider-theme=&amp;quot;d&amp;quot; data-inset=&amp;quot;true&amp;quot; &amp;gt;
                    &amp;lt;li data-role=&amp;quot;list-divider&amp;quot;&amp;gt;What We Do&amp;lt;/li&amp;gt;
                    &amp;lt;li&amp;gt;@Html.ActionLink(&amp;quot;Home&amp;quot;, &amp;quot;Index&amp;quot;, &amp;quot;Home&amp;quot;)&amp;lt;/li&amp;gt;
                    &amp;lt;li&amp;gt;@Html.ActionLink(&amp;quot;Services&amp;quot;, &amp;quot;Index&amp;quot;, &amp;quot;Services&amp;quot;)&amp;lt;/li&amp;gt;
                    &amp;lt;li&amp;gt;@Html.ActionLink(&amp;quot;Customer testimonials&amp;quot;, &amp;quot;CustomerTestimonials&amp;quot;, &amp;quot;Services&amp;quot;)&amp;lt;/li&amp;gt;
                    ...
                &amp;lt;/ul&amp;gt;
            &amp;lt;/nav&amp;gt;
            &amp;lt;div id=&amp;quot;copyright&amp;quot;&amp;gt;
                &amp;amp;amp;copy; 2009 - @DateTime.Now.Year.ToString() @Html.ActionLink(&amp;quot;Volare Systems, Inc.&amp;quot;, &amp;quot;Index&amp;quot;, &amp;quot;Home&amp;quot;)
            &amp;lt;/div&amp;gt;
        &amp;lt;/footer&amp;gt;
    &amp;lt;/div&amp;gt;
    @Scripts.Render(&amp;quot;~/Content/Scripts/mobileall&amp;quot;)
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="start-using-jquery-mobile"&gt;Start using jQuery Mobile&lt;/h2&gt;
&lt;p&gt;Now it's time to start adding in the &lt;code&gt;data-*&lt;/code&gt; attributes and classes jQuery Mobile wants to use.  You'll find them here on the &lt;a href="http://jquerymobile.com/demos/1.1.1/"&gt;demo site&lt;/a&gt;.  I used:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://jquerymobile.com/demos/1.1.1/docs/pages/page-anatomy.html"&gt;data-page=&amp;quot;page&amp;quot;&lt;/a&gt; in the mobile layout as an outer wrapper&lt;/li&gt;
&lt;li&gt;&lt;a href="http://jquerymobile.com/demos/1.1.1/docs/api/themes.html"&gt;data-theme=&amp;quot;c&amp;quot;&lt;/a&gt; (try out the different themes to see what suits you best by swapping out letters a-e)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://jquerymobile.com/demos/1.1.1/docs/about/getting-started.html"&gt;data-role=&amp;quot;content&amp;quot;&lt;/a&gt; around the &lt;code&gt;@RenderBody&lt;/code&gt; markup&lt;/li&gt;
&lt;li&gt;&lt;a href="http://jquerymobile.com/demos/1.1.1/docs/lists/docs-lists.html"&gt;data-role=&amp;quot;listview&amp;quot;&lt;/a&gt; and &lt;a href="http://jquerymobile.com/demos/1.1.1/docs/lists/lists-divider.html"&gt;data-role=&amp;quot;list-divider&amp;quot;&lt;/a&gt; for the navigation&lt;/li&gt;
&lt;li&gt;&lt;a href="http://jquerymobile.com/demos/1.1.1/docs/content/content-collapsible-set.html"&gt;data-role=&amp;quot;collapsible-set&amp;quot;&lt;/a&gt; and &lt;a href="http://jquerymobile.com/demos/1.1.1/docs/content/content-collapsible.html"&gt;data-role=&amp;quot;collapsible&amp;quot;&lt;/a&gt; for collapsible text that shows/hides when you click it&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here are the results:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2012/9/home1.png" alt="home1.png" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2012/9/phonehome.png" alt="phonehome.png" /&gt;&lt;/p&gt;
&lt;p&gt;Click through the docs and see what you can find that adapts well to your situation.  For forms, I found it was fine to remove my normal style sheet and let jQuery Mobile take over.&lt;/p&gt;
&lt;h2 id="make-a-mobile.css"&gt;Make a Mobile.css&lt;/h2&gt;
&lt;p&gt;I use Site.css and Mobile.css as my desktop and tablet/phone CSS files.  The &lt;code&gt;_Layout.Mobile.cshtml&lt;/code&gt; references to the Mobile.css, and &lt;code&gt;_Layout.cshtml&lt;/code&gt; references the &lt;code&gt;Site.css&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You may not need a Mobile.css, but I found it useful to tweak margins, padding, etc. to get the look I wanted.  You'll probably have to use the &lt;code&gt;!important&lt;/code&gt; CSS tag to force your CSS to override the jQuery Mobile CSS, so watch out for that.  Also, every time you do this, someone at &lt;a href="http://www.alistapart.com/"&gt;A List Apart&lt;/a&gt; sighs heavily.&lt;/p&gt;
&lt;h2 id="test-and-tweak-your-views"&gt;Test and tweak your views&lt;/h2&gt;
&lt;p&gt;There are lots of cheap and free iPhone/iPad simulators out there.  Try to find a free one you like.  I gave up and downloaded the &lt;a href="http://www.electricplum.com/simulator.aspx"&gt;Electric Plum&lt;/a&gt; one.  So far, so good.  It's more stable than the free ones I tried.&lt;/p&gt;
&lt;p&gt;Once you browse to your site on localhost, you'll see things you didn't realize would be such a fail on the phone.  This is your chance to remove it or fix it.  There are several approaches I used, based on the situation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add jQuery Mobile &lt;code&gt;data-*&lt;/code&gt; attributes to your view to render it the jQuery Mobile way.  Sprinkling these should not collide with your HTML for desktop rendering.&lt;/li&gt;
&lt;li&gt;Change the &lt;code&gt;Mobile.css&lt;/code&gt; to draw the elements a little differently just for mobile.  If it's really minor, you can hide it with a CSS &lt;code&gt;display: none;&lt;/code&gt;, but keep in mind this will run on a phone.  If you have the chance to send fewer bytes from the server to the device, that's almost always going to be the way to go.&lt;/li&gt;
&lt;li&gt;Add server-side conditional checks for code or markup that is &lt;strong&gt;only&lt;/strong&gt; for mobile (or just for desktop).  In a MVC Razor view, this looks like:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class="language-aspnet"&gt;@if (Request.Browser.IsMobile) {
    // do something just for mobile
}
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;If the conditional branching inside your view get to be too ugly, you can add a mobile-only view with the same naming pattern.  So &lt;code&gt;Index.cshtml&lt;/code&gt; has a mobile cohort in &lt;code&gt;Index.Mobile.cshtml&lt;/code&gt;.  You can break common code between the two views into partial views, and have the mobile and non-mobile views reference those partial views with the normal&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class="language-aspnet"&gt;@Html.Partial(&amp;quot;_ThePartialView&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;
</description>
      <pubDate>Mon, 24 Sep 2012 02:35:00 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/getting-http2-working-with-azure-cdn</guid>
      <link>https://volaresoftware.com/en/technical-posts/getting-http2-working-with-azure-cdn</link>
      <title>Getting HTTP/2 working with Azure CDN</title>
      <description>&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/HTTP/2"&gt;HTTP/2&lt;/a&gt; serves web content faster through multiplexing, where several requests can be sent on the same TCP connection.  However HTTP/2 is not available today on Azure App Services (web apps). &lt;a href="https://feedback.azure.com/forums/169385-web-apps/suggestions/9552936-enable-http-2-on-azure-web-apps"&gt;A lot of people wish it was&lt;/a&gt;, but that's a limitation of Azure hosting right now. One of the Azure feedback admins had this to say on January 9, 2018:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hi all. As everyone had noticed, we have upgraded App Service resources to Server 2016. As mentioned in our updates, this is indeed paving the way to HTTP/2 support across the board. As we are settling in with stability of the new OS version, we will begin work to open up HTTP/2. When I have a concrete timeline to share, I will do so. We should expect that in the next few months.&lt;/p&gt;
&lt;p&gt;Thanks,&lt;br /&gt;
Oded&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So it's coming, and hopefully soon, but it's not there yet.  In the meantime, you can put static resources like images on an Azure CDN and get HTTP/2 performance benefits, in addition to normal CDN benefits for long-lived content, like cache headers that don't expire any time soon and a geographically distributed network to host it on.&lt;/p&gt;
&lt;p&gt;This post is a walkthrough on how to do that with Azure Storage and Azure CDN services.&lt;/p&gt;
&lt;h3 id="azure-setup"&gt;Azure Setup&lt;/h3&gt;
&lt;p&gt;First, go into your Azure account and create a new resource group.  This makes it easier for testing so you can delete the whole thing when you're done playing around. I named mine &lt;code&gt;testresourcegroup&lt;/code&gt;.  There are so many pieces to an Azure infrastructure, you are better off if you prefix or suffix everything with one name, like your project name or acronym, and then put the name of the Azure thing you're creating somewhere in that name.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/azure_resource_grou.png" alt="https://cdn.volaresoftware.com/images/posts/2019/12/azure_resource_grou.png" /&gt;&lt;/p&gt;
&lt;p&gt;When that's created, go to that resource group. We'll add an App Service Plan (Azure-speak for the server/account type you want for your web app) and an App Service.&lt;/p&gt;
&lt;p&gt;I click the + button to add, search for &amp;quot;App Service Plan&amp;quot;, pick that, and fill that out. In the Pricing tier, I selected &amp;quot;Free&amp;quot; for this demo.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/azure_service_plan.png" alt="https://cdn.volaresoftware.com/images/posts/2019/12/azure_service_plan.png" /&gt;&lt;/p&gt;
&lt;p&gt;Now create a test web app by adding another resource to your resource group, searching for App Service, and selecting Web App. Be sure to select your newly created App Service Plan. I ended up having to go to &lt;code&gt;testweb17&lt;/code&gt; to get to a unique, publicly addressable name.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/azure_web_app.png" alt="https://cdn.volaresoftware.com/images/posts/2019/12/azure_web_app.png" /&gt;&lt;/p&gt;
&lt;p&gt;While that's being created, let's add Azure blob storage. Go back to your resource group, click the + button again to add, and search for &amp;quot;blob storage&amp;quot;, then select &amp;quot;Storage account – blob, file, table, queue&amp;quot;. Give it a unique name. In my case, I had to use &lt;code&gt;teststorge19&lt;/code&gt; to get a unique, publicly addressable name. I also changed the default Account kind to Blob storage since that's all I need. You can come back later and tweak the other settings here based on your app's needs.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/azure_storage_account.png" alt="https://cdn.volaresoftware.com/images/posts/2019/12/azure_storage_account.png" /&gt;&lt;/p&gt;
&lt;p&gt;Now we need to create the CDN in Azure. Go back to your resource group, click the + to add, and search for &amp;quot;CDN&amp;quot; and select it from the list. Give it a name. I used &lt;code&gt;testcdn&lt;/code&gt;. Pick a pricing tier. I used Standard Verizon (Verizon allows custom domain HTTPS connections, Akamai doesn't).&lt;/p&gt;
&lt;p&gt;Then select the option to create a CDN Endpoint. Like the App Service and App Service Plan relationship, the CDN is the service level and pricing, but the CDN Endpoint is the thing you really connect to. Pick a CDN endpoint name.  I used &lt;code&gt;testcdn19&lt;/code&gt; to match up with my storage account name. Again, this must be unique and publicly addressable. Be sure to pick Origin type of Storage and pick the Original hostname for your storage account from the drop down. I used &lt;code&gt;teststorage19.blog.core.windows.net&lt;/code&gt; since that is my test storage account created above.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/azure_cdn_profile.png" alt="https://cdn.volaresoftware.com/images/posts/2019/12/azure_cdn_profile.png" /&gt;&lt;/p&gt;
&lt;p&gt;When Azure is done huffing and puffing, your new resource group should look like this, but of course with your names. You'll have an App Service Plan with an App Service, a Storage Account, and a CDN Profile with a CDN Endpoint.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/azure_services.png" alt="https://cdn.volaresoftware.com/images/posts/2019/12/azure_services.png" /&gt;&lt;/p&gt;
&lt;h3 id="web-setup"&gt;Web Setup&lt;/h3&gt;
&lt;p&gt;I've made a one page web app with an index.html and an image.  You can &lt;a href="https://github.com/VolareSoftware/HTTP2WithAzureCDN"&gt;download them from GitHub&lt;/a&gt; or use your own content or test page. It's nothing more than this HTML and a picture.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;quot;utf-8&amp;quot; /&amp;gt;
    &amp;lt;title&amp;gt;HTTP/2 with Azure CDN&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;p&amp;gt;Here is an image of an elk in Rocky Mountain National Park.&amp;lt;/p&amp;gt;
    &amp;lt;img src=&amp;quot;images/Fall - Estes Elk.jpg&amp;quot; /&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To upload this web app to Azure, I first need to get a publish profile from Azure in my App Service.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/azure_get_publish_profile.png" alt="https://cdn.volaresoftware.com/images/posts/2019/12/azure_get_publish_profile.png" /&gt;&lt;/p&gt;
&lt;p&gt;Then I open my web app in Visual Studio, right click on the web site or web project and select Publish Web App.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/visual_studio_publish_web_app.png" alt="https://cdn.volaresoftware.com/images/posts/2019/12/visual_studio_publish_web_app.png" /&gt;&lt;/p&gt;
&lt;p&gt;Next, I tell Visual Studio to import the just downloaded publish profile.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/visual_studio_publish_settings.png" alt="https://cdn.volaresoftware.com/images/posts/2019/12/visual_studio_publish_settings.png" /&gt;&lt;/p&gt;
&lt;p&gt;Then when I publish my web app, it goes up to Azure and is publicly available.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/visual_studio_publish.png" alt="https://cdn.volaresoftware.com/images/posts/2019/12/visual_studio_publish.png" /&gt;&lt;/p&gt;
&lt;p&gt;After the publishing process completes, my browser opens the test web app at &lt;code&gt;https://testweb17.azurewebsites.net/&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/sample_web_page_with_image.png" alt="https://cdn.volaresoftware.com/images/posts/2019/12/sample_web_page_with_image.png" /&gt;&lt;/p&gt;
&lt;p&gt;If I open Chrome Dev Tools and go to the Network tab, I can see the two requests (one for the page, one for the image) are using HTTP 1.1. Let's see if we can get that image to be served using HTTP/2.&lt;/p&gt;
&lt;h3 id="storage-setup"&gt;Storage Setup&lt;/h3&gt;
&lt;p&gt;Go to your Azure resource group, find the storage account you set up, and add a blob container.  This is not quite a folder, but kind of acts like one for our purposes.  I'll add one for &amp;quot;web&amp;quot;. Be sure to set your container to something other than Private. I set mine to Blob.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/azure_storage_container.png" alt="https://cdn.volaresoftware.com/images/posts/2019/12/azure_storage_container.png" /&gt;&lt;/p&gt;
&lt;p&gt;Now I can select my container and upload the image to it. There are lots of client tools to upload, download, and manage your Azure storage files, like &lt;a href="https://www.cloudberrylab.com/explorer/microsoft-azure.aspx"&gt;CloudBerry Explorer for Microsoft Azure&lt;/a&gt;, which is free.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/azure_storage_container_upload.png" alt="https://cdn.volaresoftware.com/images/posts/2019/12/azure_storage_container_upload.png" /&gt;&lt;/p&gt;
&lt;p&gt;Once I have uploaded the image, I can click it and get its URL.  Open that URL to test that you can see the image. If not, check that you didn't make your container private. Also, be sure you are using the correct case. Calls to storage blobs are case sensitive. If you file is Image.jpg and request image.jpg (lowercase &amp;quot;I&amp;quot;), you'll get a 404. In my case, the image URL ends up as &lt;code&gt;https://teststorage19.blob.core.windows.net/web/Fall%20-%20Estes%20Elk.jpg&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you open Chrome Dev Tools and refresh the image, you can see it's being served over HTTP/2 already without being on a CDN.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/web_http2.png" alt="https://cdn.volaresoftware.com/images/posts/2019/12/web_http2.png" /&gt;&lt;/p&gt;
&lt;p&gt;Let's update the HTML to use that new URL and check that it's still using HTTP/2 when uploaded to the Azure App Service.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;quot;utf-8&amp;quot; /&amp;gt;
    &amp;lt;title&amp;gt;HTTP/2 with Azure CDN&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;p&amp;gt;Here is an image of an elk in Rocky Mountain National Park.&amp;lt;/p&amp;gt;
    &amp;lt;img src=&amp;quot;https://teststorage19.blob.core.windows.net/web/Fall - Estes Elk.jpg&amp;quot; /&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I made this change and re-published the web app, and sure enough, it's served over HTTP/2.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/cdn_http2.png" alt="https://cdn.volaresoftware.com/images/posts/2019/12/cdn_http2.png" /&gt;&lt;/p&gt;
&lt;p&gt;Let's go one step further and serve the image from a CDN, instead of directly from the storage account.&lt;/p&gt;
&lt;h3 id="cdn-setup"&gt;CDN Setup&lt;/h3&gt;
&lt;p&gt;In Azure, open your CDN Endpoint. You should see the URLs for your storage account and your CDN that maps to your storage account.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/azure_cdn_endpoint.png" alt="https://cdn.volaresoftware.com/images/posts/2019/12/azure_cdn_endpoint.png" /&gt;&lt;/p&gt;
&lt;p&gt;Since all our content is in a storage container called &amp;quot;web&amp;quot; and that becomes part of the URL, we can make that a default path for the CDN Endpoint under Origin.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/azure_cdn_origin_path.png" alt="https://cdn.volaresoftware.com/images/posts/2019/12/azure_cdn_origin_path.png" /&gt;&lt;/p&gt;
&lt;p&gt;Now we'll have URLs like this, using the CDN and skipping the /web/ folder in the URL:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;https://testcdn19.azureedge.net/Fall - Estes Elk.jpg&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;instead of:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;https://teststorage19.blob.core.windows.net/web/Fall - Estes Elk.jpg&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This change can take up to 90 minutes to propagate, so if you get 404s, that may be what's happening.&lt;/p&gt;
&lt;p&gt;Once you can browse to the image URL with your browser, replace that image source in the HTML markup and re-publish your web app to Azure.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;quot;utf-8&amp;quot; /&amp;gt;
    &amp;lt;title&amp;gt;HTTP/2 with Azure CDN&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;p&amp;gt;Here is an image of an elk in Rocky Mountain National Park.&amp;lt;/p&amp;gt;
    &amp;lt;img src=&amp;quot;https://testcdn19.azureedge.net/Fall - Estes Elk.jpg&amp;quot; /&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When you browse to it now, you can open Chrome Dev Tools and confirm the image is coming from the CDN and is using HTTP/2.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/web_http_final.png" alt="https://cdn.volaresoftware.com/images/posts/2019/12/web_http_final.png" /&gt;&lt;/p&gt;
</description>
      <pubDate>Sat, 03 Feb 2018 16:49:00 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/working-with-two-sets-of-eslint-rules-for-legacy-es5-and-modern-javascript-using-gulp</guid>
      <link>https://volaresoftware.com/en/technical-posts/working-with-two-sets-of-eslint-rules-for-legacy-es5-and-modern-javascript-using-gulp</link>
      <title>Working with two sets of ESLint rules for legacy ES5 and modern JavaScript using Gulp</title>
      <description>&lt;p&gt;I've written before about &lt;a href="https://volaresoftware.com/en/technical-posts/working-with-the-latest-javascript-syntax-on-your-project-today"&gt;using file extensions to tell webpack and Babel which files are older-style ES5 syntax and which are newer-style JavaScript&lt;/a&gt;. What if you've got a project that has both, and you need to run &lt;a href="https://eslint.org/"&gt;ESLint&lt;/a&gt; on the older, &lt;code&gt;*.js&lt;/code&gt; files as well as the new &lt;code&gt;*.es6&lt;/code&gt; files?&lt;/p&gt;
&lt;p&gt;You can run both in one task with &lt;a href="https://gulpjs.com/"&gt;Gulp&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;First, set up separate ESLint &lt;a href="https://eslint.org/docs/rules/"&gt;rules&lt;/a&gt; files. These are usually &lt;code&gt;.eslintrc.json&lt;/code&gt; files, but since we need two sets of rules, create &lt;code&gt;.eslintrc.es5.json&lt;/code&gt; (for the older syntax rules) and &lt;code&gt;.eslintrc.es6.json&lt;/code&gt; (for the newer syntax rules).&lt;/p&gt;
&lt;p&gt;Then create Gulp task (&amp;quot;validate-es5&amp;quot;) to get a glob of the &lt;code&gt;*.js&lt;/code&gt; files and apply the rules in the &lt;code&gt;.eslintrc.es5.json&lt;/code&gt; rules config and a Gulp task (&amp;quot;validate-es6&amp;quot;) to get a glob of the &lt;code&gt;*.es6&lt;/code&gt; files and apply the rules in the &lt;code&gt;.eslintrc.es6.json&lt;/code&gt; rules:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;const gulp = require(&amp;quot;gulp&amp;quot;);
const eslint = require(&amp;quot;gulp-eslint&amp;quot;);
const plumber = require(&amp;quot;gulp-plumber&amp;quot;);
const paths = {
    es6scripts: &amp;quot;Scripts/**/*.es6&amp;quot;,
    es5scripts: &amp;quot;Scripts/**/*.js&amp;quot;
};
const es5eslintGlob = [paths.es5scripts];
const es6eslintGlob = [paths.es6scripts];
 
 
gulp.task(&amp;quot;validate-es5&amp;quot;, () =&amp;gt;
    eslintPipeline(gulp.src(es5eslintGlob), &amp;quot;.eslintrc.es5.json&amp;quot;)
);
 
gulp.task(&amp;quot;validate-es6&amp;quot;, () =&amp;gt;
    eslintPipeline(gulp.src(es6eslintGlob), &amp;quot;.eslintrc.es6.json&amp;quot;)
);
 
function eslintPipeline(stream, rules) {
    return stream
        .pipe(plumber({
            errorHandler: error =&amp;gt; {
                console.log(error.message);
                console.log(error.toString());
            }
        }))
        .pipe(eslint(rules))
        .pipe(eslint.format())
        .pipe(eslint.failAfterError());
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, create a Gulp task to run both tasks named &amp;quot;watch&amp;quot; to run a watch on those files and execute ESLint with the correct rule set for each file extension when a file changes:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;const print = require(&amp;quot;gulp-print&amp;quot;).default;
const watch = require(&amp;quot;gulp-watch&amp;quot;);
 
gulp.task(&amp;quot;watch&amp;quot;, () =&amp;gt; {    
    eslintPipeline(watch(es5eslintGlob)
        .pipe(print(filepath =&amp;gt; `ESLint (ES5): ${filepath}`)), &amp;quot;.eslintrc.es5.json&amp;quot;)
        .pipe(eslint.failOnError());
    eslintPipeline(watch(es6eslintGlob)
        .pipe(print(filepath =&amp;gt; `ESLint (ES6): ${filepath}`)), &amp;quot;.eslintrc.es6.json&amp;quot;)
        .pipe(eslint.failOnError());
});
&lt;/code&gt;&lt;/pre&gt;
</description>
      <pubDate>Tue, 05 Feb 2019 01:39:05 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/fix-for-weird-errors-in-mvc4-when-adding-a-new-area</guid>
      <link>https://volaresoftware.com/en/technical-posts/fix-for-weird-errors-in-mvc4-when-adding-a-new-area</link>
      <title>Fix for weird errors in MVC4 when adding a new Area</title>
      <description>&lt;p&gt;MVC has let you add Areas to your web project for a couple versions now.  Areas help you group large chunks of code in your web app.  You can group along a technical axes (like &amp;quot;Api&amp;quot;) or a functional axes (like &amp;quot;Admin&amp;quot;).&lt;/p&gt;
&lt;h2 id="the-first-error"&gt;The first error&lt;/h2&gt;
&lt;p&gt;I created a new MVC4 project, added an area called &amp;quot;Test&amp;quot;, and browsed to the home page (http://localhost:59669).  Works!  Then I browse to the new area (http://localhost:59669/Test) and get this:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2012/12/image_thumb_5.png" alt="https://cdn.volaresoftware.com/images/posts/2012/12/image_thumb_5.png" /&gt;&lt;/p&gt;
&lt;p&gt;What's going on with those underscores?  The error message shows the problem is in my Web.config, but not the application root one, the one under &lt;code&gt;/Areas/Test/Views/Web.config&lt;/code&gt;.  I open it in Visual Studio, and sure enough, underscores.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-xml"&gt;&amp;lt;configSections&amp;gt;
  &amp;lt;sectionGroup name=&amp;quot;system.web.webPages.razor&amp;quot; type=&amp;quot;System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=__WebPagesVersion__.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&amp;quot;&amp;gt;
    &amp;lt;section name=&amp;quot;host&amp;quot; type=&amp;quot;System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=__WebPagesVersion__.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&amp;quot; requirePermission=&amp;quot;false&amp;quot; /&amp;gt;
    &amp;lt;section name=&amp;quot;pages&amp;quot; type=&amp;quot;System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=__WebPagesVersion__.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&amp;quot; requirePermission=&amp;quot;false&amp;quot; /&amp;gt;
  &amp;lt;/sectionGroup&amp;gt;
&amp;lt;/configSections&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I compare that to the other &lt;code&gt;Web.config&lt;/code&gt; under the root &lt;code&gt;/Views/Web.config&lt;/code&gt;, and copy and paste those values in.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-xml"&gt;&amp;lt;configSections&amp;gt;
  &amp;lt;sectionGroup name=&amp;quot;system.web.webPages.razor&amp;quot; type=&amp;quot;System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&amp;quot;&amp;gt;
    &amp;lt;section name=&amp;quot;host&amp;quot; type=&amp;quot;System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&amp;quot; requirePermission=&amp;quot;false&amp;quot; /&amp;gt;
    &amp;lt;section name=&amp;quot;pages&amp;quot; type=&amp;quot;System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35&amp;quot; requirePermission=&amp;quot;false&amp;quot; /&amp;gt;
  &amp;lt;/sectionGroup&amp;gt;
&amp;lt;/configSections&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At this point, I'm assuming there is a bug in the &amp;quot;Add Area&amp;quot; template.  So let's build and refresh the browser and it should work now, right?&lt;/p&gt;
&lt;h2 id="the-second-error"&gt;The second error&lt;/h2&gt;
&lt;p&gt;Of course not.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2012/12/image_thumb_6.png" alt="https://cdn.volaresoftware.com/images/posts/2012/12/image_thumb_6.png" /&gt;&lt;/p&gt;
&lt;p&gt;Hmm.  Lots of details in that stack trace, but not much to go on here.  I checked my route registration code and checked my area registration code.  Both looked fine:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;using System.Web.Mvc;
using System.Web.Routing;
&lt;p&gt;namespace MvcApplication2.App_Start
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute(&amp;quot;.axd/{*pathInfo}&amp;quot;);&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;        routes.MapRoute(
            name: &amp;amp;quot;Default&amp;amp;quot;,
            url: &amp;amp;quot;{controller}/{action}/{id}&amp;amp;quot;,
            defaults: new {controller = &amp;amp;quot;Home&amp;amp;quot;, action = &amp;amp;quot;Index&amp;amp;quot;, id = UrlParameter.Optional},
            namespaces: new[] { &amp;amp;quot;MvcApplication2.Controllers&amp;amp;quot; }
            );
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;using System.Web.Mvc;&lt;/p&gt;
&lt;p&gt;namespace MvcApplication2.Areas.Test
{
public class TestAreaRegistration : AreaRegistration
{
public override string AreaName
{
get { return &amp;quot;Test&amp;quot;; }
}&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    public override void RegisterArea(AreaRegistrationContext context)
    {
        context.MapRoute(
            name: &amp;amp;quot;Test_default&amp;amp;quot;,
            url: &amp;amp;quot;Test/{controller}/{action}/{id}&amp;amp;quot;,
            defaults: new {action = &amp;amp;quot;Index&amp;amp;quot;, id = UrlParameter.Optional},
            namespaces: new[] {&amp;amp;quot;MvcApplication2.Areas.Test.Controllers&amp;amp;quot;}
            );
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;I also added the namespaces to the area (the last parameter above) to help the routing engine find the right controller.  That looked fine, too.&lt;/p&gt;
&lt;p&gt;The error message was about a bad assembly (&amp;quot;The given assembly name or codebase was invalid.&amp;quot;).  Maybe something didn't get built or loaded right ?  I tried a Clean and Rebuild.  No luck.&lt;/p&gt;
&lt;p&gt;Maybe ASP.NET temp files were cached?  Let's clear browser cache, close and re-open the browser, close and re-open Visual Studio, restart IIS Express, and see if that helps….and no, no luck.&lt;/p&gt;
&lt;h2 id="the-solution"&gt;The solution&lt;/h2&gt;
&lt;p&gt;I was running out of ideas, but since the first problem was the &lt;code&gt;Web.config&lt;/code&gt;, maybe this was, too.  I opened up the generated &lt;code&gt;Web.config&lt;/code&gt; under &lt;code&gt;/Areas/Test/Views/Web.config&lt;/code&gt; again and compared it to the one under the root &lt;code&gt;/Views/Web.config&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Sure enough, more freaking underscores.  I just copied ALL the values from the root view's &lt;code&gt;Web.config&lt;/code&gt; into the areas one, built, refreshed, and finally got the areas showing up.&lt;/p&gt;
&lt;p&gt;Maybe I have a wacky install.  Maybe I got hold of some bad pre-release NuGet package.  But it seems there is a template bug here when adding Areas to an MVC project.  I have the Fall Update on Visual Studio 2012, so my About screen looks like this:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2012/12/image_thumb_8.png" alt="https://cdn.volaresoftware.com/images/posts/2012/12/image_thumb_8.png" /&gt;&lt;/p&gt;
&lt;p&gt;I'm writing this up in the hopes that I save someone else some time.  If you have suggestions on where I got an underscore happy template, please let me know in the comments below.&lt;/p&gt;
</description>
      <pubDate>Thu, 13 Dec 2012 01:39:38 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/running-specflow-and-watin-tests-with-teamcity-and-appharbor</guid>
      <link>https://volaresoftware.com/en/technical-posts/running-specflow-and-watin-tests-with-teamcity-and-appharbor</link>
      <title>Running SpecFlow and WatiN tests with TeamCity and AppHarbor</title>
      <description>&lt;p&gt;If you're using SpecFlow and WatiN to automate your web testing, things work great on localhost, but tend to fall apart on the continuous integration server.  It's a &amp;quot;chicken or the egg&amp;quot; paradox.  If the new code hasn't been deployed yet, it can't be externally tested with WatiN, but it shouldn't be deployed until all the tests have passed.  What are you supposed to do?&lt;/p&gt;
&lt;h2 id="teamcity"&gt;TeamCity&lt;/h2&gt;
&lt;p&gt;If your SpecFlow and WatiN tests are in their own assembly (something like &lt;code&gt;MyProject.AcceptanceTests.dll&lt;/code&gt;), and you're using TeamCity, it's easy to run your unit tests and integration tests, then deploy the code to a web server, then run your acceptance tests in a separate build step.  It's just a matter of breaking up the steps and designating which test assemblies will be run at which time.&lt;/p&gt;
&lt;p&gt;This step in the screen shot below is running the unit tests and integration tests.  A separate, later step will run the tests in the &lt;code&gt;**\*AcceptanceTests.dll&lt;/code&gt; assembly after the code has been deployed to the web server.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2011/6/image_9.png" alt="image_9.png" /&gt;&lt;/p&gt;
&lt;h2 id="appharbor"&gt;AppHarbor&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2011/6/image_10.png" alt="image_10.png" /&gt;&lt;/p&gt;
&lt;p&gt;If you're using AppHarbor to run your tests on check in with &lt;code&gt;git push appharbor master&lt;/code&gt;, (and you should - it's super easy), you don't want to run your web tests until the code is deployed, but AppHarbor doesn't deploy &lt;strong&gt;anything&lt;/strong&gt; until all the tests pass.&lt;/p&gt;
&lt;p&gt;What we want is for AppHarbor to ignore the web automation tests until the code is deployed.  AppHarbor flips a &lt;code&gt;*.config&lt;/code&gt; &lt;code&gt;appSetting&lt;/code&gt; key named &amp;quot;Environment&amp;quot; to &amp;quot;Test&amp;quot; when it's testing and to &amp;quot;Release&amp;quot; when the code is deployed.  So while your tests are running, your &lt;code&gt;App.config&lt;/code&gt; in your test project should look something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-xml"&gt;&amp;lt;appSettings&amp;gt;
  &amp;lt;add key=&amp;quot;Environment&amp;quot; value=&amp;quot;Test&amp;quot;/&amp;gt;
&amp;lt;/appSettings&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can take advantage of this &lt;code&gt;appSetting&lt;/code&gt; test runner change to tell SpecFlow to ignore this set of tests, which allows AppHarbor to continue running other tests and deploying the code.&lt;/p&gt;
&lt;p&gt;This is not be the most elegant way to do this, but I got this working today:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;[Binding]
public class MyStepDefinition
{
    [BeforeFeature]
    public void BeforeFeature()
    {
        if (ConfigurationManager.AppSettings[&amp;quot;Environment&amp;quot;] == &amp;quot;Test&amp;quot;)
            Assert.Ignore();
    }
&lt;pre&gt;&lt;code&gt;// Rest of step definition code...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;BeforeFeature&lt;/code&gt; attribute tells the SpecFlow test runner to execute that method before each feature.  With a quick check on the Environment &lt;code&gt;appSetting&lt;/code&gt; value, we can tell AppHarbor to ignore this test and continue processing.  This will ignore all scenarios in all feature files.  Since all my scenarios are web automation tests, that works for me.&lt;/p&gt;
&lt;p&gt;But what if you have some scenarios that rely on web automation testing and others that don't?  A more targeted approach would be to set a SpecFlow tag, like @web over the SpecFlow scenarios that require web automation testing to pass.  Then in the [BeforeScenario(&amp;quot;web&amp;quot;)] handlers for that tag, you could set Assert.Ignore to skip those scenarios while executing all other scenarios.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;[BeforeScenario(&amp;quot;web&amp;quot;)]
public void BeforeScenario()
{
    if (ConfigurationManager.AppSettings[&amp;quot;Environment&amp;quot;] == &amp;quot;Test&amp;quot;)
        Assert.Ignore();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once your non-web automation tests have passed and the code is deployed, you can point your local test runner at the AppHarbor URL and test against the newly deployed web app.&lt;/p&gt;
</description>
      <pubDate>Fri, 03 Jun 2011 00:40:12 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/sharing-data-from-within-your-windows-8-app-using-javascript</guid>
      <link>https://volaresoftware.com/en/technical-posts/sharing-data-from-within-your-windows-8-app-using-javascript</link>
      <title>Sharing data from within your Windows 8 app using JavaScript</title>
      <description>&lt;p&gt;One of the nifty features of Windows 8 is the ability of the OS to share data between apps.  For instance, if I open the Weather app, click Windows + H, I get the Share bar that let's me send the weather forecast to the Mail, Tweetro, or People apps.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2012/10/image_21.png" alt="image_21.png" /&gt;&lt;/p&gt;
&lt;p&gt;Most sharing apps take relevant text, HTML, and links, and prepare a draft email, tweet, etc. for you to send.  Here is the HTML the Mail app prepares to send from the Weather app:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2012/10/image_22.png" alt="image_22.png" /&gt;&lt;/p&gt;
&lt;p&gt;This post is about how to do the same thing from within your app.&lt;/p&gt;
&lt;h2 id="what-do-you-want-to-share"&gt;What do you want to share?&lt;/h2&gt;
&lt;p&gt;You can share text, HTML, images, files, etc.  I'm going to share text with my current location information from an altitude app.  This is what we're going for:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2012/10/image_23.png" alt="image_23.png" /&gt;&lt;/p&gt;
&lt;p&gt;It's just plain text, but &lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh771179.aspx"&gt;you can get fancier&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="listen-for-the-sharing-event"&gt;Listen for the sharing event&lt;/h2&gt;
&lt;p&gt;The first thing you'll do in your code is listen for Windows 8 telling you the user wants to share something.  Wire up the sharing event listener in your &amp;quot;ready&amp;quot; code, and unhook it in your &amp;quot;unload&amp;quot; code like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;var dataTransferManager;
&lt;p&gt;var page = WinJS.UI.Pages.define(&amp;quot;/default.html&amp;quot;, {
ready: function(element, options) {
dataTransferManager = Windows.ApplicationModel.DataTransfer.DataTransferManager.getForCurrentView();
dataTransferManager.addEventListener(&amp;quot;datarequested&amp;quot;, onSharingRequested);
},
unload: function() {
dataTransferManager.removeEventListener(&amp;quot;datarequested&amp;quot;, onSharingRequested);
}
});
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="build-up-the-sharing-payload"&gt;Build up the Sharing payload&lt;/h2&gt;
&lt;p&gt;Now we've got a function called &amp;quot;onSharingRequested&amp;quot; that will run when the user starts sharing within our app, but we need to write the code in that event/function to build up the text to share.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;function onSharingRequested(e) {
    var request = e.request;
    request.data.properties.title = &amp;quot;My current altitude and location&amp;quot;;
    request.data.setText(&amp;quot;My current altitude and location are Altitude: &amp;quot; + location.altitude + &amp;quot; &amp;quot; + location.altitudeUnits +
        &amp;quot;, Latitude: &amp;quot; + location.latitudeFormatted + &amp;quot;, Longitude: &amp;quot; + location.longitudeFormatted +
        &amp;quot;, Accuracy: &amp;quot; + location.accuracy + &amp;quot;, Near: &amp;quot; + location.near);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You set properties on the passed in request object, like the title and the text shown here.  The title must be set or sharing won't work.&lt;/p&gt;
&lt;h2 id="adding-a-button-to-start-sharing"&gt;Adding a button to start Sharing&lt;/h2&gt;
&lt;p&gt;Sharing data between apps is something people will probably get used to eventually, but if you want to be sure the users of your app know they can share, make a button that does that same thing as Windows + H or a swipe from the right on a tablet.&lt;/p&gt;
&lt;p&gt;On your button click event, call the showShareUI method of the DataTransferManager like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;function onSharingButtonClick() {
    Windows.ApplicationModel.DataTransfer.DataTransferManager.showShareUI();
}
&lt;/code&gt;&lt;/pre&gt;
</description>
      <pubDate>Wed, 17 Oct 2012 00:39:51 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/validation-frameworks-in-aspnet-mvc</guid>
      <link>https://volaresoftware.com/en/technical-posts/validation-frameworks-in-aspnet-mvc</link>
      <title>Validation frameworks in ASP.NET MVC</title>
      <description>&lt;p&gt;There are plenty of validation frameworks out there.  I've worked with &lt;a href="http://nhforge.org/wikis/validator/nhibernate-validator-1-0-0-documentation.aspx"&gt;NHibernate Validators&lt;/a&gt;, Microsoft's &lt;a href="http://msdn.microsoft.com/en-us/library/dd140112.aspx"&gt;Enterprise Application Blocks&lt;/a&gt;, and now &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.aspx"&gt;Data Annotations&lt;/a&gt;.  They primarily work by adding attributes to the properties in the class you want to validate.&lt;/p&gt;
&lt;h2 id="how-are-they-different"&gt;How are they different?&lt;/h2&gt;
&lt;p&gt;Not very.  The biggest difference between them is their syntax.  I guess the Validation Blocks from Microsoft's P&amp;amp;P group have a lot of configuration options, but I haven't needed that on a project.  The most prominent differences are in the attributes themselves.&lt;/p&gt;
&lt;p&gt;You can probably make a case for Data Annotations having a slight advantage since it's going to be in the .NET base-class libraries.  Easier to deal with assemblies installed in the GAC instead of the ones you have to drag around for each deployment.&lt;/p&gt;
&lt;h2 id="how-do-you-integrate-them-with-mvc"&gt;How do you integrate them with MVC?&lt;/h2&gt;
&lt;p&gt;Each of these frameworks can be integrated with ASP.NET MVC.  But the best validation call is one you don't have to explicitly make.  Huh?&lt;/p&gt;
&lt;p&gt;It's OK to call &lt;code&gt;MyClass.IsValid()&lt;/code&gt; in a controller action, but if you can avoid it, I think you're better off.  Otherwise, what happens if you &lt;strong&gt;forget&lt;/strong&gt; to call it?&lt;/p&gt;
&lt;p&gt;Instead, use a model binder that invokes the validation framework for you.  This is how I am using the Data Annotations model binder with the MVC framework:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;ModelBinders.Binders.DefaultBinder = new Microsoft.Web.Mvc.DataAnnotations.DataAnnotationsModelBinder();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now this guy will intercept calls to your controller actions and reject invalid incoming view models.  Here is a &lt;a href="http://www.asp.net/learn/mvc/tutorial-39-cs.aspx"&gt;simple tutorial for using Data Annotations&lt;/a&gt; that goes into more detail.&lt;/p&gt;
&lt;h2 id="how-do-you-lay-this-out-in-the-solution"&gt;How do you lay this out in the solution?&lt;/h2&gt;
&lt;p&gt;I have an Application Services layer that my MVC layer calls into.  My controllers have constructors with an interface to an application service injected into them.  My IoC container decides which concrete version of this application service interface to use at runtime.&lt;/p&gt;
&lt;p&gt;Next, my Application Service layer has a DTO folder that holds all the DTOs (property-only classes) my views need in my MVC app.  These are &lt;strong&gt;not&lt;/strong&gt; my domain entities.  There might be a lot of overlap with those domain entities, but these DTOs are &lt;strong&gt;just&lt;/strong&gt; there for communication between the UI layer and Application Services layer.  These DTOs are where I put my validation attributes.&lt;/p&gt;
&lt;p&gt;So now I've got views that are tightly bound to the DTOs, which are owned in the Application Services layer.  This allows strong typing of the view so I can use the DTO's properties as my view's model.  This is handy for the Html Helpers to get design-time IntelliSense and compile-time checking.&lt;/p&gt;
&lt;h2 id="what-else-can-you-do"&gt;What else can you do?&lt;/h2&gt;
&lt;p&gt;I haven't spent a lot of time looking into it, but &lt;a href="http://xval.codeplex.com/"&gt;xVal&lt;/a&gt; looks pretty strong for client side AND server side validation using Data Annotations and a couple other validation frameworks.  It also lets you validate your business rules in your domain and throw an exception.  I need to check into this more, because that sounds like the validation holy grail for validation to me: getting UI validation and business rule validation into a common format.&lt;/p&gt;
</description>
      <pubDate>Thu, 17 Sep 2009 00:41:23 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/the-case-for-tdd</guid>
      <link>https://volaresoftware.com/en/technical-posts/the-case-for-tdd</link>
      <title>The case for TDD</title>
      <description>&lt;p&gt;TDD is hard. It sounds like it wouldn't be hard. It's just a little test. The code is the hard part, right?  But it's &lt;strong&gt;really&lt;/strong&gt; hard to do it well. I struggle with it plenty and I know my way around C# and OO pretty well.&lt;/p&gt;
&lt;p&gt;There better be a payoff for this bass-ackwards way of coding.  It takes a while to get there, but I can see the light at the end of the tunnel in my own development.  Here's where I've seen my code improve as I've moved toward TDD:&lt;/p&gt;
&lt;h2 id="focusness"&gt;Focusness&lt;/h2&gt;
&lt;p&gt;You focus on the behavior of your code instead of the implementation.  You don't start by thinking of tables, classes, and properties (or in my case, try hard not to).  You start off thinking of the business requirements and roles.  User stories are popular because they push you into restating the requirements in context: &amp;quot;As a (some role)...I want to (do something)...so that (some business value)&amp;quot;.  The first two chunks of this can guide your test creation.  You can write methods that cover these scenarios.&lt;/p&gt;
&lt;p&gt;If you're doing it the RED-GREEN-REFACTOR way, you'll write a test and just enough for the code to compile, get the test to pass with the minimum amount of code possible.  Finally, you can go back and clean up what you aren't proud of from your first effort, then run the test again.  You get to keep repeating that until you are happy with the code and that the requirement/story is met and the user accepts it.&lt;/p&gt;
&lt;p&gt;Then you &lt;strong&gt;STOP&lt;/strong&gt;.  That's the fourth step you don't see in the pretty RED-GREEN-REFACTOR icon.  If you don't stop, you loose your focus on the functionality and you start trying to gold-plate the code.  Which can lead to...&lt;/p&gt;
&lt;h2 id="dude-you-know-what-would-make-this-really-cool"&gt;Dude, you know what would make this REALLY cool?&lt;/h2&gt;
&lt;p&gt;You're getting paid to write software to meet the requirements.  If you going beyond that, be careful who you're doing the coding for.  If it's the business, and you're glad to show them how much time you've spent on it, you might be justified in doing it.  But if you're coding it for yourself, do it on your own time.&lt;/p&gt;
&lt;p&gt;Unfortunately, people who are drawn to programming are often tinkerers and bit-twiddlers.  I appreciate having a framework for my development that keeps me on task, because I am easily distracted by grand visions of what I might be able to code into the app.  There is no code we couldn't tweak a little and add this new cool pattern or just-learned technique to.  TDD forces you to go directly to the requirements, not the technology.&lt;/p&gt;
&lt;h2 id="solid-code"&gt;SOLID code&lt;/h2&gt;
&lt;p&gt;The more you move toward TDD, the more little classes you have with giant names.  Same thing with methods.  There are tons, they are very short (one screen or so max), and they have long names.  This is progress?&lt;/p&gt;
&lt;p&gt;Yes, I think it is because of the &lt;a href="https://en.wikipedia.org/wiki/SOLID"&gt;SOLID principals&lt;/a&gt;. SOLID is a horrible acronym of acronyms, but it can help you keep some object-oriented principals in mind. I'll go over it and how I've tried to learn it in more depth in a future post, but &lt;a href="http://www.lostechies.com/blogs/chad_myers/archive/2008/03/07/pablo-s-topic-of-the-month-march-solid-principles.aspx"&gt;the guys at Los Techies covered SOLID in depth&lt;/a&gt; already.  So the side effect of decoupled code is you have lots of little files that just do one little thing.  It took me a while to get over this and the file bloat in the project, but I'm at peace with it now. The payoff is that I am using more SOLID principals than I was before, and that's a good thing.&lt;/p&gt;
&lt;h2 id="oh-yeah-you-get-some-tests-too"&gt;Oh yeah, you get some tests, too&lt;/h2&gt;
&lt;p&gt;It's been said before, but TDD is kind of misnamed.  Yes, you start with the test, but that's not the most important thing.  The most important thing is the requirement focus and the way it drives you toward a more loosely coupled design.  But it's pretty fun to see that screen light up with green checks or circles after you've made a change.&lt;/p&gt;
&lt;p&gt;The real value of the tests themselves is that today's unit tests become tomorrow's regression tests.  You won't remember why you wrote the code last week, but you don't have to.  The tests can also serve as mini-documentation of the requirements if you write the test names in a consistent way.  There are BDD frameworks that let you spit out some HTML to do exactly this.&lt;/p&gt;
&lt;h2 id="ruthless-refactoring"&gt;Ruthless Refactoring&lt;/h2&gt;
&lt;p&gt;All this adds up to something of a safety net for refactoring. Think of the confidence you can have changing the code, even if it's another team members code.  Or if (gasp!) they make changes to your code.  It's nice to know your code still works.&lt;/p&gt;
&lt;p&gt;If you write the tests first, you know you've got the &amp;quot;happy path&amp;quot; covered on your code.  That's the one you started with.  You can write a few more tests to cover the likely deviations from that happy path, but when you get to the weird stuff (what if you order $999,999,999,999 in widgets?), call it good and move on.&lt;/p&gt;
</description>
      <pubDate>Fri, 17 Jul 2009 11:39:00 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/showing-and-saving-user-settings-in-a-windows-8-app-with-javascript</guid>
      <link>https://volaresoftware.com/en/technical-posts/showing-and-saving-user-settings-in-a-windows-8-app-with-javascript</link>
      <title>Showing and saving user settings in a Windows 8 app with JavaScript</title>
      <description>&lt;p&gt;If your Windows 8 app has user-based settings, you need a place to show those values, let users change them, and save them for later use.  Sometimes these are called preferences, but in Windows 8, they are called &amp;quot;settings&amp;quot;.&lt;/p&gt;
&lt;p&gt;You can see and set your settings in a Windows 8 app with Windows + I.  You'll pull up a fly out dialog from the right like this:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2012/10/image_24.png" alt="image_24.png" /&gt;&lt;/p&gt;
&lt;p&gt;Clicking on the &amp;quot;Options&amp;quot; choice opens up the settings for the app:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2012/10/image_25.png" alt="image_25.png" /&gt;&lt;/p&gt;
&lt;p&gt;Before you dive in and do this with your app, get acquainted with the &lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh770544.aspx"&gt;Windows 8 app settings guidelines&lt;/a&gt;.  Here's what I did for mine.&lt;/p&gt;
&lt;h2 id="create-the-options-view"&gt;Create the Options view&lt;/h2&gt;
&lt;p&gt;Here is my &lt;code&gt;options.html&lt;/code&gt; file.  Most of this is plain old HTML.  Note the ID of the outer div is &amp;quot;options&amp;quot;.  This could be named anything, but keep that ID in mind since we'll need it later.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;quot;utf-8&amp;quot; /&amp;gt;
    &amp;lt;title&amp;gt;Options&amp;lt;/title&amp;gt;
&lt;pre&gt;&lt;code&gt;&amp;amp;lt;!-- WinJS references --&amp;amp;gt;
&amp;amp;lt;link href=&amp;amp;quot;https://volaresoftware.com/blog/Microsoft.WinJS.1.0/css/ui-light.css&amp;amp;quot; rel=&amp;amp;quot;stylesheet&amp;amp;quot; /&amp;amp;gt;
&amp;amp;lt;script src=&amp;amp;quot;//Microsoft.WinJS.1.0/js/base.js&amp;amp;quot;&amp;amp;gt;&amp;amp;lt;/script&amp;amp;gt;
&amp;amp;lt;script src=&amp;amp;quot;//Microsoft.WinJS.1.0/js/ui.js&amp;amp;quot;&amp;amp;gt;&amp;amp;lt;/script&amp;amp;gt;

&amp;amp;lt;!-- App references --&amp;amp;gt;
&amp;amp;lt;link href=&amp;amp;quot;https://volaresoftware.com/blog/css/settings.css&amp;amp;quot; rel=&amp;amp;quot;stylesheet&amp;amp;quot; /&amp;amp;gt;
&amp;amp;lt;script src=&amp;amp;quot;/js/app/options.js&amp;amp;quot;&amp;amp;gt;&amp;amp;lt;/script&amp;amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;div id=&amp;quot;options&amp;quot; class=&amp;quot;win-settingsflyout&amp;quot; data-win-control=&amp;quot;WinJS.UI.SettingsFlyout&amp;quot; data-win-options=&amp;quot;{ width:'narrow' }&amp;quot;&amp;gt;
&amp;lt;div class=&amp;quot;win-header&amp;quot;&amp;gt;
&amp;lt;button id=&amp;quot;backButton&amp;quot; class=&amp;quot;win-backbutton&amp;quot; aria-label=&amp;quot;Back&amp;quot; onclick=&amp;quot;WinJS.UI.SettingsFlyout.show()&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;
&amp;lt;div class=&amp;quot;win-label&amp;quot;&amp;gt;Options&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div class=&amp;quot;win-content&amp;quot;&amp;gt;
&amp;lt;div class=&amp;quot;win-settings-section&amp;quot;&amp;gt;
&amp;lt;p&amp;gt;
&amp;lt;label&amp;gt;Use feet or meters&amp;lt;/label&amp;gt;
&amp;lt;label&amp;gt;
&amp;lt;input id=&amp;quot;feet&amp;quot; name=&amp;quot;feetOrMeters&amp;quot; type=&amp;quot;radio&amp;quot; value=&amp;quot;Feet&amp;quot; checked /&amp;gt;Feet
&amp;lt;/label&amp;gt;
&amp;lt;label&amp;gt;
&amp;lt;input id=&amp;quot;meters&amp;quot; name=&amp;quot;feetOrMeters&amp;quot; type=&amp;quot;radio&amp;quot; value=&amp;quot;Meters&amp;quot; /&amp;gt;Meters
&amp;lt;/label&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;
&amp;lt;label for=&amp;quot;refreshInterval&amp;quot;&amp;gt;Refresh interval in minutes&amp;lt;/label&amp;gt;
&amp;lt;input id=&amp;quot;refreshInterval&amp;quot; name=&amp;quot;refreshInterval&amp;quot; type=&amp;quot;range&amp;quot; min=&amp;quot;0&amp;quot; max=&amp;quot;15&amp;quot; value=&amp;quot;1&amp;quot; /&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;
&amp;lt;label for=&amp;quot;movementThreshold&amp;quot;&amp;gt;Movement threshold in feet&amp;lt;/label&amp;gt;
&amp;lt;input id=&amp;quot;movementThreshold&amp;quot; name=&amp;quot;movementThreshold&amp;quot; type=&amp;quot;range&amp;quot; min=&amp;quot;0&amp;quot; max=&amp;quot;100&amp;quot; value=&amp;quot;50&amp;quot; /&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;The CSS classes may not be familiar, but these are coming from the Windows 8 SDK CSS (&lt;code&gt;ui-light.css&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;The interesting parts are 1) there is no form tag or submit button (we'll see the JavaScript below that works with these values), 2) the data-win-control stuff in the top level div,&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;div id=&amp;quot;options&amp;quot; class=&amp;quot;win-settingsflyout&amp;quot; data-win-control=&amp;quot;WinJS.UI.SettingsFlyout&amp;quot; data-win-options=&amp;quot;{ width:'narrow' }&amp;quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and 3) the onclick event for the back button that calls WinJS.UI.SettingsFlyout.show().&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;button id=&amp;quot;backButton&amp;quot; class=&amp;quot;win-backbutton&amp;quot; aria-label=&amp;quot;Back&amp;quot; onclick=&amp;quot;WinJS.UI.SettingsFlyout.show()&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The WinJS area we're working with here is the &lt;code&gt;SettingsFlyout&lt;/code&gt;, and the &lt;code&gt;show()&lt;/code&gt; and &lt;code&gt;hide()&lt;/code&gt; methods display it and move it out of the way.&lt;/p&gt;
&lt;p&gt;In modern web development, it's a venial sin to put JavaScript code in the onclick event of a button.  We usually aim for unobtrusive JavaScript where all the events are wired up in JavaScript and the HTML just does the layout.  I think that's a good practice, but for a back button like this, it makes the JavaScript more cluttered to have a tangential concern shoved in there.  So take your pick on where you put your onclick event – the button itself or the JavaScript file.&lt;/p&gt;
&lt;h2 id="open-the-options-view"&gt;Open the Options view&lt;/h2&gt;
&lt;p&gt;Now that we've got lovely labels and inputs to show in the Settings pane, we're ready to show it off.  Add the following to your default.js file:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;app.onsettings = function(e) {
    e.detail.applicationcommands = {
        &amp;quot;options&amp;quot;: {title: &amp;quot;Options&amp;quot;, href: &amp;quot;/pages/settings/options.html&amp;quot;},
    };
    WinJS.UI.SettingsFlyout.populateSettings(e);
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This code will listen for the application's onsettings event (the &amp;quot;app&amp;quot; variable here = &lt;code&gt;WinJS.Application&lt;/code&gt;) and open the &lt;code&gt;options.html&lt;/code&gt; file in the href above.  The title is what you want the user to see on the app's Settings pane.  Clicking it will open your view where they can change values.  The &amp;quot;options&amp;quot; part on the left side is the ID of the div it will look for in the options.html file.&lt;/p&gt;
&lt;p&gt;At this point, you should be able to run your app and type Windows + I and see the app's settings pane, then click Options and see your app's options and the options.html input controls.  Nothing will be reading or writing any data yet, so let's do that next.&lt;/p&gt;
&lt;h2 id="save-and-recall-user-settings-for-your-app"&gt;Save and recall user settings for your app&lt;/h2&gt;
&lt;p&gt;There are &lt;a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh464917.aspx"&gt;three built-in storage areas for your Windows 8 app&lt;/a&gt;:  local storage, roaming storage, and temporary storage.  You can  also use &lt;a href="http://msdn.microsoft.com/en-us/library/live/hh826521.aspx"&gt;SkyDrive&lt;/a&gt;, &lt;a href="https://www.windowsazure.com/en-us/develop/mobile/"&gt;Windows Azure Mobile Services&lt;/a&gt;, or your own homemade JSON API that reads and writes to your own database.&lt;/p&gt;
&lt;p&gt;For app settings, I think roaming makes the most sense.  Users will expect your app to remember their settings across different devices, and that's what roaming provides with no extra work on your part.  The real difference between roaming and local you have to consider is, roaming storage is limited to 100k and can't hold binary data. If that won't work for your app, look into local storage, SkyDrive for files or photos, or Azure Mobile Services for structured data.&lt;/p&gt;
&lt;p&gt;Here's the &lt;code&gt;options.js&lt;/code&gt; file that pulls values from options.html and reads and writes values from the inputs:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;(function() {
    &amp;quot;use strict&amp;quot;;
&lt;pre&gt;&lt;code&gt;var appData = Windows.Storage.ApplicationData.current.roamingSettings;

WinJS.UI.Pages.define(&amp;amp;quot;/pages/settings/options.html&amp;amp;quot;, {
    // This function is called whenever a user navigates to this page. It
    // populates the page elements with the app's data.
    ready: function (element, options) {
        var feetRadio = document.getElementById(&amp;amp;quot;feet&amp;amp;quot;),
            metersRadio = document.getElementById(&amp;amp;quot;meters&amp;amp;quot;),
            refreshIntervalRange = document.getElementById(&amp;amp;quot;refreshInterval&amp;amp;quot;),
            movementThresholdRange = document.getElementById(&amp;amp;quot;movementThreshold&amp;amp;quot;);

        // Set settings to existing values
        if (appData.values.size &amp;amp;gt; 0) {
            if (appData.values[&amp;amp;quot;feetOrMeters&amp;amp;quot;]) {
                setFeetOrMetersValue();
            }
            if (appData.values[&amp;amp;quot;refreshInterval&amp;amp;quot;]) {
                refreshIntervalRange.value = appData.values[&amp;amp;quot;refreshInterval&amp;amp;quot;];
            }
            if (appData.values[&amp;amp;quot;movementThresholdInFeet&amp;amp;quot;]) {
                movementThresholdRange.value = appData.values[&amp;amp;quot;movementThresholdInFeet&amp;amp;quot;];
            }
        }

        // Wire up on change events for settings controls
        feetRadio.onchange = function () {
            appData.values[&amp;amp;quot;feetOrMeters&amp;amp;quot;] = getFeetOrMetersValue();
        };
        metersRadio.onchange = function () {
            appData.values[&amp;amp;quot;feetOrMeters&amp;amp;quot;] = getFeetOrMetersValue();
        };
        refreshIntervalRange.onchange = function() {
            appData.values[&amp;amp;quot;refreshInterval&amp;amp;quot;] = refreshIntervalRange.value;
        };
        movementThresholdRange.onchange = function() {
            appData.values[&amp;amp;quot;movementThresholdInFeet&amp;amp;quot;] = movementThresholdRange.value;
        };
    },

    unload: function() {
        // Respond to navigations away from this page.
    },

    updateLayout: function(element, viewState, lastViewState) {
        // Respond to changes in viewState.
    }
});

function getFeetOrMetersValue() {
    var feetOrMetersRadio = document.getElementsByName(&amp;amp;quot;feetOrMeters&amp;amp;quot;);
    for (var i = 0; i &amp;amp;lt; feetOrMetersRadio.length; i++) {
        if (feetOrMetersRadio[i].checked) {
            return feetOrMetersRadio[i].value;
        }
    }
}

function setFeetOrMetersValue() {
    var feetOrMetersRadio = document.getElementsByName(&amp;amp;quot;feetOrMeters&amp;amp;quot;);
    for (var i = 0; i &amp;amp;lt; feetOrMetersRadio.length; i++) {
        if (feetOrMetersRadio[i].value === appData.values[&amp;amp;quot;feetOrMeters&amp;amp;quot;]) {
            feetOrMetersRadio[i].checked = true;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;})();
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;I'm using the &lt;code&gt;Windows.Storage.ApplicationData.current.roamingSettings&lt;/code&gt; (shortened to the appData variable) to read and write from roaming settings with the syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;appData.values[&amp;quot;theKey&amp;quot;] = theValue;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It's a key value store, so if you've worked with cookies in the past, this will seem familiar.&lt;/p&gt;
&lt;p&gt;The existing values (if there are any) are pushed into the input controls.  Next, the onchange events on the options.html inputs are wired up to write the new values.  You may also have other things you have to do in your app when the user changes a setting value, like redraw or hide something, etc.&lt;/p&gt;
</description>
      <pubDate>Tue, 23 Oct 2012 00:39:49 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/push-your-logic-to-the-core</guid>
      <link>https://volaresoftware.com/en/technical-posts/push-your-logic-to-the-core</link>
      <title>Push your logic to the core</title>
      <description>&lt;h2 id="creeping-logic"&gt;Creeping logic&lt;/h2&gt;
&lt;p&gt;Developers struggle with where to put their business logic.  We all know at an intellectual level that we should be keeping business rules and logic in some kind of a business layer, but I don't see it in practice that often.  I do see a lot of business layers that turn around and call data layers.  There's often nothing business-y about them.&lt;/p&gt;
&lt;p&gt;Instead, the logic is sprinkled throughout the other layers, sometimes to take advantage of a technology, sometimes because of the strengths of the developer who wrote the code.&lt;/p&gt;
&lt;p&gt;Validation controls in ASP.NET Web Forms are an example of business logic in the UI layer.  Another is an ASP.NET Web Forms code behind event that calculate discounts for preferred customers on Page_Load.&lt;/p&gt;
&lt;p&gt;ASP.NET MVC isn't immune from this either, although the validation logic story is better with Data Annotations letting validation rules flow up to the UI.  Controller actions can be mistreated just like code-behind and often contain more business logic than they should.&lt;/p&gt;
&lt;p&gt;And putting more logic in stored procs doesn't make your app dev teams more agile.  It makes the data team the bottleneck for logic changes.&lt;/p&gt;
&lt;h2 id="journey-to-the-center-of-the-app"&gt;Journey to the Center of the App&lt;/h2&gt;
&lt;p&gt;A better approach is to lift that logic out of those layers and put it in your business/domain/core layer in C# &lt;a href="http://en.wikipedia.org/wiki/Plain_Old_CLR_Object"&gt;POCOs&lt;/a&gt;.  In many apps, this logic is what makes the app worthwhile.  Sometimes, it's what gives the company a competitive advantage.  It should be clear, expressive, and long lived code.  It should not be coupled to any particular technology.&lt;/p&gt;
&lt;p&gt;These can be tricky changes to make once an app is partly finished or already up and working in production.  There can be a lot of refactoring.  But the effort can pay off in making the code more clear to anyone working on it and letting you make complex changes much faster because the logic is centralized and expressive.&lt;/p&gt;
&lt;h2 id="how-do-you-do-this"&gt;How do you do this?&lt;/h2&gt;
&lt;p&gt;One test I like to use for where the logic goes is, &amp;quot;What if the technology changed?&amp;quot;  What if I wasn't able to use Web Forms or MVC, but had to use Silverlight or any other future technology?  What if SQL Server went away?  What if we switched from stored procs to NHibernate and then again to Entity Framework?  If we've got business logic wrapped up in our tools, no matter what the tools are, we can be sure the logic will need to be rewritten when the technology changes.&lt;/p&gt;
&lt;p&gt;It's great to take advantage of new tools, but your code needs to keep it's distance where possible.  Wrap the tool with an interface or something so the tool is decoupled from your logic, and you can replace the technology if you need to. I've written about this &lt;a href="https://volaresoftware.com/en/technical-posts/unit-testing-untestable-code"&gt;interface wrapping technique&lt;/a&gt; before.&lt;/p&gt;
&lt;p&gt;Another great technique is using &lt;a href="http://en.wikipedia.org/wiki/Test_driven_development"&gt;TDD&lt;/a&gt; or other test-first approaches because your code will be written with an eye toward how it will be consumed. You'll end up with lots of small classes and methods with expressive names. This outside-in approach to coding really guides you toward creating a clean API for the app's first customer - your test code.&lt;/p&gt;
</description>
      <pubDate>Thu, 30 Dec 2010 01:40:30 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/generated-unit-tests-are-a-net-negative</guid>
      <link>https://volaresoftware.com/en/technical-posts/generated-unit-tests-are-a-net-negative</link>
      <title>Generated unit tests are a net negative</title>
      <description>&lt;p&gt;One of the most common misunderstandings for developers new to unit testing is the value of code coverage.  We intuitively know that if coverage is low, we don't have enough tests, and if coverage is high, we probably do.  Some IT shops even set minimum code coverage percentages, so if you check in code that drops the coverage metric below 80%, you fail the build.&lt;/p&gt;
&lt;p&gt;One way to get higher code coverage is to generate the tests.  Visual Studio has versions that can do this for you.  Point the code at a class, click OK a few times, and all your code in the class under test can be covered.  In fact, the generated test usually check for things you might not bother to, like what if there is a negative value passed in to a method, what if a zero passed in, what about a null, etc.  How can this be bad?  We're exercising the API of our class more fully, right?&lt;/p&gt;
&lt;h2 id="what-not-to-test"&gt;What not to test&lt;/h2&gt;
&lt;p&gt;I think the focus needs to be on testing the &lt;strong&gt;right&lt;/strong&gt; code in the &lt;strong&gt;right&lt;/strong&gt; way.  There is no point in testing the .NET framework.  If you have a auto property that is an int, you don't need to test -1, 0, 1, and null.  If int stops working, everyone using .NET has a bug.  But int isn't going to fail, and even if it does, it's not your code anyway (unless you work at Microsoft on the .NET framework team).&lt;/p&gt;
&lt;p&gt;So the first rule is be sure you're testing &lt;strong&gt;your&lt;/strong&gt; code.  That means testing your methods that do real stuff.  If you have a method in your class that just wraps a call to another class, there really isn't anything worth testing.  All you can test is that the class can be created and the method can be accessed and has those parameters and they are of that type.  But you can do that better by testing the underlying class instead of the pass-through method.&lt;/p&gt;
&lt;h2 id="go-faster-when-refactoring"&gt;Go faster when refactoring&lt;/h2&gt;
&lt;p&gt;In fact, testing these properties and pass-through methods and no arg constructors increases your code coverage numbers without adding anything meaningful to the test suite.  The net negative comes into play when it's time to refactor, whether it's adding or removing properties, renaming, moving things to different classes, etc.  Generated tests can really slow you down here as the new code stops building and the generated tests have to be removed and regenerated.&lt;/p&gt;
&lt;p&gt;A better way is to write the tests you need first, then add the code to implement that business rule or feature.  Whether you're using TDD, BDD or something else, you'll end up with tests that express the intent of the code rather than its implementation.  Tests should emphasize the features of the application, not the coding artifacts.  These are the kind of tests that add real value to your project.&lt;/p&gt;
</description>
      <pubDate>Tue, 12 Oct 2010 00:40:38 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/mvc-2-electric-boogaloo-whats-new-in-mvc-2</guid>
      <link>https://volaresoftware.com/en/technical-posts/mvc-2-electric-boogaloo-whats-new-in-mvc-2</link>
      <title>MVC 2: Electric Boogaloo - What's new in MVC 2</title>
      <description>&lt;p&gt;The MVC team loves their rec center, but an evil real estate developer wants to bulldoze it to build a hipster bar named Ruby's.  The team has been coding their butts off with MVC 2, but will the new features be enough to save the rec center?  Will the cynical real estate developer cackle and complain that it's still not enough?&lt;/p&gt;
&lt;p&gt;Will the MVC team get areas right?  Will the new templated HtmlHelpers strike the right balance of rapid development and fine control?  Will validation concerns get muddled up with UI concerns?  Will more web forms developers make the switch to MVC?&lt;/p&gt;
&lt;h2 id="new-areas"&gt;New Areas&lt;/h2&gt;
&lt;p&gt;Areas are an organizing tool for large web sites.  If you've got lots of view and lots of controllers plus some shared content, areas can work as a top-level routing mechanism.&lt;/p&gt;
&lt;p&gt;Example areas might be Admin for an administrative site, Store for a ecommerce site, etc.  They can be either folders or separate web projects.  Use the &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.mvc.arearegistration%28VS.100%29.aspx"&gt;AreaRegistration&lt;/a&gt; class to set up your routes in your Global.asax (taken from &lt;a href="http://msdn.microsoft.com/en-us/library/ee307987%28VS.100%29.aspx"&gt;MSDN article&lt;/a&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute(&amp;quot;{resource}.axd/{*pathInfo}&amp;quot;);
&lt;pre&gt;&lt;code&gt;AreaRegistration.RegisterAllAreas();

routes.MapRoute(
    &amp;amp;quot;Default&amp;amp;quot;,                                              // Route name
    &amp;amp;quot;{controller}/{action}/{id}&amp;amp;quot;,                           // URL with parameters
    new { controller = &amp;amp;quot;Home&amp;amp;quot;, action = &amp;amp;quot;Index&amp;amp;quot;, id = &amp;amp;quot;&amp;amp;quot; }  // Parameter defaults
);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Then override AreaRegistration in the area's folder or in the root of the area web project (also taken from &lt;a href="http://msdn.microsoft.com/en-us/library/ee307987%28VS.100%29.aspx"&gt;MSDN article&lt;/a&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
&lt;p&gt;namespace Store
{
public class Routes : AreaRegistration
{
public override string AreaName
{
get { return &amp;quot;Store&amp;quot;; }
}&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    public override void RegisterArea(AreaRegistrationContext context)
    {
        context.MapRoute(
            &amp;amp;quot;Store_Default&amp;amp;quot;,
            &amp;amp;quot;Store/{controller}/{action}/{id}&amp;amp;quot;,
            new { controller = &amp;amp;quot;Products&amp;amp;quot;, action = &amp;amp;quot;List&amp;amp;quot;, id = &amp;amp;quot;&amp;amp;quot; }
        );
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.sharparchitecture.net/"&gt;Sharp Architecture&lt;/a&gt; has had areas since its first release.  I remember hearing rumors about areas coming in MVC for version 1.0, but I guess it wasn't ready.  The biggest difference between the Microsoft version and the Sharp Architecture version is that the Microsoft version lets you register different web projects.&lt;/p&gt;
&lt;p&gt;Theoretically, multiple teams can work on multiple web projects, then these web projects can be rolled into the same solution and AreaRegistration can make them appear as one big web site to a browser.  I don't know how much of a need that is, but I guess if you have distributed teams that can't get to the same source code repository, it might be useful.  I prefer multiple folders in one web project over multiple web projects to keep build times down and Visual Studio responsiveness up.  I wouldn't break out each logical web site section to its own web project until the folder approach stopped working.&lt;/p&gt;
&lt;h2 id="new-htmlhelpers"&gt;New HtmlHelpers&lt;/h2&gt;
&lt;p&gt;I'm not sure if &lt;a href="http://code.google.com/p/codecampserver/"&gt;Code Camp Server&lt;/a&gt; pushed the MVC team into this or just showed how it was possible to take HtmlHelpers to this extreme, but I'm glad to see the same concepts getting rolled into the base class libraries.&lt;/p&gt;
&lt;p&gt;I think the new HtmlHelpers do give a nice range of control over your markup.  You can use:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;%= Html.LabelFor(x =&amp;gt; x.FirstName) %&amp;gt;
&amp;lt;%= Html.EditorFor(x =&amp;gt; x.FirstName) %&amp;gt;
&amp;lt;%= Html.LabelFor(x =&amp;gt; x.LastName) %&amp;gt;
&amp;lt;%= Html.EditorFor(x =&amp;gt; x.LastName) %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;if you want to be fairly explicit for each form element.  Or you can save a lot of keystrokes with:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;%= Html.EditorFor(x =&amp;gt; x) %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And if that's not enough, you can decorate your models with some &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.uihintattribute%28VS.100%29.aspx"&gt;UI hint attributes&lt;/a&gt; and roll your own rendering.  I think this is something large web projects will take advantage of for consistent markup and control rendering.  Seems like this has the advantages of homemade server controls without some of the hassles (&lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.inamingcontainer%28VS.100%29.aspx"&gt;INamingContainer&lt;/a&gt;, I'm looking at you).&lt;/p&gt;
&lt;h2 id="new-validation"&gt;New Validation&lt;/h2&gt;
&lt;p&gt;I did worry for a little bit about the UI stuff bleeding into the model with these new attributes.  Seems like we've got a leaky abstraction there.  But these days I think of the MVC model as the view model, not the domain model.  The view model is married to the view it works with.  It has no other purpose than to represent the data in that view.  Well, now it also validates the data in that view, at least initially.  Oh, and it now controls some of the view rendering.  Damn.  That's three responsibilities for my little view model.&lt;/p&gt;
&lt;p&gt;But I don't have an alternative proposal to attribute-heavy view models either.  I don't want partial classes.  I haven't seen much benefit to the buddy class approach.  And I do want to reuse some of my UI hints across view models (like a date picker for DateTime types).  Plus, I want to take advantage of the new client and server side validation of my view model before it gets into the action method.  MVC 2 has this built in.&lt;/p&gt;
&lt;p&gt;I guess I'll grin and bear it and work on a new blog post about the Triple Responsibility Principal for View Models (as opposed to &lt;a href="http://en.wikipedia.org/wiki/Single_responsibility_principle"&gt;SRP&lt;/a&gt;). :D&lt;/p&gt;
&lt;h2 id="future"&gt;Future&lt;/h2&gt;
&lt;p&gt;I've already talked about &lt;a href="https://volaresoftware.com/en/technical-posts/evolution-of-a-view-in-aspnet-mvc"&gt;where MVC views are now and where they are going&lt;/a&gt;, and the view engine is definitely getting better. I still think views will continue to be the most in-flux part of the MVC framework.  I know people that are very happy with &lt;a href="http://sparkviewengine.com/"&gt;Spark&lt;/a&gt; as a view engine, and &lt;a href="http://www.hanselman.com/blog/HanselminutesPodcast192TheSparkViewEngineForASPNETMVCWithLouisDeJardin.aspx"&gt;Louis DeJardin, the guy who wrote Spark, is now working for Microsoft&lt;/a&gt; on the ASP.NET team.  I don't have any inside scoop, but I wouldn't be surprised if the web forms view engine got a little.&amp;quot;sparkier&amp;quot;.&lt;/p&gt;
&lt;p&gt;Views may also be the area with the most room for improvement, depending on who you talk to.  When I visit with people about MVC and explain that runat=&amp;quot;server&amp;quot; is gone and you can go ahead and close your Visual Studio toolbox, most get a glazed look.  They don't want to hand code the HTML.  They don't want to see a property sheet that doesn't know anything about their current mouse selection.  They don't want to give up their current productivity.&lt;/p&gt;
&lt;p&gt;I get that, but I think you can be faster without the designers and toolboxes and property sheets.  It takes a while to get used to using the keyboard more than the mouse, but I think it's worth pushing yourself over that learning curve.&lt;/p&gt;
&lt;h2 id="time-to-switch-from-web-forms-to-mvc"&gt;Time to switch from Web Forms to MVC?&lt;/h2&gt;
&lt;p&gt;I push MVC on projects where I have influence on that decision.  In your world, it's your call.  You may have environment constraints, in-flight projects, etc.&lt;/p&gt;
&lt;p&gt;But it also doesn't have to be all or nothing.  You don't have to wait for a &lt;a href="http://en.wikipedia.org/wiki/Greenfield_project"&gt;greenfield project&lt;/a&gt; to fall in your lap.  You &lt;strong&gt;can&lt;/strong&gt; run MVC inside your current Web Forms project.  It's just another set of HttpHandlers living under ASP.NET.  Here is &lt;a href="http://www.hanselman.com/blog/PlugInHybridsASPNETWebFormsAndASPMVCAndASPNETDynamicDataSideBySide.aspx"&gt;some&lt;/a&gt; &lt;a href="http://www.codeproject.com/KB/aspnet/webformmvcharmony.aspx"&gt;guidance&lt;/a&gt; for getting your current project set up to do this.&lt;/p&gt;
&lt;p&gt;I encourage you to give it a try and see what you think.  It will take a while to get used to the paradigm.  It's not hard - just different.  But I think once you're used to it, you'll like the separation of concerns, the easier testing, and the more natural flow for web development.&lt;/p&gt;
&lt;p&gt;By natural flow, I mean embracing the world of GET and POST.  I mean when you need to expose &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.mvc.jsonresult.aspx"&gt;JSON&lt;/a&gt;, an &lt;a href="http://www.wduffy.co.uk/blog/rssresult-aspnet-mvc-rss-actionresult/"&gt;RSS&lt;/a&gt; feed, or something else (XML, PDF, file, etc.), &lt;a href="http://msdn.microsoft.com/en-us/library/dd410269.aspx"&gt;Controller Actions&lt;/a&gt; are ready to go.  Stop writing custom HttpHandlers or fighting &lt;a href="http://msdn.microsoft.com/en-us/library/ms731734.aspx"&gt;WCF configuration&lt;/a&gt; for this stuff.  It should be simpler, and it is with Controller Actions and the right &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.mvc.actionresult.aspx"&gt;ActionResult&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Make it a goal to get some real-world MVC experience in 2010.  Think of the kids on the MVC team and their beloved rec center.  Don't let their dream die.  They've come too far.  And remember the tag line from Breakin' 2 - &amp;quot;If you can't beat the system&lt;em&gt;break it!&lt;/em&gt;&amp;quot;.&lt;/p&gt;
</description>
      <pubDate>Mon, 18 Jan 2010 01:41:07 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/setting-default-values-for-kendo-ui-and-datatables-controls</guid>
      <link>https://volaresoftware.com/en/technical-posts/setting-default-values-for-kendo-ui-and-datatables-controls</link>
      <title>Setting default values for Kendo UI and DataTables controls</title>
      <description>&lt;p&gt;Most JavaScript controls take a JSON object for their settings.  Here's how you initialize a &lt;a href="http://demos.kendoui.com/web/grid/index.html"&gt;Kendo UI grid&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;$(&amp;quot;#myGrid&amp;quot;).kendoGrid({
    pageable: true,
    sortable: { mode: &amp;quot;multiple&amp;quot;, allowUnsort: true },
    filterable: true,
    dataSource: {
        data: myData,
        pageSize: 10
    }
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And here's how you initialize a &lt;a href="http://www.datatables.net/"&gt;DataTables&lt;/a&gt; grid:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;$(&amp;quot;#myGrid&amp;quot;).dataTable({
    &amp;quot;bSort&amp;quot;: true,
    &amp;quot;bAutoWidth&amp;quot;: false,
    &amp;quot;bProcessing&amp;quot;: true,
    &amp;quot;bJQueryUI&amp;quot;: true,
    &amp;quot;bPaginate&amp;quot;: true,
    &amp;quot;bServerSide&amp;quot;: true,
    &amp;quot;bSortCellsTop&amp;quot;: true,
    &amp;quot;sPaginationType&amp;quot;: &amp;quot;full_numbers&amp;quot;,
    &amp;quot;iDisplayLength&amp;quot;: 25,
    &amp;quot;aLengthMenu&amp;quot;: [[5, 10, 25, 100], [5, 10, 25, 100]],
    &amp;quot;aaSorting&amp;quot;: [],
    &amp;quot;sAjaxSource&amp;quot;: &amp;quot;/Api/MyData&amp;quot;,
    &amp;quot;sAjaxDataProp&amp;quot;: &amp;quot;Data&amp;quot;
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Both controls take an object literal with all the settings to style how the control looks, works, etc.&lt;/p&gt;
&lt;p&gt;But look at all those settings!  We have to set all that sorting and paging and filtering every time if we want non-default behavior?  And what if we change our mind later and want to use virtual paging instead of page numbers or another application-wide change?&lt;/p&gt;
&lt;p&gt;If there was only a way to centralize the common settings and reuse them with each call…&lt;/p&gt;
&lt;h2 id="reuse-common-settings"&gt;Reuse common settings&lt;/h2&gt;
&lt;p&gt;Here's a snippet of JavaScript to store common settings for a Kendo UI grid:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;var kendoGridDefaults = {
    filterable: {
        pageable: true,
        sortable: { mode: &amp;quot;multiple&amp;quot;, allowUnsort: true },
        filterable: true
    },
    nonFilterable: {
        pageable: true,
        sortable: { mode: &amp;quot;multiple&amp;quot;, allowUnsort: true },
        filterable: false
    },
    extend: function (defaults, settings) {
        return $.extend(true, {}, this[defaults], settings);
    }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And here are some common settings for a DataTables grid:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;var dataTableDefaults = {
    serverSide: {
        &amp;quot;bSort&amp;quot;: true,
        &amp;quot;bAutoWidth&amp;quot;: false,
        &amp;quot;bProcessing&amp;quot;: true,
        &amp;quot;bJQueryUI&amp;quot;: true,
        &amp;quot;bPaginate&amp;quot;: true,
        &amp;quot;bServerSide&amp;quot;: true,
        &amp;quot;bSortCellsTop&amp;quot;: true,
        &amp;quot;sPaginationType&amp;quot;: &amp;quot;full_numbers&amp;quot;,
        &amp;quot;iDisplayLength&amp;quot;: 25,
        &amp;quot;aLengthMenu&amp;quot;: [[5, 10, 25, 100], [5, 10, 25, 100]],
        &amp;quot;aaSorting&amp;quot;: []
    },
    extend: function(defaults, settings) {
        return $.extend(true, {}, this[defaults], settings);
    }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In both cases, you build up an object literal with with the common settings you want to reuse, then create an &amp;quot;extend&amp;quot; function (or another name, if you like) using the &lt;a href="http://api.jquery.com/jQuery.extend/"&gt;jQuery $.extend function&lt;/a&gt;, which merges your default settings with any new settings you pass in.&lt;/p&gt;
&lt;h2 id="more-than-one-set-of-common-settings"&gt;More than one set of common settings&lt;/h2&gt;
&lt;p&gt;You will likely have more than one set of reusable settings (server-side grid and client side grid, filterable and non-filterable grids, etc.).  Just define new objects in your settings object.  Above, I've got &amp;quot;filterable&amp;quot;, &amp;quot;nonFilterable&amp;quot;, and &amp;quot;serverSide&amp;quot; as property sets.&lt;/p&gt;
&lt;h2 id="usage"&gt;Usage&lt;/h2&gt;
&lt;p&gt;To take advantage of the default settings, call your control code and pass in the common settings object, then call the extend function with your overrides and/or additional settings:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;$(&amp;quot;#myGrid&amp;quot;).kendoGrid(kendoGridDefaults.extend(&amp;quot;filterable&amp;quot;, {
    dataSource: {
        data: myData,
        pageSize: 10
    }
}));
&lt;p&gt;$(&amp;quot;#myGrid&amp;quot;).dataTable(dataTableDefaults.extend(&amp;quot;serverSide&amp;quot;, {
&amp;quot;sAjaxSource&amp;quot;: &amp;quot;/api/myData&amp;quot;,
&amp;quot;sAjaxDataProp&amp;quot;: &amp;quot;Data&amp;quot;
}));
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;This technique isn't limited to grids, or to Kendo UI or DataTables.  It can be used with any controls that set their properties with a JavaScript object literal.&lt;/p&gt;
</description>
      <pubDate>Mon, 01 Apr 2013 05:57:00 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/sessionless-mvc-3</guid>
      <link>https://volaresoftware.com/en/technical-posts/sessionless-mvc-3</link>
      <title>Sessionless MVC 3</title>
      <description>&lt;p&gt;If you've done much ASP.NET development, you know you shouldn't use &lt;a href="http://msdn.microsoft.com/en-us/library/ms178581.aspx"&gt;session&lt;/a&gt; for high performance web sites that require web farms and load balancers.  You can centralize session to be on one web server or move it to the database, but what if you want to avoid it altogether?&lt;/p&gt;
&lt;p&gt;MVC 3 introduces a new controller attribute called &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.mvc.sessionstateattribute%28v=VS.98%29.aspx"&gt;SessionStateAttribute&lt;/a&gt;.  You can decorate your controller with this attribute to disable session, make it read-only, or turn it on for full read-write access.  Note that &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.mvc.tempdatadictionary%28v=VS.90%29.aspx"&gt;TempData&lt;/a&gt;, which uses session to store values between requests, is also disabled if session is disabled.  That makes sense, but since it's called &lt;code&gt;TempData[]&lt;/code&gt; instead of &lt;code&gt;Session[]&lt;/code&gt;, it's not obvious.&lt;/p&gt;
&lt;p&gt;Here's how you can use this on a controller.  Note this attribute is at the controller level, not the action level.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;using System.Web.Mvc;
using System.Web.SessionState;
&lt;p&gt;namespace MvcApplication1.Controllers
{
[SessionState(SessionStateBehavior.Disabled)]
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = &amp;quot;Welcome to ASP.NET MVC!&amp;quot;;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;        return View();
    }

    public ActionResult About()
    {
        return View();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;strike&gt;And here's how you can set it as a &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.mvc.globalfiltercollection%28v=vs.98%29.aspx"&gt;Global Filter&lt;/a&gt;&lt;strike&gt; to turn it off for all controllers. The attribute is being set in the &lt;code&gt;RegisterGloablFilters&lt;/code&gt; method in the &lt;code&gt;Global.asax&lt;/code&gt; and is called in &lt;code&gt;Application_Start&lt;/code&gt;.&lt;/strike&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UPDATE:&lt;/strong&gt; This doesn't work as a global action filter.  However, you can turn off session for your whole application with code in your &lt;code&gt;web.config&lt;/code&gt; like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-xml"&gt;&amp;lt;system.web&amp;gt;
    ...
    &amp;lt;sessionState mode=&amp;quot;Off&amp;quot; /&amp;gt;
    ...
&amp;lt;/system.web&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
</description>
      <pubDate>Fri, 21 Jan 2011 01:40:25 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/handling-exceptions-in-asp-net-mvc</guid>
      <link>https://volaresoftware.com/en/technical-posts/handling-exceptions-in-asp-net-mvc</link>
      <title>Handling Exceptions in ASP.NET MVC</title>
      <description>&lt;p&gt;Here is a quick run down of the various approaches for handling exceptions.  I use a combination of these that I'll show at the end.&lt;/p&gt;
&lt;h2 id="try-catch-everywhere"&gt;Try-Catch everywhere&lt;/h2&gt;
&lt;p&gt;You've seen this code before, right?&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public void DoSomething()
{
    try
    {
        var x = 1;
    } 
    catch (Exception ex) 
    {
        ShowExceptionToUser(ex.Message);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The approach of putting try-catch block around every ounce of code seems like a good idea intuitively.  Sure, you're showing the user an ugly error message, but it's better than crashing the server.&lt;/p&gt;
&lt;p&gt;But what is the user supposed to do with the information you show them?  How are they supposed to fix &lt;em&gt;your&lt;/em&gt; null reference exception?&lt;/p&gt;
&lt;p&gt;The other knock on this approach is there is so much &lt;a href="http://msdn.microsoft.com/en-us/magazine/dvdarchive/dd419655.aspx"&gt;ceremony code&lt;/a&gt;!&lt;/p&gt;
&lt;h2 id="generic-error-page"&gt;Generic error page&lt;/h2&gt;
&lt;p&gt;This approach goes the other way with a generic error page displayed to the user for any unhandled error.  It's easy to implement in the &lt;code&gt;Web.config&lt;/code&gt; file, and the user never sees a null reference exception or stack trace.&lt;/p&gt;
&lt;p&gt;Here's what I'm using:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-xml"&gt;&amp;lt;customErrors mode=&amp;quot;RemoteOnly&amp;quot; defaultRedirect=&amp;quot;~/Error&amp;quot;&amp;gt;
  &amp;lt;error statusCode=&amp;quot;403&amp;quot; redirect=&amp;quot;~/Error&amp;quot; /&amp;gt;
  &amp;lt;error statusCode=&amp;quot;404&amp;quot; redirect=&amp;quot;~/Error&amp;quot; /&amp;gt;
&amp;lt;/customErrors&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are two problems with the generic error page approach.  First, the user has &lt;em&gt;no&lt;/em&gt; information about what happened.  Maybe it's something they could have resolved?  Maybe they should try again later?  Just saying &amp;quot;Pardon our mess&amp;quot; doesn't give them any details.&lt;/p&gt;
&lt;p&gt;Second, it doesn't give &lt;em&gt;you&lt;/em&gt; any details either.  The next time you talk to the user, they will tell you they got an error in your app.  &amp;quot;Oh, what happened?&amp;quot; you'll ask.&lt;/p&gt;
&lt;p&gt;&amp;quot;Uh, it was on that screen with the customer info.  I forgot what I was doing, but it just showed the error screen, so I rebooted and went home for the day.&amp;quot;  Not much to go on.  Something about the customer screen?  This will be a fun one to try to reproduce!&lt;/p&gt;
&lt;h2 id="just-log-it"&gt;Just log it&lt;/h2&gt;
&lt;p&gt;The last approach is to log all errors.  You collect as much detail as you need.  The date and time the exception was thrown, which user/IP address, which server they were on, the stack trace, etc.&lt;/p&gt;
&lt;p&gt;Error logging can be extensive and can be stored in rolling text files or database tables.  I prefer using the database so I don't need to grant write permissions to the ASP.NET process running that web app.&lt;/p&gt;
&lt;p&gt;Here's an &lt;code&gt;Application_Error&lt;/code&gt; event from a couple projects back:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;protected void Application_Error(object sender, EventArgs e) 
{
    var ctx = HttpContext.Current;
    var ex = ctx.Server.GetLastError();
    if (ex != null) 
    {
        _logService.LogExceptionToDatabase(ex);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I've done lots of applications like this, where the &lt;code&gt;Application_Error&lt;/code&gt; event in &lt;code&gt;Global.asax&lt;/code&gt; calls into a logger like &lt;a href="http://logging.apache.org/log4net/index.html"&gt;log4net&lt;/a&gt; or &lt;a href="http://www.codeplex.com/entlib"&gt;Enterprise Library&lt;/a&gt; to store exception details.  It works great.  You get the details you need to fix the bug.&lt;/p&gt;
&lt;p&gt;But what about the user?  What are the users looking at when this exception is thrown?&lt;/p&gt;
&lt;h2 id="combo-platter"&gt;#3 Combo Platter&lt;/h2&gt;
&lt;p&gt;Today, I'm using bits and pieces of all of these.&lt;/p&gt;
&lt;p&gt;I show the user a generic error page for all &lt;strong&gt;unhandled&lt;/strong&gt; exceptions.  It may not have much info, but something weird just happened in the app and I wasn't expecting it.  I need more information about what happened so I can decide what needs to be done.&lt;/p&gt;
&lt;p&gt;That's why I'm also using &lt;a href="http://code.google.com/p/elmah/"&gt;ELMAH&lt;/a&gt; to log all &lt;strong&gt;unhandled&lt;/strong&gt; exceptions.  The exception details get stored in my database and I even get a fancy exception viewer since ELMAH works as an &lt;code&gt;HttpHandler&lt;/code&gt;.  My favorite ELMAH feature is you can usually see the yellow screen you would have seen if running locally on your box.&lt;/p&gt;
&lt;p&gt;Finally, sometimes there are &lt;strong&gt;handled&lt;/strong&gt; exceptions.  This is where an exception occurred before in the code (database is down, file not found, etc.), it might occur again, and I've got some thoughts about what to do next time it happens.&lt;/p&gt;
&lt;p&gt;In my view, the only place you need try-catch blocks is when you are worried that an exception might happen and you want to give the user some information, give the user instructions, or silently fix the problem yourself.  If I can't do one of these, I just show the &amp;quot;Oops&amp;quot; page try to come up with a plan later.&lt;/p&gt;
&lt;p&gt;For instance, if the database is down, I'd tell the user to try again later, but I couldn't save their record right now.  If the user is trying to upload a file and it's not there, they can try to correct the file upload input box and resubmit.&lt;/p&gt;
&lt;h2 id="how-to-wire-this-up-in-asp.net-mvc"&gt;How to wire this up in ASP.NET MVC&lt;/h2&gt;
&lt;h3 id="set-up-elmah"&gt;Set up ELMAH&lt;/h3&gt;
&lt;p&gt;First, &lt;a href="http://code.google.com/p/elmah/downloads/list"&gt;download ELMAH binaries&lt;/a&gt;, add a reference to the ELMAH assembly in your web project, and follow the &lt;a href="http://code.google.com/p/elmah/wiki/MVC"&gt;instructions to get your Web.config set up correctly&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Now test out ELMAH.  You should be able to browse to elmah.axd and see the list of exceptions.  Try throwing one in your code somewhere and see if ELMAH logs it.&lt;/p&gt;
&lt;p&gt;You can make the elmah.axd page secure, log to a database, etc.&lt;/p&gt;
&lt;h3 id="set-up-the-generic-error-page"&gt;Set up the Generic Error Page&lt;/h3&gt;
&lt;p&gt;Once ELMAH is logging, wire up your Web.config to show the generic error page:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-xml"&gt;&amp;lt;customErrors mode=&amp;quot;RemoteOnly&amp;quot; defaultRedirect=&amp;quot;~/Error&amp;quot;&amp;gt;
  &amp;lt;error statusCode=&amp;quot;403&amp;quot; redirect=&amp;quot;~/Error&amp;quot; /&amp;gt;
  &amp;lt;error statusCode=&amp;quot;404&amp;quot; redirect=&amp;quot;~/Error&amp;quot; /&amp;gt;
&amp;lt;/customErrors&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I'm using an Error controller with a single Index action so I can send the user to the root and to the Error route to show the error page.  Here's the controller:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public class ErrorController : Controller
{
    public ActionResult Index() 
    {
        return View(&amp;quot;Error&amp;quot;);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It's calling a view also called &amp;quot;Error&amp;quot; that is in &lt;code&gt;~\Views\Shared\Error.aspx&lt;/code&gt;.  Make your version of that page.  Remember, this is the page for unhandled exceptions.&lt;/p&gt;
&lt;p&gt;Next, you need to register this route.  I've moved my route registration out of my &lt;code&gt;Global.asax&lt;/code&gt;, but if you have a default ASP.NET MVC install, look for your routing registrations in &lt;code&gt;Application\_Start&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;routes.MapRoute(&amp;quot;UnhandledExceptions&amp;quot;, &amp;quot;Error&amp;quot;, new { controller = &amp;quot;Error&amp;quot;, action = &amp;quot;Index&amp;quot; });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is just setting up some defaults in the route to simplify redirects to the generic error page.  At this point, you should be able to browse to any controller with a thrown exception in the action and see your generic error page displayed.&lt;/p&gt;
&lt;h3 id="set-up-the-elmahhandleerror-attribute"&gt;Set up the ElmahHandleError attribute&lt;/h3&gt;
&lt;p&gt;There's one step left!  You've now got two ways of dealing with unhandled exceptions.  We need to consolidate these so the generic page is show AND the ELMAH logging is called.&lt;/p&gt;
&lt;p&gt;You know how you have to add the &lt;code&gt;HandleError&lt;/code&gt; attribute to your controller classes to get the generic error page to appear?  This attribute doesn't call ELMAH.  This is by design, since the &lt;code&gt;HandleError&lt;/code&gt; attribute is, well, &lt;em&gt;handling&lt;/em&gt; the error.  ELMAH is for &lt;strong&gt;unhandled&lt;/strong&gt; errors and doesn't log otherwise.&lt;/p&gt;
&lt;p&gt;But you can have it both ways and use ELMAH as your handled exception logging tool as well.  Follow these steps to &lt;a href="http://stackoverflow.com/questions/766610/how-to-get-elmah-to-work-with-asp-net-mvc-handleerror-attribute"&gt;create an ElmahHandleError attribute&lt;/a&gt; and replace the &lt;code&gt;HandleError&lt;/code&gt; attribute on your controllers with this new attribute.&lt;/p&gt;
&lt;p&gt;That's it!  You should be all set with an exception handling strategy.&lt;/p&gt;
</description>
      <pubDate>Sun, 23 Aug 2009 09:24:27 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/combining-javascript-bundling-minification-cache-busting-and-easier-debugging</guid>
      <link>https://volaresoftware.com/en/technical-posts/combining-javascript-bundling-minification-cache-busting-and-easier-debugging</link>
      <title>Combining JavaScript bundling, minification, cache busting, and easier debugging</title>
      <description>&lt;p&gt;ASP.NET MVC has had server-side bundling and minification for a couple versions now.  You can use this to reduce HTTP requests from the client browser to the web server.  This optimization is a must when you get lots of small JavaScript files, which is what most large web applications have these days.&lt;/p&gt;
&lt;p&gt;Here's the default BundleConfig.cs in an MVC4 default project:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;using System.Web;
using System.Web.Optimization;
&lt;p version=""&gt;namespace BundlingSample
{
public class BundleConfig
{
// For more information on Bundling, visit &lt;a href="http://go.microsoft.com/fwlink/?LinkId=254725"&gt;http://go.microsoft.com/fwlink/?LinkId=254725&lt;/a&gt;
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBundle(&amp;quot;&lt;sub&gt;/bundles/jquery&amp;quot;).Include(
&amp;quot;&lt;/sub&gt;/Scripts/jquery-.js&amp;quot;));&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;        bundles.Add(new ScriptBundle(&amp;amp;quot;~/bundles/jqueryui&amp;amp;quot;).Include(
                    &amp;amp;quot;~/Scripts/jquery-ui-{version}.js&amp;amp;quot;));

        bundles.Add(new ScriptBundle(&amp;amp;quot;~/bundles/jqueryval&amp;amp;quot;).Include(
                    &amp;amp;quot;~/Scripts/jquery.unobtrusive*&amp;amp;quot;,
                    &amp;amp;quot;~/Scripts/jquery.validate*&amp;amp;quot;));

        // Use the development version of Modernizr to develop with and learn from. Then, when you're
        // ready for production, use the build tool at http://modernizr.com to pick only the tests you need.
        bundles.Add(new ScriptBundle(&amp;amp;quot;~/bundles/modernizr&amp;amp;quot;).Include(
                    &amp;amp;quot;~/Scripts/modernizr-*&amp;amp;quot;));

        bundles.Add(new StyleBundle(&amp;amp;quot;~/Content/css&amp;amp;quot;).Include(&amp;amp;quot;~/Content/site.css&amp;amp;quot;));

        bundles.Add(new StyleBundle(&amp;amp;quot;~/Content/themes/base/css&amp;amp;quot;).Include(
                    &amp;amp;quot;~/Content/themes/base/jquery.ui.core.css&amp;amp;quot;,
                    &amp;amp;quot;~/Content/themes/base/jquery.ui.resizable.css&amp;amp;quot;,
                    &amp;amp;quot;~/Content/themes/base/jquery.ui.selectable.css&amp;amp;quot;,
                    &amp;amp;quot;~/Content/themes/base/jquery.ui.accordion.css&amp;amp;quot;,
                    &amp;amp;quot;~/Content/themes/base/jquery.ui.autocomplete.css&amp;amp;quot;,
                    &amp;amp;quot;~/Content/themes/base/jquery.ui.button.css&amp;amp;quot;,
                    &amp;amp;quot;~/Content/themes/base/jquery.ui.dialog.css&amp;amp;quot;,
                    &amp;amp;quot;~/Content/themes/base/jquery.ui.slider.css&amp;amp;quot;,
                    &amp;amp;quot;~/Content/themes/base/jquery.ui.tabs.css&amp;amp;quot;,
                    &amp;amp;quot;~/Content/themes/base/jquery.ui.datepicker.css&amp;amp;quot;,
                    &amp;amp;quot;~/Content/themes/base/jquery.ui.progressbar.css&amp;amp;quot;,
                    &amp;amp;quot;~/Content/themes/base/jquery.ui.theme.css&amp;amp;quot;));
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;This approach works well for 3rd party libraries (jQuery, jQuery validation, knockout, etc.), and it has a cache-busting hash in the URL that keeps you from caching an old version of the bundled and minified script in your browser.&lt;/p&gt;
&lt;p&gt;Here you can see jquery and modernizr have a query string after the file name with the unique key:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2013/3/image_48.png" alt="image_48.png" /&gt;&lt;/p&gt;
&lt;p&gt;So we've got bundling of scripts, minification, and cache-busting.  What's not to love?&lt;/p&gt;
&lt;h2 id="where-do-i-put-my-application-scripts"&gt;Where do I put my application scripts?&lt;/h2&gt;
&lt;p&gt;The default MVC project gives you a \Scripts folder.  You could put your application scripts there.  NuGet would like you to leave 3rd party scripts there, and it's the convention, but I prefer to move scripts I didn't write for the current app into a \Scripts\lib folder, and scripts for the app go in a \Scripts\app folder.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2013/3/image_49.png" alt="image_49.png" /&gt;&lt;/p&gt;
&lt;p&gt;You'll have some moving around to do when you update a JavaScript via NuGet to get it in your preferred folder, but it's a little easier to find the stuff you'll really be working on for your app.  You'll also need to update your BundleConfig.cs to point to the new \Scripts\lib folder.&lt;/p&gt;
&lt;p&gt;So how to we bundle these app scripts?  You could bundle them all in one file.  Everything in that folder gets put in a &amp;quot;~/bundles/myApp&amp;quot; bundle.  The problem is, you'll likely end up with lots of sequencing problems in the scripts and see &amp;quot;undefined&amp;quot; errors.  This could work if you only have a small amount of JavaScript in your app, but it's not recommended.&lt;/p&gt;
&lt;p&gt;You could also create a Razor section in the _Layout.cshtml and call it &amp;quot;scripts&amp;quot;, then each view can list the scripts it needs to work in that Razor section.  The default MVC4 _Layout.cshtml file already has this Razor section set up for you.  This approach works, but now we're not bundling or minifying the JavaScript, and we don't have any cache busting going on with our app scripts.&lt;/p&gt;
&lt;h2 id="so-i-have-to-debug-minified-files-yuck"&gt;So I have to debug minified files? Yuck.&lt;/h2&gt;
&lt;p&gt;The other drawback of using the built-in ASP.NET optimizations for bundling and minification is debugging minified files.  You've probably dealt with this when your JavaScript throws an exception and you're in the middle of a jQuery file.  JQuery almost certainly doesn't have a bug, but you sent it some values it wasn't expecting.  Have fun sorting that out.&lt;/p&gt;
&lt;p&gt;![[image_thumb_11.png](https://cdn.volaresoftware.com/images/posts/2013/3/image_thumb_11.png)&lt;/p&gt;
&lt;p&gt;IE10 and Chrome have JavaScript pretty print tools that can make the minified script a little easier to read than one long line, but the variable names will all still be a, b, c, and whatever the minifier hadn't already used.&lt;/p&gt;
&lt;p&gt;Using map files is a better way to go, and in Chrome, you turn this on in dev tools and click the gear at the bottom right, then check &amp;quot;Enable source maps&amp;quot;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2013/3/image_50.png" alt="image_50.png" /&gt;&lt;/p&gt;
&lt;p&gt;Now each minified file can have a map file that points to the original, unminified source code.  The built-in ASP.NET optimizations don't work with map files yet.&lt;/p&gt;
&lt;h2 id="web-essentials-bundling-to-the-rescue"&gt;Web Essentials bundling to the rescue&lt;/h2&gt;
&lt;p&gt;If you are a Visual Studio web developer and you don't have &lt;a href="http://visualstudiogallery.msdn.microsoft.com/07d54d12-7133-4e15-becb-6f451ea3bea6"&gt;Web Essentials&lt;/a&gt;, go get it now.  You'll love it.  It's a Visual Studio extension created my &lt;a href="https://twitter.com/mkristensen"&gt;Mads Kristensen&lt;/a&gt;, who works for Microsoft for the Web Platform and Tools group.&lt;/p&gt;
&lt;p&gt;One of the features is bundling and minification.  You select the files you want to bundle, right click, then choose Web Essentials &amp;gt; Create JavaScript bundle file.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2013/3/image_51.png" alt="image_51.png" /&gt;&lt;/p&gt;
&lt;p&gt;Name your bundle, and several files will be created.  The first is the *.bundle file:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-xml"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;
    &amp;lt;bundle minify=&amp;quot;true&amp;quot; runOnBuild=&amp;quot;true&amp;quot;&amp;gt;
    &amp;lt;!--The order of the &amp;lt;file&amp;gt; elements determines the order of them when bundled.--&amp;gt;
    &amp;lt;file&amp;gt;/Scripts/app/script1.js&amp;lt;/file&amp;gt;
    &amp;lt;file&amp;gt;/Scripts/app/script2.js&amp;lt;/file&amp;gt;
&amp;lt;/bundle&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This file lists each script in the bundle and has flags for minify (default is &amp;quot;true&amp;quot;) and runOnBuild (default is &amp;quot;true&amp;quot;).  You may need to rearrange the order of the bundle files if there are functions defined in one file and called in another.&lt;/p&gt;
&lt;p&gt;Any change you make to script1.js or script2.js, the *.bundle file, or building your app, will regenerate the files underneath the *.bundle file:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2013/3/image_52.png" alt="image_52.png" /&gt;&lt;/p&gt;
&lt;p&gt;These three files are 1) the combined bundle without minification, 2) the bundle with minification, and 3) the map file for debugging the original script.  The first is a giant concatenation of the two files and isn't that interesting.&lt;/p&gt;
&lt;p&gt;The minified file looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;function add(n,t){return n+t}function subtract(n,t){return n-t}function showMessage(n){alert(n)}
//@ sourceMappingURL=myAppBundle.min.js.map
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the map file looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-json"&gt;{
    &amp;quot;version&amp;quot;:3,
    &amp;quot;file&amp;quot;:&amp;quot;myAppBundle.min.js&amp;quot;,
    &amp;quot;lineCount&amp;quot;:1,
    &amp;quot;mappings&amp;quot;:&amp;quot;AAAAA,SAASA,GAAG,CAACC,CAAC,CAAEC,CAAJ,CAAO,CACf,OAAOD,CAAE,CAAEC,CADI,CAInBC,SAASA,QAAQ,CAACF,CAAC,CAAEC,CAAJ,CAAO,CACpB,OAAOD,CAAE,CAAEC,CADS,CCJxBE,SAASA,WAAW,CAACC,CAAD,CAAM,CACtBC,KAAK,CAACD,CAAD,CADiB&amp;quot;,
    &amp;quot;sources&amp;quot;:[&amp;quot;/Scripts/app/script1.js&amp;quot;,&amp;quot;/Scripts/app/script2.js&amp;quot;],
    &amp;quot;names&amp;quot;:[&amp;quot;add&amp;quot;,&amp;quot;x&amp;quot;,&amp;quot;y&amp;quot;,&amp;quot;subtract&amp;quot;,&amp;quot;showMessage&amp;quot;,&amp;quot;msg&amp;quot;,&amp;quot;alert&amp;quot;]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So the minified file gives the browser instructions on how to get to the map file, which gives the browser instructions on how to render in unminified, made-for-humans format.&lt;/p&gt;
&lt;h2 id="using-the-bundles"&gt;Using the bundles&lt;/h2&gt;
&lt;p&gt;I create a bundle of app scripts for each view (usually I name it after the view, like register.bundle, login.bundle, etc.) and use the Razor &amp;quot;scripts&amp;quot; section in the _Layout.cshtml file to place those scripts at the bottom of the html, just before the closing &lt;body&gt; tag.  The script reference points to the minified file.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;@section scripts {
    &amp;lt;script src=&amp;quot;~/Scripts/app/myAppBundle.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In Chrome, the end result is this for the minified file:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2013/3/image_53.png" alt="image_53.png" /&gt;&lt;/p&gt;
&lt;p&gt;And this for the mapped file:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2013/3/image_54.png" alt="image_54.png" /&gt;&lt;/p&gt;
&lt;p&gt;This human-readable script can have breakpoints, etc.  It looks like the original file, but the browser has not created new HTTP requests to pull down the originals.  It's map file magic.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2013/3/image_55.png" alt="image_55.png" /&gt;&lt;/p&gt;
&lt;p&gt;Setting up view-specific bundles seems lighter weight to me than always editing the BundleConfig.cs file, plus you get the mapping files.  Now we just need to solve for the cache busting we lost with this approach.&lt;/p&gt;
&lt;h2 id="cache-busting"&gt;Cache busting&lt;/h2&gt;
&lt;p&gt;Ever send your product owner to the CI web server to check out a new feature, only to have them tell you they got JavaScript errors on that page?  Did you tell them to type CTRL-F5 to force a refresh of the page?  If so, you have a caching problem where the browser is caching the file even though it has changed.&lt;/p&gt;
&lt;p&gt;Mads has &lt;a href="https://madskristensen.net/blog/cache-busting-in-aspnet/"&gt;a blog post on cache busting&lt;/a&gt; that works well.  It's based on getting the last changed date of the file and appending that date in ticks to the path of the request for the script or css.  His solution involves having URL rewriting working on IIS.&lt;/p&gt;
&lt;p&gt;In my case, I didn't want to mess with URL rewriting, so I went with the somewhat less optimal but simpler solution of using a query string instead.  Here's my Razor helper:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;using System.IO;
using System.Web;
using System.Web.Caching;
using System.Web.Hosting;
&lt;p&gt;namespace BundlingSample.Extensions
{
public static class StaticFile
{
public static string Version(string rootRelativePath)
{
if (HttpRuntime.Cache[rootRelativePath] == null)
{
var absolutePath = HostingEnvironment.MapPath(rootRelativePath);
var lastChangedDateTime = File.GetLastWriteTime(absolutePath);&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;            if (rootRelativePath.StartsWith(&amp;amp;quot;~&amp;amp;quot;))
            {
                rootRelativePath = rootRelativePath.Substring(1);
            }

            var versionedUrl = rootRelativePath + &amp;amp;quot;?v=&amp;amp;quot; + lastChangedDateTime.Ticks;

            HttpRuntime.Cache.Insert(rootRelativePath, versionedUrl, new CacheDependency(absolutePath));
        }

        return HttpRuntime.Cache[rootRelativePath] as string;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;and how it's used in the Razor view:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;@section scripts {
    &amp;lt;script src=&amp;quot;@StaticFile.Version(&amp;quot;~/Scripts/app/myAppBundle.min.js&amp;quot;)&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and the resulting file name in the browser:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2013/3/image_56.png" alt="image_56.png" /&gt;&lt;/p&gt;
&lt;p&gt;The query string pattern matches the built-in ASP.NET optimization pattern.  I say this is sub-optimal because some page speed tools will fuss at you for using query strings.  Google PageSpeed says, &amp;quot;Enabling public caching in the HTTP headers for static resources allows the browser to download resources from a nearby proxy server rather than from a remote origin server.&amp;quot;  I'm not too worried about that, but you'll want to use Mads' URL rewrite approach if you want a better PageSpeed score.&lt;/p&gt;
&lt;p&gt;So there you have it.  Bundling, minification, debugging, and cache busting when you need it!&lt;/p&gt;
</description>
      <pubDate>Mon, 18 Mar 2013 01:12:00 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/prefiltering-a-kendo-ui-grid-with-an-odata-data-source</guid>
      <link>https://volaresoftware.com/en/technical-posts/prefiltering-a-kendo-ui-grid-with-an-odata-data-source</link>
      <title>Prefiltering a Kendo UI grid with an OData data source</title>
      <description>&lt;p&gt;If you're using &lt;a href="http://demos.kendoui.com/web/grid/index.html"&gt;Kendo UI's grid&lt;/a&gt;, you know you can &lt;a href="https://volaresoftware.com/en/technical-posts/using-kendo-ui-grid-with-web-api-and-odata"&gt;plug it into a Web API OData data source&lt;/a&gt;.  The nice thing about using an OData end point is you don't have to parse all the possible filter values in your Web API code.  You'd have to plan for column names, values, different operators, and'ing and or'ing of values, etc.  Instead, with OData, just keep the data IQueryable, mark the method with a [Queryable] attribute, and you're all set.&lt;/p&gt;
&lt;p&gt;But what if you want some client-side filtering to start off with?  You could hack up the OData URL sent back to Web API, or you could set a filter on the grid's data source (extending the &lt;a href="https://volaresoftware.com/en/technical-posts/using-kendo-ui-grid-with-web-api-and-odata"&gt;example here&lt;/a&gt;).&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;$(function () {
    var dataSource = new kendo.data.DataSource({
        type: &amp;quot;odata&amp;quot;,
        transport: {
            read: {
                url: &amp;quot;/api/Cats&amp;quot;,
                dataType: &amp;quot;json&amp;quot;
            },
        },
        schema: {
            data: function (data) {
                return data[&amp;quot;value&amp;quot;];
            },
            total: function (data) {
                return data[&amp;quot;odata.count&amp;quot;];
            },
            model: {
                fields: {
                    Id: { type: &amp;quot;number&amp;quot; },
                    Name: { type: &amp;quot;string&amp;quot; },
                    Color: { type: &amp;quot;string&amp;quot; }
                }
            }
        },
        pageSize: 10,
        serverPaging: true,
        serverFiltering: true,
        serverSorting: true,
        filter: { field: &amp;quot;Color&amp;quot;, operator: &amp;quot;eq&amp;quot;, value: &amp;quot;black&amp;quot; }
    });
&lt;pre&gt;&lt;code&gt;$(&amp;amp;quot;#grid&amp;amp;quot;).kendoGrid({
    dataSource: dataSource,
    filterable: true,
    sortable: true,
    pageable: true,
    columns: [
        { field: &amp;amp;quot;Id&amp;amp;quot; },
        { field: &amp;amp;quot;Name&amp;amp;quot; },
        { field: &amp;amp;quot;Color&amp;amp;quot; }
    ]
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;});
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;See the &amp;quot;filter&amp;quot; setting on the data source?  That will tell OData to search for &lt;code&gt;/api/Cats/?&amp;lt;other OData stuff&amp;gt;&amp;amp;amp;$filter=Color eq ‘black'&lt;/code&gt; on the URL (you will probably get a &lt;code&gt;+&lt;/code&gt; symbol instead of a space from URL encoding).  This URL stuff will become part of the query's where clause and filter your data.  Since this is just a grid filter, your user can go in and edit it, clear it, etc.&lt;/p&gt;
&lt;p&gt;But what if you have more complex filtering needs?  What if you have multiple values or &amp;quot;or&amp;quot; logic instead of &amp;quot;and&amp;quot; logic?&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;filter: {
    logic: &amp;quot;or&amp;quot;,
    filters: [
        { field: &amp;quot;Name&amp;quot;, operator: &amp;quot;contains&amp;quot;, value: &amp;quot;fluffy&amp;quot; },
        { field: &amp;quot;Color&amp;quot;, operator: &amp;quot;eq&amp;quot;, value: &amp;quot;black&amp;quot; }
    ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will let you &amp;quot;or&amp;quot; your columns, so you are looking for Names containing &amp;quot;fluffy&amp;quot; &lt;strong&gt;or&lt;/strong&gt; Colors equal to &amp;quot;black&amp;quot;.  The URL will look like &lt;code&gt;/api/Cats/?&amp;lt;other OData stuff&amp;gt;&amp;amp;amp;$filter=(substringof(‘fluffy',Name) or Color eq ‘black')&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;What if your filtering needs are more complex than this?  What if you have both &amp;quot;and&amp;quot; and &amp;quot;or&amp;quot; logic you want to pass through to filter your OData?&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;filter: [
    {
        logic: &amp;quot;or&amp;quot;,
        filters: [
            { field: &amp;quot;Name&amp;quot;, operator: &amp;quot;contains&amp;quot;, value: &amp;quot;fluffy&amp;quot; },
            { field: &amp;quot;Color&amp;quot;, operator: &amp;quot;eq&amp;quot;, value: &amp;quot;black&amp;quot; }
        ]
    },
    {
        logic: &amp;quot;and&amp;quot;,
        filters: [
            { field: &amp;quot;Active&amp;quot;, operator: &amp;quot;eq&amp;quot;, value: true }
        ]
    }
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The grid's filter property is smart enough to handle more complex JavaScript objects thrown at it, as long as is matches the filter pattern.  Take advantage of this to prefilter your grid data so those fancy OData queries don't send down values that aren't helpful for your end users.&lt;/p&gt;
</description>
      <pubDate>Wed, 22 May 2013 23:28:00 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/push-to-appharbor-on-every-push-to-github</guid>
      <link>https://volaresoftware.com/en/technical-posts/push-to-appharbor-on-every-push-to-github</link>
      <title>Push to AppHarbor on every push to GitHub</title>
      <description>&lt;p&gt;If you're using &lt;a href="https://github.com/"&gt;GitHub&lt;/a&gt; as your shared, online, git repository and you're using &lt;a href="https://appharbor.com/"&gt;AppHarbor&lt;/a&gt; for continuous integration and deployment, you really have two git repositories – the GitHub one and the AppHarbor one.&lt;/p&gt;
&lt;p&gt;AppHarbor instructions help you set up a remote to this git repository so you can push to it whenever you like, but that means you have two steps on most commits:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-git"&gt;git push origin master
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;to push your code up to your GitHub repo, and:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-git"&gt;git push appharbor master
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;to push your code up to the AppHarbor repo.  Because AppHarbor doesn't support SSH yet (only HTTPS is supported now), you also have to enter your password.  Not a giant hassle, but what if you could get rid of that last little bit of friction?&lt;/p&gt;
&lt;h2 id="github-service-hooks"&gt;GitHub Service Hooks&lt;/h2&gt;
&lt;p&gt;GitHub Service Hooks run after a push to GitHub, and there is one to fire off your AppHarbor build/test/deploy.  It's under your GitHub repo &amp;gt; Admin &amp;gt; Service Hooks.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2011/10/image19.png" alt="image19.png" /&gt;&lt;/p&gt;
&lt;p&gt;Once you're there, the instructions are pretty simple.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Go to your application's main page on AppHarbor and find the &amp;quot;Create build URL&amp;quot;. Example: &lt;a href="https://appharbor.com/application/%7Bapplication_slug%7D/build?authorization=%7Btoken%7D"&gt;https://appharbor.com/application/{application_slug}/build?authorization=&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&amp;quot;token&amp;quot; is the value of the &amp;quot;authorization&amp;quot; parameter.&lt;/li&gt;
&lt;li&gt;&amp;quot;application_slug&amp;quot; is your application's unique identifier.&lt;/li&gt;
&lt;li&gt;If your GitHub repository is private you need to add the &amp;quot;apphb&amp;quot; GitHub user as a collaborator. This enables AppHarbor to download the source code.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here's where you can find the values for steps 1-3 in AppHarbor:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2011/10/image35.png" alt="image35.png" /&gt;&lt;/p&gt;
&lt;p&gt;Step #4 can be skipped if you have a public repo.  If you're using private repos, add the &amp;quot;apphb&amp;quot; GitHub user to a GitHub team with &amp;quot;pull&amp;quot; grants.&lt;/p&gt;
&lt;h2 id="all-done"&gt;All done!&lt;/h2&gt;
&lt;p&gt;Next time you do&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-git"&gt;git push origin master
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;your code will be pushed up to GitHub and AppHarbor will grab the latest code from GitHub (not from the AppHarbor repo anymore), build it, test it, and if the tests pass, deploy it.  All in one step!&lt;/p&gt;
</description>
      <pubDate>Wed, 12 Oct 2011 00:40:07 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/whats-new-in-mvc-2</guid>
      <link>https://volaresoftware.com/en/technical-posts/whats-new-in-mvc-2</link>
      <title>What's New in MVC 2?</title>
      <description>&lt;p&gt;Thanks to all the folks who attended the &lt;a href="http://www.southcolorado.net/"&gt;South Colorado .NET User Group&lt;/a&gt; Visual Studio 2010 launch on May 6th.  We went through a giant buffet of new things in Visual Studio, Entity Framework, SharePoint, Silverlight, and ASP.NET.  &lt;a href="https://github.com/VolareSoftware/Presentations/tree/master/What%27s%20New%20in%20MVC%202%20-%20Colorado%20Springs%20.NET%20Group"&gt;Slides from my talk on the new features in MVC 2 can be downloaded here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Big thanks also to &lt;a href="http://twitter.com/benhnet"&gt;Ben Hoelting&lt;/a&gt; for putting the event together.  I liked the mini code camp format!  It was a lot of info, but it was a great survey of most of the new features.&lt;/p&gt;
</description>
      <pubDate>Wed, 12 May 2010 04:00:00 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/faster-karma-test-runs-that-work-in-vsts-with-chrome-headless-browser</guid>
      <link>https://volaresoftware.com/en/technical-posts/faster-karma-test-runs-that-work-in-vsts-with-chrome-headless-browser</link>
      <title>Faster Karma test runs that work in VSTS with Chrome headless browser</title>
      <description>&lt;p&gt;&lt;a href="https://karma-runner.github.io/1.0/index.html"&gt;Karma&lt;/a&gt; is a well known framework-agnostic test runner. It's the glue between your JavaScript tests and your test results.&lt;/p&gt;
&lt;p&gt;Because Karma doesn't care what test framework, assertion library, or browser you use, configuration can be a bit of a headache. You have to specify everything.&lt;/p&gt;
&lt;p&gt;Most examples I've seen use &lt;a href="http://phantomjs.org/"&gt;PhantomJS&lt;/a&gt; as a headless browser, and it works ok. But on my current project, we have 4,700+ JavaScript tests written with Jasmine. When I run those tests manually through Chrome using the Jasmine stock HTML test runner, the tests run in just over 15 seconds.  When I run those same tests from the command line or the build server using Karma and PhantomJS, the tests run in about 1.5 minutes – much slower.&lt;/p&gt;
&lt;p&gt;I was looking for something faster that would work well both locally and on the build server, and the new-ish Chrome headless browser sounded promising. After getting it set up and working, the Karma tests with Chrome headless as the browser now run in under 10 seconds. Yay!&lt;/p&gt;
&lt;p&gt;Here's a step-by-step to getting it set up with the minimum configuration.&lt;/p&gt;
&lt;h3 id="installation"&gt;Installation&lt;/h3&gt;
&lt;p&gt;To install, first make sure you've got &lt;a href="https://nodejs.org/en/download/"&gt;Node installed&lt;/a&gt; and then run:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;npm install karma --save-dev
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This installs &lt;code&gt;karma&lt;/code&gt; for this project. Then:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;npm install karma-cli -g
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This installs the &lt;code&gt;karma-cli&lt;/code&gt; globally for this computer. Next:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;npm install karma-jasmine karma-chrome-launcher jasmine-core --save-dev
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This installs common plugins we'll need for this project: &lt;code&gt;karma-jasmine&lt;/code&gt;, &lt;code&gt;karma-chrome-launcher&lt;/code&gt; and &lt;code&gt;jasmine-core&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Next, we will install &lt;a href="https://github.com/GoogleChrome/puppeteer"&gt;Puppeteer&lt;/a&gt;, an API for Chrome's headless browser. If you are not running your JavaScript tests on your build server, you can skip this step. I was able to get my local Chrome headless browser running without this, but I needed this installed for my build server, Visual Studio Team Services (VSTS).&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;npm install puppeteer --save-dev
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once &lt;code&gt;puppeteer&lt;/code&gt; is installed for this project, it's time to configure things.&lt;/p&gt;
&lt;h3 id="configuration"&gt;Configuration&lt;/h3&gt;
&lt;p&gt;You need to specify all the settings for Karma because it doesn't know anything about your project.  It's like the opposite of zero-config - it's infinite-config.&lt;/p&gt;
&lt;p&gt;Recognizing this, the Karma team came up with a bunch of simple questions to get most of what you need added to your config file.  From the command line, run:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;karma init karma.conf.js
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Pick &lt;code&gt;jasmine&lt;/code&gt; for the testing framework, &lt;code&gt;no&lt;/code&gt; for RequireJS (unless you need that), &lt;code&gt;Chrome&lt;/code&gt; for the browser (we'll adjust this later), and &lt;code&gt;src/**/*.js&lt;/code&gt; and &lt;code&gt;tests/**/*-tests.js&lt;/code&gt; for the source and test files (unless you prefer a different folder/filename pattern), and &lt;code&gt;yes&lt;/code&gt; that we'll let the watcher keep an eye on file changes.&lt;/p&gt;
&lt;p&gt;This is what mine looked like:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2018/2/karma-conf-js_thumb.png" alt="https://cdn.volaresoftware.com/images/posts/2018/2/karma-conf-js_thumb.png" /&gt;&lt;/p&gt;
&lt;p&gt;Next, open &lt;code&gt;package.json&lt;/code&gt; in the project root and &lt;code&gt;scripts&lt;/code&gt; section if you don't already have one at the top level.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;&amp;quot;scripts&amp;quot;: {
  &amp;quot;test&amp;quot;: &amp;quot;karma start&amp;quot;
},
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This addition let's us run the tests from the command line with &lt;code&gt;npm test&lt;/code&gt; or &lt;code&gt;karma start&lt;/code&gt;. This is very helpful for build servers, like VSTS, which know about Node and npm, but not about Karma. Running &lt;code&gt;npm test&lt;/code&gt; as an npm task on VSTS works nicely.&lt;/p&gt;
&lt;h3 id="write-a-sample-test"&gt;Write a sample test&lt;/h3&gt;
&lt;p&gt;We won't know if it's working until we write a test and see it fail and then see it pass.  Let's do that now.&lt;/p&gt;
&lt;p&gt;Add a new file under &lt;code&gt;/tests&lt;/code&gt; named &lt;code&gt;sample-tests.js&lt;/code&gt;. This file should get picked up by our glob pattern in &lt;code&gt;karma.conf.js&lt;/code&gt;. Add this code to it:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;describe(&amp;quot;Testing Karma with Chrome headless&amp;quot;, () =&amp;gt; {
&lt;pre&gt;&lt;code&gt;it(&amp;amp;quot;Should work if configuration is correct&amp;amp;quot;, () =&amp;amp;gt; {
  expect(false).toBeTruthy();
}); 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;});
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;You would never write this kind of test for a real project, but we just want to know if we've got everything working. This test should fail. Let's run it and see. From the command line, enter:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;karma start
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You should see a failing test like this.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2018/2/failing_test_thumb.png" alt="https://cdn.volaresoftware.com/images/posts/2018/2/failing_test_thumb.png" /&gt;&lt;/p&gt;
&lt;p&gt;You can use CTRL-C to break from the watch if you need to. Change the test so the assert is:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;expect(true).toBeTruthy();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and save. As soon as you save the changes in the test file, the watcher should re-run the tests and you should see this.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2018/2/passing_test_thumb.png" alt="https://cdn.volaresoftware.com/images/posts/2018/2/passing_test_thumb.png" /&gt;&lt;/p&gt;
&lt;p&gt;If you don't have a passing test this point, go back and see if you missed a step or download from the &lt;a href="https://github.com/VolareSoftware/KarmaWithChromeHeadless"&gt;GitHub repository&lt;/a&gt; and try running from that code.&lt;/p&gt;
&lt;h3 id="chrome-headless"&gt;Chrome Headless&lt;/h3&gt;
&lt;p&gt;When the tests run, Karma creates a web server, opens Chrome, and runs the tests using the Chrome browser. You can see it running. But we want the headless Chrome browser for speed and to keep that extra browser out of the way.&lt;/p&gt;
&lt;p&gt;Use CTRL-C to cancel the watch Karma is running so we can kick it off again when we've made our changes. Open &lt;code&gt;karma.conf.js&lt;/code&gt; and find the &lt;code&gt;browsers&lt;/code&gt; section.  Change it to:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;browsers: ['ChromeHeadless'],
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is the token used to specify the headless (not visible) version of Chrome. There are &lt;a href="https://npmjs.org/browse/keyword/karma-launcher"&gt;a lot more browsers you can choose from&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Next, find the &lt;code&gt;singleRun&lt;/code&gt; section and change it to:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;singleRun: true,
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and save. This is needed for your build server, or at least if your build server is VSTS.&lt;/p&gt;
&lt;p&gt;Re-run with &lt;code&gt;karma start&lt;/code&gt;. You should get similar results, with a passing test, but now it says the browser is &lt;code&gt;HeadlessChrome&lt;/code&gt;. Also, the test stops and returns to the command prompt when completed instead of staying in watch mode.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://volaresystems.com/blog/image.axd?picture=chrome_headless.png"&gt;![chrome_headless_thumb.png](https://cdn.volaresoftware.com/images/posts/2018/2/chrome_headless_thumb.png)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I don't really care for the watch running all the time on tests, as I prefer to run my tests manually, so I usually turn&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;autoWatch: false,
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;in &lt;code&gt;karma.conf.js&lt;/code&gt;. I also don't like a lot of chatter in my test output, so I also set&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;logLevel: config.LOG_ERROR,
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now when I run the tests, I get just the last line from above. That's more like it!&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2018/2/final_thumb.png" alt="https://cdn.volaresoftware.com/images/posts/2018/2/final_thumb.png" /&gt;&lt;/p&gt;
&lt;p&gt;All the code for this post can be found on &lt;a href="https://github.com/VolareSystems/KarmaWithChromeHeadless"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
</description>
      <pubDate>Mon, 12 Feb 2018 08:30:00 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/specflow-isnt-just-a-watin-wrapper</guid>
      <link>https://volaresoftware.com/en/technical-posts/specflow-isnt-just-a-watin-wrapper</link>
      <title>SpecFlow isn't just a WatiN Wrapper</title>
      <description>&lt;p&gt;I have been using &lt;a href="http://specflow.org/"&gt;SpecFlow&lt;/a&gt; with &lt;a href="http://watin.sourceforge.net/"&gt;WatiN&lt;/a&gt; for about 9 months now.  It's a great combination for driving the features you want in a web site and verifying they work as expected.  SpecFlow takes care of the &lt;a href="http://en.wikipedia.org/wiki/Behavior_Driven_Development"&gt;BDD&lt;/a&gt; framework and application features side, while WatiN drives the browser to verify behavior.&lt;/p&gt;
&lt;p&gt;I've gotten used to the the pattern of writing a SpecFlow scenario, then writing the WatiN code in the step definition to open a browser and perform the task or look for the expected HTML.  Once you get the hang of the tools and the process, it's a very sustainable workflow for the developer.&lt;/p&gt;
&lt;p&gt;But today I ran into something that I couldn't test with WatiN.  I wanted to check that an XML sitemap was coming up correctly on a web site.  WatiN was able to open the XML document in the browser, but there was no Body tag because the XML is not an HTML document, so WatiN couldn't read the XML.  All I needed to do was verify that an expected value was in the XML sitemap.  If the value was found, the test would pass.&lt;/p&gt;
&lt;p&gt;I spent about 15 minutes trying out different WatiN commands to find the text, but with no Body tag, there was nothing loaded into the WatiN object model, so nothing was working.  I also tried looking through the WatiN Elements collection and a few other dead ends, but it was only showing me the previous web page or null.&lt;/p&gt;
&lt;p&gt;Finally, the obvious answer occurred to me.  I'm looking at an XML document and I want to verify that it has a value in it.  I'm in a SpecFlow step definition and I've got the entire .NET framework at my disposal, not just WatiN.  Five minutes later, I've got it coded to load and examine an XDocument for the value I needed so the test can pass.&lt;/p&gt;
&lt;p&gt;This was a good lesson for me.  Being on a development workflow roll is no excuse to not keep your head up for alternative strategies that would better solve your problem.  SpecFlow isn't just a wrapper for WatiN calls.  It can be used to verify any behavior it can invoke.&lt;/p&gt;
</description>
      <pubDate>Wed, 05 Jan 2011 01:40:28 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/fix-for-cisco-anyconnect-hanging-on-hostscan-is-waiting-for-the-next-scan</guid>
      <link>https://volaresoftware.com/en/technical-posts/fix-for-cisco-anyconnect-hanging-on-hostscan-is-waiting-for-the-next-scan</link>
      <title>Fix for Cisco AnyConnect hanging on Hostscan is waiting for the next scan</title>
      <description>&lt;p&gt;Welcome Coronavirus work-from-home folks trying to get their Cisco AnyConnect VPN working! I wrote this article about a year and a half ago but have recently refreshed it.&lt;/p&gt;
&lt;p&gt;If solution below still works for you, please leave a comment below. Thanks, and happy social distancing! :)&lt;/p&gt;
&lt;h2 id="tldr"&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;If you use Fiddler to watch network traffic on your computer, it creates personal certificates that interfere with Cisco AnyConnect VPN.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Inside Fiddler, choose &lt;code&gt;Tools&lt;/code&gt; &amp;gt; &lt;code&gt;Fiddler Options&lt;/code&gt; &amp;gt; &lt;code&gt;HTTPS&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Click the certificate maker. Click &amp;quot;Clear server certificates on Exit.&amp;quot;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You may have to reboot to clear memory, but you should be able to use  your VPN normally after that.&lt;/p&gt;
&lt;h2 id="backstory"&gt;Backstory&lt;/h2&gt;
&lt;p&gt;I use Cisco AnyConnect to connect to a client's VPN. Lately, it started hanging with the status message &amp;quot;Hostscan is waiting for the next scan&amp;quot;.&lt;/p&gt;
&lt;p&gt;The logs show a loop that lasts a little over 10 minutes where it scans and starts over until it finally gives up.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-batch"&gt;9:42:46 AM Hostscan state idle
9:42:48 AM Hostscan is waiting for the next scan
9:43:50 AM Hostscan is performing system scan
9:43:51 AM Hostscan is performing software scan
9:43:58 AM Hostscan state idle
9:44:00 AM Hostscan is waiting for the next scan
9:45:03 AM Hostscan is performing system scan
9:45:04 AM Hostscan is performing software scan
9:45:19 AM Hostscan state idle
9:45:22 AM Hostscan is waiting for the next scan
9:46:24 AM Hostscan is performing system scan
9:46:24 AM Hostscan is performing software scan
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I read something about removing personal certificates helping with this, but I only have a few personal certificates, and they are my machine name, &lt;code&gt;localhost&lt;/code&gt;, local development, and something NVIDIA put on there.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2018/12/image_thumb_46.png" alt="https://cdn.volaresoftware.com/images/posts/2018/12/image_thumb_46.png" /&gt;&lt;/p&gt;
&lt;h2 id="solution"&gt;Solution&lt;/h2&gt;
&lt;p&gt;But then I read something else about personal certificates in IE11.  Sure enough, under Tools (or the gear icon) &amp;gt; Internet Options &amp;gt; Content there is a button for Certificates.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2018/12/image_thumb_47.png" alt="https://cdn.volaresoftware.com/images/posts/2018/12/image_thumb_47.png" /&gt;&lt;/p&gt;
&lt;p&gt;After clicking that, I saw something very different from the machine certificates. They were there, plus some other certificates for local development, but there were HUNDREDS like &lt;code&gt;*.somewebsite.com&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I sorted by the name, selected them, and removed them. Then I tried Cisco AnyConnect again, and it finally connected.&lt;/p&gt;
&lt;p&gt;The wildcard certificates I saw in the IE11 Internet Options were created by &lt;a href="https://www.telerik.com/fiddler"&gt;Fiddler&lt;/a&gt;, which I use to watch network traffic and inspect web requests and responses. Fiddler acts as a proxy between your computer and your internet connection, and I guess it creates a personal wildcard certificate for every site you visit, or when Dropbox syncs, or your email does a send/receive, etc.&lt;/p&gt;
&lt;p&gt;Since I must use Cisco AnyConnect for the VPN and I only use Fiddler sometimes, I removed the wildcard certificates and uninstalled Fiddler and I've been able to connect to the VPN reliably for a week now.&lt;/p&gt;
</description>
      <pubDate>Wed, 11 Mar 2020 13:34:00 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/stop-wasting-time-with-enums-in-c</guid>
      <link>https://volaresoftware.com/en/technical-posts/stop-wasting-time-with-enums-in-c</link>
      <title>Stop wasting time with enums in C#</title>
      <description>&lt;p&gt;Enums in C# can make you code easier to read:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;private enum Status
{
    Awesome = 1,
    Cool = 2
};
&lt;p&gt;public void Sample()
{
var lego = new Lego();&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;lego.Everything = Status.Awesome;
if (lego.PartOfTeam == true)
{
    lego.Everything = Status.Cool;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;But enums don't cross in and out of C# easily.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Have you ever tried to save an enum to SQL?  It becomes an &lt;code&gt;int&lt;/code&gt; and you're right back to, &amp;quot;Wait, what does a Status of 2 mean again?&amp;quot;.&lt;/p&gt;
&lt;p&gt;It's easy convert the enum to a &lt;code&gt;string&lt;/code&gt; before sending it to SQL, but then you have to convert it back to an enum in C# when you read it in, and that code is gross:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public string ConvertEnumToString(Status status)
{
   return status.ToString();
}
&lt;p&gt;public Status ConvertStringToEnum(string status)
{
return (Status) Enum.Parse(typeof (Status), status);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;What about sending the value down to the client in JSON?  Again, by default you get an &lt;code&gt;int&lt;/code&gt; that looses the point of having the enum in the first place.&lt;/p&gt;
&lt;p&gt;That is, unless you want to add enum converters from Json.NET to your &lt;code&gt;JsonSerializer&lt;/code&gt; to turn them into strings:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;serializer.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="thats-not-so-bad.plus-whats-the-alternative"&gt;That's not so bad.  Plus, what's the alternative?&lt;/h2&gt;
&lt;p&gt;The simplest alternatives are primitive types that convert across all layers, like &lt;code&gt;ints&lt;/code&gt; and &lt;code&gt;strings&lt;/code&gt;.  I prefer &lt;code&gt;strings&lt;/code&gt; so I can immediately know what the value represents and code around that (e.g., the Status is &amp;quot;Cool&amp;quot; instead of 2).&lt;/p&gt;
&lt;p&gt;&amp;quot;But this is using magic &lt;code&gt;strings&lt;/code&gt;, and those are bad.&amp;quot;  Maybe.  But 1) everyone likes magic, and 2) what's the risk?&lt;/p&gt;
&lt;p&gt;That you mistype the &lt;code&gt;string&lt;/code&gt;? There is type-safety risk, but it's a mild one and only applies to C#.  Let's say you're in JavaScript and looking for that status of &amp;quot;Coll&amp;quot; instead of &amp;quot;Cool&amp;quot;.  That code will fail.  How long until you figure that out? You'll have tests and/or run the code yourself and see it doesn't work, right?&lt;/p&gt;
&lt;p&gt;Also, if you work with a dynamic language, you know you can type in any nonsense and your compiler won't help you. It's up to you to test it. I see magic &lt;code&gt;strings&lt;/code&gt; the same way. Yes, you might make a mistake the compiler doesn't catch, but that's why we test our code.&lt;/p&gt;
&lt;p&gt;What about the risk that the value changes in the future.  Let's say management decides that statuses of &amp;quot;Awesome&amp;quot; are too strong.  They want you to change all occurrences of &amp;quot;Awesome&amp;quot; to &amp;quot;Good&amp;quot; throughout the app.  What's the damage here?&lt;/p&gt;
&lt;p&gt;Well if you have C# enums, you change &lt;code&gt;Status.Awesome&lt;/code&gt; to &lt;code&gt;Status.Good&lt;/code&gt; everywhere, then you update you SQL data so old records are correct (only needed if you converted the enum values to &lt;code&gt;strings&lt;/code&gt; before storing them), then you update your JavaScript so it doesn't look for or branch on the wrong &lt;code&gt;string&lt;/code&gt; (again, only needed if you serialized your C# enums to strings).&lt;/p&gt;
&lt;p&gt;If you didn't use enums at all, and just used &lt;code&gt;strings&lt;/code&gt; in C#, you would have the same SQL and JavaScript updating to do, but maybe more C# &lt;code&gt;strings&lt;/code&gt; to find/replace throughout the project. But I don't think you can reasonably say that's a lot more work. Maybe a few minutes more?&lt;/p&gt;
&lt;p&gt;On top of that, what's the risk that enums change in the future like this. It's not zero, but it's really low. Enum values should be immutable and usually represent the type or state of something, so enum values don't change their meanings very often.&lt;/p&gt;
&lt;p&gt;So why go to the trouble to store C# values in a special type that SQL and JavaScript can't work with? A magic &lt;code&gt;string&lt;/code&gt; is just as easy to read as the enum, and it works up and down the stack.&lt;/p&gt;
&lt;p&gt;Here's the original code, but with magic &lt;code&gt;string&lt;/code&gt;s instead of enums. I don't think it loses any clarity:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public void Sample()
{
    var lego = new Lego();
&lt;pre&gt;&lt;code&gt;lego.Everything = &amp;amp;quot;Awesome&amp;amp;quot;;
if (lego.PartOfTeam == true)
{
    lego.Everything = &amp;amp;quot;Cool&amp;amp;quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="concerns-with-this-approach"&gt;Concerns with this approach&lt;/h2&gt;
&lt;p&gt;This post has generated a lot of comments! It's been a good discussion on the tradeoffs of using C# enums. Some people have agreed with me that it is simpler to use magic &lt;code&gt;strings&lt;/code&gt; because they work across languages.&lt;/p&gt;
&lt;p&gt;Some have worried about database space used storing &lt;code&gt;strings&lt;/code&gt; vs. &lt;code&gt;ints&lt;/code&gt;. &lt;code&gt;Strings&lt;/code&gt; do take up more disk space, but I'd argue we're living in the age of not worrying about that, so take advantage of it. Others have pointed out databases can sort, index, and pull &lt;code&gt;ints&lt;/code&gt; faster than &lt;code&gt;strings&lt;/code&gt;. If storage costs or milliseconds matter in your situation, you'll need to factor that in.&lt;/p&gt;
&lt;p&gt;Others have agreed with the point that enum conversions can be messy, but think I've gone too far with magic &lt;code&gt;strings&lt;/code&gt; everywhere. The consensus with this crowd seems to be maybe skip enums, but &lt;em&gt;at least&lt;/em&gt; use C# static classes. I like this, and that's what I'm doing these days:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public static class Status
{
    public const string Awesome = &amp;quot;Awesome&amp;quot;;
    public const string Cool = &amp;quot;Cool&amp;quot;;
}
lego.Everything = Status.Awesome;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Still others want their C# enums just like they are and don't mind converting in JavaScript and SQL if needed.&lt;/p&gt;
&lt;p&gt;It's up to you to decide what makes the most sense for your project.&lt;/p&gt;
</description>
      <pubDate>Sun, 12 Apr 2020 04:29:00 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/using-crm-auto-filtering-in-custom-reports-with-complex-sql</guid>
      <link>https://volaresoftware.com/en/technical-posts/using-crm-auto-filtering-in-custom-reports-with-complex-sql</link>
      <title>Using CRM auto filtering in custom reports with complex SQL</title>
      <description>&lt;p&gt;Report prefiltering in Microsoft CRM 4.0 is a very cool feature - when it works.  The normal ways of setting up this auto filtering feature in your custom CRM reports are 1) special aliases, and 2) SQL strings.&lt;/p&gt;
&lt;h2 id="special-aliases"&gt;Special aliases&lt;/h2&gt;
&lt;p&gt;The alias approach is the simplest one to use.  If you have a report that needs prefiltering, change your SQL from this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-sql"&gt;select firstname, lastname 
from FilteredContact
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;to this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-sql"&gt;select firstname, lastname 
from FilteredContact AS CRMAF_FilteredContact
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The trick is the alias.  All you need to do is add an alias with &lt;code&gt;CRMAF\_&lt;/code&gt; in front of the view name, and CRM will rip out your SQL at report runtime and replace it with a custom SQL statement.  I think the acronym must stand for CRM Auto Filter.  By using a special alias CRM recognizes, the actual SQL run on your server will be similar to this, where contacts are prefiltered for city = 'Denver'.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-sql"&gt;select firstname, lastname 
from (select contact0.* 
      from FilteredContact as contact0 
      where address1_city  = 'Denver') AS CRMAF_FilteredContact
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="sql-strings"&gt;SQL strings&lt;/h2&gt;
&lt;p&gt;The other route you can go is mash together SQL strings and get a parameter from CRM that is the prefilter SQL statement.  You've probably done this kind of this kind of thing before:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-sql"&gt;declare @sqlstring varchar(max)
set @sqlstring = 'select firstname, lastname 
from (' + @CRM_FilteredContact + ') AS MyFilteredContacts '
exec (@sqlstring)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This really isn't bad when you have a small SQL statement, but you probably wouldn't need to create a custom CRM report if it was a simple SQL statement, right?  The CRM users could create their own simple report inside CRM for that.&lt;/p&gt;
&lt;p&gt;When the SQL statement gets complex, you have quote and string bugs.  When the SQL gets lengthy, you can't have over a certain number of characters in the SQL string or you have to split it and you end up with:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-sql"&gt;exec (@sqlstring1 + @sqlstring2 + @sqlstring3)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can get it to work, but it's pretty yucky.&lt;/p&gt;
&lt;h2 id="the-problem"&gt;The problem&lt;/h2&gt;
&lt;p&gt;I much prefer the alias approach.  It's much easier to read, and the aliases are not too much trouble to add in and get prefiltering in CRM for free.&lt;/p&gt;
&lt;p&gt;The problem is, the alias technique breaks down when the queries get more complex or you need multiple datasets in your report using the same prefiltering.  Here are the cases I've found and the workarounds.&lt;/p&gt;
&lt;h2 id="dataset-based-on-a-union-query"&gt;Dataset based on a union query&lt;/h2&gt;
&lt;p&gt;If you have a query with a union statement, like:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-sql"&gt;select firstname, lastname 
from FilteredContact AS CRMAF_FilteredContact
where address1_city = 'Denver'
union
select firstname, lastname 
from FilteredContact AS CRMAF_FilteredContact
where address1_city = 'Highlands Ranch'
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;CRM will do the alias filtering trick, &lt;strong&gt;but only for the first select&lt;/strong&gt;.  The second select in this query will not be filtered at all.&lt;/p&gt;
&lt;p&gt;The fix I've come up with uses SQL temp tables.  Maybe not the best approach, but I had a lot of reports that were not auto filtering as expected, and this has worked so far:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-sql"&gt;select * 
into #FilteredContact
from FilteredContact AS CRMAF_FilteredContact
&lt;p&gt;select firstname, lastname
from #FilteredContact
where address1_city = 'Denver'
union
select firstname, lastname
from #FilteredContact
where address1_city = 'Highlands Ranch'&lt;/p&gt;
&lt;p&gt;drop table #FilteredContact
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;This let's CRM do what it wants to, and swaps out your SQL where it finds the &lt;code&gt;CRMAF\_FilteredContact&lt;/code&gt; alias the first time.  It also let's you leave the rest of your SQL pretty much intact.&lt;/p&gt;
&lt;h2 id="dataset-based-on-multiple-queries-selecting-into-a-temp-table"&gt;Dataset based on multiple queries selecting into a temp table&lt;/h2&gt;
&lt;p&gt;I had another query that was suffering the same problem, but this query was a little different.  I needed the data displayed in columns, so I created a temp table and populated it with selects.  There were multiple selects in the query filling up the columns in this temp table.  Everything ran great without auto filtering.&lt;/p&gt;
&lt;p&gt;But with auto filtering, the same thing happened.  The first select statement got filtered.  The ones after that were untouched.  The fix I used was the same.  I created a temp table, populated it with the auto filtered data, then selected off that temp table throughout.&lt;/p&gt;
&lt;p&gt;To be a good TempDB citizen, I dropped the temp table at the end of the query.  SQL Server does the temp table drop for you when the table is out of scope, but it helps to have the drop statement in there when testing the query in SQL Server Management Studio and running it multiple times in the same query window.&lt;/p&gt;
&lt;h2 id="reports-with-multiple-datasets"&gt;Reports with multiple datasets&lt;/h2&gt;
&lt;p&gt;This technique works if you have a complex query that needs auto filtering.  But what if you have multiple datasets in your report, and they all need to be auto filtered?&lt;/p&gt;
&lt;p&gt;In one report, the queries were very similar.  I had two datasets that were identical expect one used report parameter A and one used report parameter B.  This was to compare two funnels for two different time periods.  Auto filtering worked fine on the first dataset and funnel, but didn't do anything on the second dataset or funnel.&lt;/p&gt;
&lt;p&gt;The fix in this case was to create one dataset that didn't filter on either report parameter A or parameter B.  Then in the report, have the funnel controls themselves do the filtering based on the report parameters.  Most SQL Server Reporting Services data controls have a filter property.  I've never really used them before now, since it almost never makes sense to pull all the data from the database and then filter inside the report.  I'd rather filter on the database first.  However, in this case, the control filters helped and I got the result I wanted because there was one dataset with one &lt;code&gt;CRMAF\_ alias&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;On another report, there were three charts built using three different datasets.  The datasets were the same except for the group by clause.  I was able to use the same approach and condense these to one dataset with no group by clause, then do the grouping in the chart controls.  Again, it made me feel a little bad that the data wasn't already summed and grouped when it got to the chart control, but at least it was working.&lt;/p&gt;
</description>
      <pubDate>Mon, 14 Feb 2011 01:40:20 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/rest-like-behavior-with-mvc-instead-of-wcf</guid>
      <link>https://volaresoftware.com/en/technical-posts/rest-like-behavior-with-mvc-instead-of-wcf</link>
      <title>REST-like behavior with MVC instead of WCF</title>
      <description>&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms735119.aspx"&gt;WCF&lt;/a&gt; is a very cool framework for adding an abstraction layer over your services.  You can have .asmx, .svc, and now, &lt;a href="http://msdn.microsoft.com/en-us/netframework/cc950529.aspx"&gt;REST&lt;/a&gt; URLs with no extension.  These endpoints can even return &lt;a href="http://en.wikipedia.org/wiki/JSON"&gt;JSON&lt;/a&gt; to the caller, which is useful if you're using &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt; or another JavaScript library.&lt;/p&gt;
&lt;p&gt;The knock on WCF?  The configuration story!  It's &lt;a href="http://microsoftpdc.com/Sessions/FT13"&gt;getting&lt;/a&gt; &lt;a href="http://blogs.microsoft.co.il/blogs/stiller/archive/2009/11/19/pdc-2009-day-3-what-s-new-in-wcf-4-0.aspx"&gt;better&lt;/a&gt; in WCF 4, which is scheduled for release in a month or so.  It will have a bunch of defaults so you don't have to be as explicit in your config file.  Finally, some &lt;a href="http://en.wikipedia.org/wiki/Convention_over_configuration"&gt;convention over configuration&lt;/a&gt; in the WCF space!  Now someone needs to create a fluent, code-based configuration tool for the exceptions to the default conventions…&lt;/p&gt;
&lt;h2 id="dont-be-afraid-of-json"&gt;Don't be afraid of JSON!&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2010/3/jason_thumb.jpg" alt="https://cdn.volaresoftware.com/images/posts/2010/3/jason_thumb.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;But if you need to return JSON to a caller today, you don't need scary WCF config files to do it.  You can get the same URL and the same data payload with a lot less hassle using MVC controller actions.&lt;/p&gt;
&lt;p&gt;The steps are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a new action in a controller.&lt;/li&gt;
&lt;li&gt;Grab your data or whatever you want to return.&lt;/li&gt;
&lt;li&gt;Parse your data to JSON.&lt;/li&gt;
&lt;li&gt;Throw it back out to the requestor.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The trick is to use &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.mvc.jsonresult.aspx"&gt;JsonResult&lt;/a&gt; as the return type for your controller action and convert your output to a JSON string with the base controller's &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.mvc.controller.json.aspx"&gt;Json&lt;/a&gt; method:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public JsonResult GetAllDepartments()
{
    var departments = _repository.GetAllDepartments();
    return Json(departments);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now if I browse to this controller action (I'm using the HomeController in this example):&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;u&amp;gt;http://localhost/Home/GetAllDepartments&amp;lt;/u&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I get a pop-up to save the response stream, which I can open with Notepad:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-json"&gt;[{&amp;quot;Name&amp;quot;:&amp;quot;Human Resources&amp;quot;},{&amp;quot;Name&amp;quot;:&amp;quot;Accounting&amp;quot;},{&amp;quot;Name&amp;quot;:&amp;quot;IT&amp;quot;},{&amp;quot;Name&amp;quot;:&amp;quot;Pencil Sharpening&amp;quot;}]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Yeah, JSON!  And there was no gory config setup needed!&lt;/p&gt;
&lt;h2 id="using-jquery-with-json"&gt;Using jQuery with JSON&lt;/h2&gt;
&lt;p&gt;Now we can use jQuery in the MVC view to take advantage of this returned JSON.&lt;/p&gt;
&lt;p&gt;Here's a view that has a button and a div tag.  jQuery is being used to tie the button click to a call to the controller and action we set up above.  It then gets the JSON coming back, loops through it, and puts it in the div tag so it's visible to the user.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;&amp;lt;script src=&amp;quot;../../Scripts/jquery-1.3.2.min.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&lt;p&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;
$(function() {
$(&amp;quot;#btnShowDepartments&amp;quot;).click(function() {
$.getJSON(&amp;quot;/Home/GetAllDepartments&amp;quot;, null, function(data) {
for (item in data) {
var department = data[item];
$(&amp;quot;#divDepartments&amp;quot;).append(department.Name, &amp;quot;, &amp;quot;);
}
});&lt;br /&gt;
});
});&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;p&amp;gt;
&amp;lt;input id=&amp;quot;btnShowDepartments&amp;quot; type=&amp;quot;button&amp;quot; value=&amp;quot;Show Departments&amp;quot; /&amp;gt;
&amp;lt;div id=&amp;quot;divDepartments&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;This is probably not the best jQuery in the world.  I'm still new to it.  But the point is to show that you can put a URL in, parse the JSON, and use the data however your app needs it.&lt;/p&gt;
</description>
      <pubDate>Mon, 08 Mar 2010 01:40:57 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/is-aspnet-relevant-to-modern-web-development</guid>
      <link>https://volaresoftware.com/en/technical-posts/is-aspnet-relevant-to-modern-web-development</link>
      <title>Is ASP.NET relevant to modern web development?</title>
      <description>&lt;p&gt;ASP.NET has a &lt;a href="http://www.asp.net/vnext"&gt;new version coming out soon&lt;/a&gt;.  ASP.NET vNext will have a new project file management system (long overdue) and a lot of integration points with modern front-end web development tooling, like Grunt and Bower.&lt;/p&gt;
&lt;p&gt;I'm a web developer, and all of the back-end systems I work with are Microsoft based (ASP.NET MVC and Web API, SQL Server, Azure, etc.).  I must be super excited about this new stuff coming soon, right?&lt;/p&gt;
&lt;p&gt;Nah, not really.&lt;/p&gt;
&lt;p&gt;Like most web developers, I spend a lot of time in HTML5 and CSS3 and tons of time in JavaScript.  I spend most of my energy getting front-end libraries to work together, making web pages responsive, dealing with cross-browser and cross-device issues, and debugging with browser tools.  Over the last several years, MVC, Web API, and even SQL Server have been less a part of my day-to-day coding, so changes and new versions matter less to me.&lt;/p&gt;
&lt;h3 id="just-another-back-end"&gt;Just another back end?&lt;/h3&gt;
&lt;p&gt;If you are a front-end web developer, you need your AJAX request to hit a back-end endpoint and give you a response.  That kind of framing of the back-end, that it can be encapsulated or black-boxed, also means its implementation could be changed and you wouldn't really care.  Why should it matter if the back end is written with node.js, Ruby on Rails, Java, Azure Mobile Services, or ASP.NET?  From the front-end web developer perspective, I just want a response.  Obviously, it needs to be fast, scalable, robust, secure, and that kind of thing, but all major server-side frameworks have that figured out.&lt;/p&gt;
&lt;p&gt;It seems to me that back-end tooling is becoming a commodity.  Here's what I mean.  Quick - which cloud provider is the best one?  I don't know.  Aren't they all about the same? Maybe they have different SLAs, or broader or narrower service offerings, but just to get a web app running with a database, they are all about the same.  If one was $5/month cheaper, wouldn't you switch to them?  Unless the support or extra services or the hassle of changing cloud providers were worth an extra $5/month to you, you'd switch.&lt;/p&gt;
&lt;p&gt;I think of ASP.NET and SQL Server the same way.  It's back-end tooling.  It involves maybe 10-25% of my coding week.  I'm not dissatisfied with the tools.  I just don't use them that much.  I guess they could get a little better, but that won't make me need to use them more or care more about how they are implemented.&lt;/p&gt;
&lt;p&gt;I don't send view models down with my MVC views anymore.  I just let MVC serve up a view-model-less view and let JavaScript and AJAX calls go get anything else the page needs.  This means the initial page loads fast, but it doesn't fully work until the JavaScript has finished putting everything in its place.&lt;/p&gt;
&lt;p&gt;Once you start spending a lot of time in JavaScript and pulling in data with AJAX, and you have to write it that way so the user can interact with the page, then why write it twice with 1) the Razor-template-populated-with-initial-view-model way, and 2) the HTML-template-populated-with-AJAX-data way?  Writing the same functionality with two templating languages and two data sources isn't going to get your project done faster or reduce maintenance costs.&lt;/p&gt;
&lt;p&gt;Plus, the user gets to see most of the page, just maybe without all the data yet or with empty drop downs while the data is still on its way to the page.  I think that gives the user a sense that we're getting you the parts of the page as soon as we can, instead of building everything up on the server as one big ball of templated data while you look at a white, empty browser window.&lt;/p&gt;
&lt;p&gt;So why not just dump the whole thing and code HTML, CSS, and JavaScript with any old text editor?&lt;/p&gt;
&lt;h3 id="where-does-the-microsoft-ecosystem-add-value-in-modern-web-development"&gt;Where does the Microsoft ecosystem add value in modern web development?&lt;/h3&gt;
&lt;h4 id="ide"&gt;IDE&lt;/h4&gt;
&lt;p&gt;In spite of its limitations for front-end development, Visual Studio is still a very good IDE.  Different colors for keywords and navigation within and across files is very good.  But most of the value I get from continuing to use Visual Studio is a result of the &lt;a href="http://vswebessentials.com/"&gt;Web Essentials&lt;/a&gt; extension.  It's nice to run JSHint with every save and to get pointers in the IDE about CSS rules, potential browser issues, and unclosed HTML tags.  If I switched to Notepad, I'd be giving up some things that really do make my coding day a little brighter.&lt;/p&gt;
&lt;p&gt;Working with the current Visual Studio project system has been more than just an annoyance; it's been a source of real pain.  Looks like the new project/file system may help in vNext.&lt;/p&gt;
&lt;p&gt;I can't say that Intellisense is very useful to me these days.  It's never really worked right with JavaScript.  Maybe that will get a little better, but I've gotten used to it pulling up every JavaScript symbol when I type &amp;quot;.&amp;quot;.&lt;/p&gt;
&lt;h4 id="local-web-server"&gt;Local Web Server&lt;/h4&gt;
&lt;p&gt;Simple and unobtrusive, IIS Express is a great place to test run your web app, and the integration with Visual Studio is limited but sufficient.&lt;/p&gt;
&lt;p&gt;The alternative would be HTML files that you double click to open and debug in the browser.  It would work, but you'd have to keep you file system and text editor open all the time, and you wouldn't have server-side debugging of your API layer.&lt;/p&gt;
&lt;h4 id="security"&gt;Security&lt;/h4&gt;
&lt;p&gt;Security is probably the main thing that has kept me from dumping ASP.NET and using HTML files instead.  I've never worked on a web app where security wasn't important.  You need a way to know who's knocking on the server's door, and when that request is bouncing around on the back-end servers, you need to know what group/role that user is in so you can turn features on and off.&lt;/p&gt;
&lt;p&gt;I still use MVC and Web API for their security, and I'm glad their namespaces are finally going to be merged in vNext.  That means I won't have any more code that filters MVC requests one way and Web API requests another way.&lt;/p&gt;
&lt;h4 id="api-layer"&gt;API layer&lt;/h4&gt;
&lt;p&gt;Web API is totally relevant for modern web development.  All web apps need a way of interacting with a back end, and Web API sets up as a simple, thin transport layer so you can do whatever back-end stuff you need to do on the server. Content negotiation is nice if you have a public API, but I've only written internal APIs that send/receive JSON.&lt;/p&gt;
&lt;h3 id="conclusion"&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;I guess I am looking forward to some of the improvements in ASP.NET vNext.&lt;/p&gt;
&lt;p&gt;If I was building a new web app today, would I use ASP.NET as the back end?  Probably, but it would be the same way I've used it the last 4-5 years: minimal MVC page serving, an API service layer, and a security layer.&lt;/p&gt;
&lt;p&gt;The most interesting, highest customer value web development stuff is happening on the front end, and I don't see that changing anytime soon.&lt;/p&gt;
</description>
      <pubDate>Mon, 29 Dec 2014 05:04:00 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/working-with-the-latest-javascript-syntax-on-your-project-today</guid>
      <link>https://volaresoftware.com/en/technical-posts/working-with-the-latest-javascript-syntax-on-your-project-today</link>
      <title>Working with the latest JavaScript syntax on your project today</title>
      <description>&lt;p&gt;Are you working in an existing code base with tons of ES5 JavaScript, and you're jealous of your friends working on greenfield projects using ES6/ES7/ES8+ or ES2015/ES2016/ES2017+ JavaScript?  Here's how we moved our code base forward to start using newer features of JavaScript without losing our minds.&lt;/p&gt;
&lt;p&gt;I've made a sample project using the ASP.NET MVC default project (and removing some of the noise). You can &lt;a href="https://github.com/VolareSoftware/ECMAScriptWithBabelAndWebpack"&gt;see all the code&lt;/a&gt; if you want to follow along or fork this on GitHub.&lt;/p&gt;
&lt;h3 id="install-npm-packages"&gt;Install NPM packages&lt;/h3&gt;
&lt;p&gt;First, &lt;a href="https://nodejs.org/en/download/"&gt;install node and npm&lt;/a&gt;, then install &lt;a href="https://webpack.js.org/"&gt;webpack&lt;/a&gt; and &lt;a href="https://babeljs.io/"&gt;Babel&lt;/a&gt; from the command line in the web project root.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;npm install --save-dev babel-core babel-loader babel-preset-env
npm install --save-dev webpack webpack-cli
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When you are done, you should have a  &lt;code&gt;devDependencies&lt;/code&gt; section in your &lt;code&gt;package.json&lt;/code&gt; file, also in the web root, that looks something like this. You will almost certainly have different versions, and you will probably have more than just this in your  &lt;code&gt;devDependencies&lt;/code&gt; section, and that's fine.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;&amp;quot;devDependencies&amp;quot;: {
  &amp;quot;babel-core&amp;quot;: &amp;quot;^6.26.0&amp;quot;,
  &amp;quot;babel-loader&amp;quot;: &amp;quot;^7.1.4&amp;quot;,
  &amp;quot;babel-preset-env&amp;quot;: &amp;quot;^1.6.1&amp;quot;,
  &amp;quot;webpack&amp;quot;: &amp;quot;^4.4.1&amp;quot;,
  &amp;quot;webpack-cli&amp;quot;: &amp;quot;^2.0.13&amp;quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="set-up-visual-studio"&gt;Set up Visual Studio&lt;/h2&gt;
&lt;p&gt;The plan is to leave old JavaScript files with the &lt;code&gt;*.js&lt;/code&gt; extension and create new ES2015+ JavaScript files with the &lt;code&gt;*.es6&lt;/code&gt; extension.  You can use &lt;code&gt;*.es2015&lt;/code&gt; or any other extension not already in use if you prefer.  We just need some file marker so webpack knows which files need Babel transpilation and which don't.&lt;/p&gt;
&lt;p&gt;In Visual Studio, you'll need to set up this new extension to use the JavaScript editor.  You can do that in Tools &amp;gt; Options &amp;gt; Text Editor &amp;gt; File Extension. If you skip this step, Visual Studio will treat &lt;code&gt;*.es6&lt;/code&gt; like text files instead of JavaScript files.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2018/4/image_thumb_42.png" alt="https://cdn.volaresoftware.com/images/posts/2018/4/image_thumb_42.png" /&gt;&lt;/p&gt;
&lt;h3 id="configure-webpack-and-babel"&gt;Configure webpack and Babel&lt;/h3&gt;
&lt;p&gt;Let's set up the &lt;code&gt;webpack.config.js&lt;/code&gt; file in the web root to work with the newer JavaScript syntax.&lt;/p&gt;
&lt;p&gt;Below, the &lt;code&gt;resolve&lt;/code&gt; section tells webpack we are using these two extensions for JavaScript files, and webpack should be looking for both &lt;code&gt;*.js&lt;/code&gt; and &lt;code&gt;*.es6&lt;/code&gt; files when making bundles.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;rules&lt;/code&gt; section tells webpack that it needs to use Babel to load &lt;code&gt;*.es6&lt;/code&gt; extension files. There are a lot more Babel options you can add here. For example, want to use async/await in your &lt;code&gt;*.es6&lt;/code&gt; files? Add a Babel &lt;code&gt;plugin&lt;/code&gt; for &lt;code&gt;syntax-async-functions&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;isRelease&lt;/code&gt; flag is used to toggle between development and production settings for the build. This is using webpack 4's new &lt;code&gt;mode&lt;/code&gt; setting, which should set up most things correctly. The &lt;code&gt;devtool&lt;/code&gt; option uses either a quick and dirty source map or a more production-ready one.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;const path = require(&amp;quot;path&amp;quot;);
&lt;p&gt;module.exports = env =&amp;gt; {
const isRelease = env === &amp;quot;RELEASE&amp;quot;;
return {
mode: isRelease ? &amp;quot;production&amp;quot; : &amp;quot;development&amp;quot;,
devtool: isRelease ? &amp;quot;source-map&amp;quot; : &amp;quot;cheap-module-source-map&amp;quot;,
entry: {
index: &amp;quot;index.es6&amp;quot;,
about: &amp;quot;about.js&amp;quot;
},
output: {
filename: &amp;quot;[name].js&amp;quot;,
path: path.resolve(__dirname, &amp;quot;dist&amp;quot;),
publicPath: &amp;quot;/dist&amp;quot;
},
resolve: {
extensions: [&amp;quot;.js&amp;quot;, &amp;quot;.es6&amp;quot;],
modules: [&amp;quot;Scripts&amp;quot;, &amp;quot;node_modules&amp;quot;]
},
module: {
rules: [
{
test: /.es6$/,
exclude: /(node_modules)/,
use: {
loader: &amp;quot;babel-loader&amp;quot;,
options: {
presets: [&amp;quot;env&amp;quot;]
}
}
}
]
}
};
};
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;h3 id="single-page-vs.multi-page-applications"&gt;Single-Page vs. Multi-Page applications&lt;/h3&gt;
&lt;p&gt;In the &lt;code&gt;entry&lt;/code&gt; section above, I've got two values for the two pages in this sample. &lt;code&gt;index&lt;/code&gt; will be built using the &lt;code&gt;index.es6&lt;/code&gt; file as an entry point, and &lt;code&gt;about&lt;/code&gt; will be built using &lt;code&gt;about.js&lt;/code&gt; as the entry point. If your whole app is a SPA, you will have just one entry. If you have a multi-page application, you'll need an entry for each page. Webpack crawls the entry to bundle up all the dependencies.&lt;/p&gt;
&lt;p&gt;We are outputting our files to a &lt;code&gt;/dist&lt;/code&gt; folder. For simplicity, the file name will be the entry name plus &amp;quot;.js&amp;quot;.&lt;/p&gt;
&lt;h3 id="scripts"&gt;Scripts&lt;/h3&gt;
&lt;p&gt;We needs some scripts to test out the different JavaScript syntax styles.&lt;/p&gt;
&lt;p&gt;Here is &lt;code&gt;index.es6&lt;/code&gt;, using the new JavaScript &lt;code&gt;import&lt;/code&gt; and templated string options.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;import $ from &amp;quot;jquery&amp;quot;;
&lt;p&gt;$(&amp;quot;#setInCode&amp;quot;).text(&lt;code&gt;This value was set in code using jQuery at ${new Date().toLocaleString()}.&lt;/code&gt;);
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;And here is &lt;code&gt;about.js&lt;/code&gt;, using older AMD-style modules and ES5 style JavaScript.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;define([&amp;quot;jquery&amp;quot;], function($) {
    $(&amp;quot;#setInCode&amp;quot;).text(&amp;quot;This value was set in code using jQuery at &amp;quot; + new Date().toLocaleString() + &amp;quot;.&amp;quot;);
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These scripts both find an element with jQuery and set some text to it and add the date/time. We want something simple to test if our pages are working with both old and new-style JavaScript.&lt;/p&gt;
&lt;h3 id="script-references"&gt;Script references&lt;/h3&gt;
&lt;p&gt;Since I'm using a boilerplate ASP.NET MVC project template, the &lt;code&gt;_Layout.cshtml&lt;/code&gt; file already has:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;@RenderSection(&amp;quot;scripts&amp;quot;, required: false)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each page, such as &lt;code&gt;Index.cshtml&lt;/code&gt; and &lt;code&gt;About.cshtml&lt;/code&gt; will then reference the built-by-webpack scripts in the &lt;code&gt;/dist&lt;/code&gt; folder with. &lt;code&gt;Index.cshtml&lt;/code&gt; will reference &lt;code&gt;/dist/index.js&lt;/code&gt;, and &lt;code&gt;About.cshtml&lt;/code&gt; will reference &lt;code&gt;/dist/about.js&lt;/code&gt; like this.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;@section scripts
{
    &amp;lt;script src=&amp;quot;/dist/index.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id="build-it"&gt;Build it&lt;/h3&gt;
&lt;p&gt;So we've got our npm packages installed, the &lt;code&gt;webpack.config.js&lt;/code&gt; file is set up, our pages call our webpack-built scripts in the&lt;code&gt;/dist&lt;/code&gt; folder . Let's run it and test it out.&lt;/p&gt;
&lt;p&gt;Add a new section for &lt;code&gt;scripts&lt;/code&gt; to your &lt;code&gt;package.json&lt;/code&gt; file:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;&amp;quot;scripts&amp;quot;: {
  &amp;quot;build&amp;quot;: &amp;quot;webpack --colors --watch&amp;quot;,
  &amp;quot;build:release&amp;quot;: &amp;quot;webpack --colors --env RELEASE&amp;quot;
},
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This allows us to run &lt;code&gt;npm build&lt;/code&gt; and &lt;code&gt;npm build:release&lt;/code&gt; as shortcuts for running webpack commands. You can name the commands anything you like.&lt;/p&gt;
&lt;p&gt;The options show colors in the console, and for the &lt;code&gt;build&lt;/code&gt; script, it sets up a watch on the files to re-run the build if anything changes. You'll want to use this for development. For the &lt;code&gt;build:release&lt;/code&gt; script, we pass in &lt;code&gt;—env RELEASE&lt;/code&gt; so the &lt;code&gt;webpack.config.js&lt;/code&gt; script knows we want the build optimized for production.&lt;/p&gt;
&lt;p&gt;You can also add another section to &lt;code&gt;package.json&lt;/code&gt; to link up these build commands to the Visual Studio Task Runner Explorer.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;&amp;quot;-vs-binding&amp;quot;: {
  &amp;quot;ProjectOpened&amp;quot;: [
    &amp;quot;build&amp;quot;
  ]
},
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will run your new &lt;code&gt;build&lt;/code&gt; command when the project opens. Since it keeps a watch running, that should be all you need to development.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2018/4/task_runner_thumb.png" alt="https://cdn.volaresoftware.com/images/posts/2018/4/task_runner_thumb.png" /&gt;&lt;/p&gt;
&lt;p&gt;For production, you'll want to stop the &lt;code&gt;build&lt;/code&gt; task and manually run the &lt;code&gt;build:release&lt;/code&gt; task in the Task Runner Explorer (or run it from command line, or as a before/after build script for your ASP.NET project, or on your build server…).&lt;/p&gt;
&lt;h3 id="run-it"&gt;Run it&lt;/h3&gt;
&lt;p&gt;Run the web app after the &lt;code&gt;build&lt;/code&gt; command completes and you should be able to browse to the Index and About pages and see the jQuery execute in both pages the same way, even though the syntax for importing jQuery was very different for each page.&lt;/p&gt;
&lt;h3 id="debug-it"&gt;Debug it&lt;/h3&gt;
&lt;p&gt;Note we are referencing &lt;code&gt;index.js&lt;/code&gt; in &lt;code&gt;Index.cshtml&lt;/code&gt; and not the source code file name &lt;code&gt;index.es6&lt;/code&gt;. That's because we're not referencing the source code. We're referencing the webpack built code in the &lt;code&gt;/dist&lt;/code&gt; folder.&lt;/p&gt;
&lt;p&gt;Don't worry. You can still set breakpoints and watches and debug with your favorite browser dev tools when referencing the built code through source maps. When opening a file, look for the one served by &lt;code&gt;webpack://&lt;/code&gt;. It will be the original source code seen through the source map. The other file will be the bundled/minified one.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2018/4/open_this_thumb.png" alt="https://cdn.volaresoftware.com/images/posts/2018/4/open_this_thumb.png" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/debug_minified_javascript.png" alt="https://cdn.volaresoftware.com/images/posts/2019/12/debug_minified_javascript.png" /&gt;&lt;/p&gt;
&lt;h3 id="now-what"&gt;Now what?&lt;/h3&gt;
&lt;p&gt;If you are on a project that isn't using the newer JavaScript syntax and features, talk with your team. Chances are good they would like to be using the new stuff, too.&lt;/p&gt;
&lt;p&gt;You don't need to wait until you get put on a new project. You can start coding with the latest JavaScript syntax today, but still keep backward compatibility for your project's ES5 script.&lt;/p&gt;
</description>
      <pubDate>Tue, 03 Apr 2018 05:17:00 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/deploying-reports-built-with-ssrs-2008-r2-to-ssrs-2008-non-r2</guid>
      <link>https://volaresoftware.com/en/technical-posts/deploying-reports-built-with-ssrs-2008-r2-to-ssrs-2008-non-r2</link>
      <title>Deploying Reports Built with SSRS 2008 R2 to SSRS 2008 non-R2</title>
      <description>&lt;p&gt;I've got SQL Server 2008 R2 Express installed on my primary development machine, and I create SSRS reports on this box.  The problem is, I've got one customer with SQL Server 2008.  And yes, Microsoft changed the RDL file format between SSRS 2008 and SSRS 2008 R2, so SSRS 2008 can't read SSRS 2008 R2 RDL files.&lt;/p&gt;
&lt;p&gt;So how you you get around this without setting up VMs with both?  It's not elegant, but here's what I do:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;On your SSRS project properties with all your reports, change the Target Server Version to SQL Server 2008 (and not SQL Server 2008 R2).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2012/3/snaghtmlab90e1b.png" alt="snaghtmlab90e1b.png" /&gt;&lt;/p&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Get your local dev box SSRS R2 server running if it's not already.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2012/3/snaghtmlabb1913.png" alt="snaghtmlabb1913.png" /&gt;&lt;/p&gt;
&lt;ol start="3"&gt;
&lt;li&gt;Deploy the report project to your local SSRS R2 server.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2012/3/image_12.png" alt="image_12.png" /&gt;&lt;/p&gt;
&lt;ol start="4"&gt;
&lt;li&gt;Go to your report management site (usually http://localhost:Reports) and download the report.  This will save out the RDL for you.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2012/3/image6.png" alt="image6.png" /&gt;&lt;/p&gt;
&lt;ol start="5"&gt;
&lt;li&gt;Now when you deploy this report to the non-R2 SSRS server, it will be the correct, non-R2 format!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The crucial steps are setting that Target Server Version and deploying.  That's where the Visual Studio report project converts the RDL file to the format you need it to be.  After that, the downloading is just a way to get a copy of the report in the non-R2 format.&lt;/p&gt;
&lt;p&gt;Now you can deploy the RDL to the customer's non-R2 SSRS server, without changing your dev box.&lt;/p&gt;
</description>
      <pubDate>Mon, 19 Mar 2012 00:40:02 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/moving-a-vm-to-another-machine</guid>
      <link>https://volaresoftware.com/en/technical-posts/moving-a-vm-to-another-machine</link>
      <title>Moving a VM to another machine</title>
      <description>&lt;p&gt;I've got a work laptop with a &lt;a href="http://www.vmware.com/"&gt;VMware&lt;/a&gt; virtual machine.  But I wanted to move it to my slightly faster personal rig, with the nicer keyboard, mouse, dual monitors, etc.&lt;/p&gt;
&lt;p&gt;So I shut down the VM on the work laptop and copied it over to the personal machine.  Then I downloaded and installed the &lt;a href="http://www.vmware.com/download/player/download.html"&gt;VMware Player&lt;/a&gt; to the new machine, copied the VM to it, and opened it up.  I got a prompt asking if I &amp;quot;moved&amp;quot; or &amp;quot;copied&amp;quot; the VM.  I chose &amp;quot;copied&amp;quot;.&lt;/p&gt;
&lt;p&gt;The VM spun for a little while, and then there was some gibberish message about VT being possible but disabled on the host.  VT = Vermont?  VT = Virginia Tech? VT = WTF?  I did what professional developers are trained to do in these situations.  I ignored it and clicked OK.&lt;/p&gt;
&lt;p&gt;The VM said &amp;quot;Windows in Loading Files.&amp;quot; but it kept rebooting over, and over, and over.&lt;/p&gt;
&lt;p&gt;I got a tip from &lt;a href="http://blog.davidyack.com/"&gt;David Yack&lt;/a&gt; to check the BIOS settings.  I have a &lt;a href="http://www.dell.com/latitude"&gt;Dell Latitude&lt;/a&gt;, so your mileage may vary here, but in &lt;strong&gt;my&lt;/strong&gt; BIOS settings, I go to &lt;code&gt;Post Behavior&lt;/code&gt;, then &lt;code&gt;Virtualization&lt;/code&gt;, then set it to &lt;code&gt;Enabled&lt;/code&gt;, then save settings and reboot.&lt;/p&gt;
&lt;p&gt;That worked!&lt;/p&gt;
</description>
      <pubDate>Tue, 17 Nov 2009 01:41:16 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/a-quick-look-at-ndepend</guid>
      <link>https://volaresoftware.com/en/technical-posts/a-quick-look-at-ndepend</link>
      <title>A quick look at NDepend</title>
      <description>&lt;p&gt;&lt;a href="https://www.ndepend.com/"&gt;NDepend&lt;/a&gt; is a Visual Studio extension designed to help you improve your code quality and reduce your technical debt. It sells for €399 per developer, which is about $462 U.S.&lt;/p&gt;
&lt;p&gt;I gave it a try a very small project and a very large project. You open your project in Visual Studio, point NDepend at it, and wait a minute or so for the reports.&lt;/p&gt;
&lt;p&gt;NDepend spits out a lot of reports and a lot of metrics, from dependency graphs to tree maps with hot spots showing too much cyclomatic complexity in red.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/ndepend_diagrams.jpg" alt="https://cdn.volaresoftware.com/images/posts/2019/12/ndepend_diagrams.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;Here are the small project application metrics:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/ndepend_application_metrics.jpg" alt="https://cdn.volaresoftware.com/images/posts/2019/12/ndepend_application_metrics.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;NDepend gives some basic counts and rule and quality checks, but the most interesting data is the technical debt. Here, both apps get an &amp;quot;A&amp;quot;, but they have 3.69% and 4.81% tech debt. This didn't print out as nicely on my projects as the demo report from NDepend shown below.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/ndepend_stats.png" alt="https://cdn.volaresoftware.com/images/posts/2019/12/ndepend_stats.png" /&gt;&lt;/p&gt;
&lt;p&gt;Here you can see the estimated time to bring your tech debt up a letter grade, from a C to a B, is 14 days and 2 hours. The estimated annual interest on your tech debt is 47 days, and that's up 17 days and 4 hours from the last time the analysis was run.&lt;/p&gt;
&lt;p&gt;When you drill into the errors and warnings NDepend shows you, you can also see the cost of fixing or leaving that tech debt.  Here is one of the rules I broke in my project with a class that has too many methods (48!). In this case, it's a test class, so I'm not worried about it. Neither is NDepend, since it estimates this tech debt will cost me 4 minutes and 13 seconds a year.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/ndepend_rule_violation.png" alt="https://cdn.volaresoftware.com/images/posts/2019/12/ndepend_rule_violation.png" /&gt;&lt;/p&gt;
&lt;p&gt;If you want to tackle your tech debt but don't know where to start, NDepend can help you asses where your project is today, show your progress, and help you decide which tech debt is most costly and needs to be addressed soonest.&lt;/p&gt;
</description>
      <pubDate>Tue, 04 Sep 2018 04:00:00 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/adding-and-styling-dynamic-content-in-jquery-mobile-pages</guid>
      <link>https://volaresoftware.com/en/technical-posts/adding-and-styling-dynamic-content-in-jquery-mobile-pages</link>
      <title>Adding and styling dynamic content in jQuery Mobile pages</title>
      <description>&lt;p&gt;&lt;a href="http://jquerymobile.com/"&gt;jQuery Mobile&lt;/a&gt; does great job styling your web app to look kind of like a native phone app.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2012/10/snaghtml246ff343.png" alt="snaghtml246ff343.png" /&gt;&lt;/p&gt;
&lt;p&gt;It injects lots of classes like &amp;quot;ui-link&amp;quot;, &amp;quot;ui-content&amp;quot;, &amp;quot;ui-listview&amp;quot;, &amp;quot;ui-shadow&amp;quot;, etc. to make your page look pretty.&lt;/p&gt;
&lt;p&gt;But if you're using &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt; to dynamically load content from another source on document ready, jQuery Mobile is already done with its styling changes.  I searched and found lots of suggestions for refreshing the styles in the new section of the page, but .page(), .page(&amp;quot;refresh&amp;quot;), and .trigger(&amp;quot;enhance&amp;quot;) didn't add the styles.  You can see people &lt;a href="http://stackoverflow.com/questions/6297470/forcing-jquery-mobile-to-re-evaluate-styles-theme-on-dynamically-inserted-conten"&gt;struggling&lt;/a&gt; &lt;a href="http://stackoverflow.com/questions/7999436/jquery-mobile-does-not-apply-styles-after-dynamically-adding-content"&gt;with&lt;/a&gt; &lt;a href="http://stackoverflow.com/questions/4844738/dynamic-pages-with-jquery-mobile"&gt;this&lt;/a&gt; &lt;a href="http://stackoverflow.com/questions/9456809/proper-formatting-when-adding-dynamic-content-in-jquery-mobile"&gt;question&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I finally found the answer in &lt;a href="http://blog.stikki.me/2011/08/18/loading-dynamic-content-in-jquery-mobile-with-jquerys-load-function/"&gt;this blog post&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;$(function () {
    $(&amp;quot;#dynamicSection&amp;quot;).load(&amp;quot;/api/dynamicContent&amp;quot;, function () {
        $(this).trigger(&amp;quot;create&amp;quot;);
    });
})
&lt;/code&gt;&lt;/pre&gt;
</description>
      <pubDate>Wed, 11 Jan 2012 01:39:56 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/using-kendo-ui-grid-with-web-api-and-odata</guid>
      <link>https://volaresoftware.com/en/technical-posts/using-kendo-ui-grid-with-web-api-and-odata</link>
      <title>Using Kendo UI grid with Web API and OData</title>
      <description>&lt;p&gt;The &lt;a href="http://demos.kendoui.com/web/grid/index.html"&gt;Kendo UI grid&lt;/a&gt; is a snazzy little thing:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2013/2/image_36.png" alt="image_36.png" /&gt;&lt;/p&gt;
&lt;p&gt;The grid works natively with OData, but &lt;a href="http://demos.kendoui.com/web/grid/remote-data.html"&gt;the examples from the Kendo team are of OData services driven by WCF back ends&lt;/a&gt;.  I wanted to get the grid working with Web API and minimal coding to implement server-side sorting, filtering, and paging.&lt;/p&gt;
&lt;p&gt;Until earlier this week, if you wanted to do that, you were on your own.  There was a partial OData implementation in Web API via a NuGet package, but it didn't support $inlinecount, which is what the grid needs to know how many items there are total (e.g., the $inlinecount for the grid above is 830).&lt;/p&gt;
&lt;p&gt;A more fully supported Web API OData implementation was &lt;a href="http://weblogs.asp.net/scottgu/archive/2013/02/18/announcing-release-of-asp-net-and-web-tools-2012-2-update.aspx"&gt;rolled out this week&lt;/a&gt; and is &lt;a href="https://nuget.org/packages/Microsoft.AspNet.WebApi.OData/4.0.0"&gt;available via NuGet&lt;/a&gt;.  Here are the steps to get it working with a Kendo UI grid.&lt;/p&gt;
&lt;h2 id="server-side"&gt;Server side&lt;/h2&gt;
&lt;p&gt;Open your existing Web API project and install the Web API OData NuGet update:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2013/2/image_37.png" alt="image_37.png" /&gt;&lt;/p&gt;
&lt;p&gt;Decide what data you want to send to the browser and model it.  I've got a Cat entity and a Dog entity:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;namespace KendoGridWebApiOdata.Models
{
    public class Cat
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Color { get; set; }
    }
}
&lt;p&gt;namespace KendoGridWebApiOdata.Models
{
public class Dog
{
public int Id { get; set; }
public string Name { get; set; }
public string Color { get; set; }
}
}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Update your WebApiConfig.Register() method (in the &lt;code&gt;App\_Start&lt;/code&gt; folder):&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;using System.Web.Http;
using System.Web.Http.OData.Builder;
using KendoGridWebApiOdata.Models;
&lt;p&gt;namespace KendoGridWebApiOdata.App_Start
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
var modelBuilder = new ODataConventionModelBuilder();
modelBuilder.EntitySet&amp;lt;Cat&amp;gt;(&amp;quot;Cats&amp;quot;);
modelBuilder.EntitySet&amp;lt;Dog&amp;gt;(&amp;quot;Dogs&amp;quot;);
var model = modelBuilder.GetEdmModel();&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;        config.Routes.MapODataRoute(
            routeName: &amp;amp;quot;OData&amp;amp;quot;,
            routePrefix: &amp;amp;quot;api&amp;amp;quot;,
            model: model
            );

        config.Routes.MapHttpRoute(
            name: &amp;amp;quot;DefaultApi&amp;amp;quot;,
            routeTemplate: &amp;amp;quot;api/{controller}/{id}&amp;amp;quot;,
            defaults: new { id = RouteParameter.Optional }
            );

        // Uncomment the following line of code to enable query support for actions with an IQueryable or IQueryable&amp;amp;lt;T&amp;amp;gt; return type.
        // To avoid processing unexpected or malicious queries, use the validation settings on QueryableAttribute to validate incoming queries.
        // For more information, visit http://go.microsoft.com/fwlink/?LinkId=279712.
        config.EnableQuerySupport();

        // To disable tracing in your application, please comment out or remove the following line of code
        // For more information, refer to: http://www.asp.net/web-api
        config.EnableSystemDiagnosticsTracing();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;You'll define the OData models you want to expose and set up special OData routes for them.  You can add multiple EntitySets to the model builder as needed for your OData endpoints.  Here, I'm adding Cat and Dog to the model builder.&lt;/p&gt;
&lt;p&gt;The MapODataRoute uses the model builder values to create an OData route.  Note this is not exactly a Web API route, but you can use the same &lt;code&gt;/api/{controller}&lt;/code&gt; convention if you like (or &lt;code&gt;/odata/{controller}&lt;/code&gt; if you prefer) by setting the routePrefix to whatever you like.&lt;/p&gt;
&lt;p&gt;I tried toggling &lt;code&gt;config.EnableQuerySupport&lt;/code&gt; on and off, and it worked in both cases, so I don't know if that matters any more after the Web API OData update.&lt;/p&gt;
&lt;p&gt;For more details about what is going on here, check out &lt;a href="http://blogs.msdn.com/b/webdev/archive/2013/01/29/getting-started-with-asp-net-webapi-odata-in-3-simple-steps.aspx"&gt;Youssef Moussaoui's blog post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Finally, you'll need a controller, but this isn't a Web API controller, it's an ODataContoller.  That's kinda close, and it inherits from the Web API controller, but it's specifically designed for the OData calls you just set up in routing.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;using System.Linq;
using System.Web.Http;
using System.Web.Http.OData;
using FizzWare.NBuilder;
using KendoGridWebApiOdata.Models;
&lt;p&gt;namespace KendoGridWebApiOdata.Controllers
{
public class CatsController : ODataController
{
[Queryable]
public IQueryable&amp;lt;Cat&amp;gt; Get()
{
return BuildTestData();
}&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    private IQueryable&amp;amp;lt;Cat&amp;amp;gt; BuildTestData()
    {
        return Builder&amp;amp;lt;Cat&amp;amp;gt;
            .CreateListOfSize(100)
            .Build()
            .AsQueryable();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Here, I've got a CatsController inheriting from the ODataController.  I also have a [Queryable] attribute over the Get() action method.  This is another piece you supposedly need, and this was used in the older version of the Web API OData NuGet package, but I found my grid worked whether the attribute was on there or not.  You will likely want to leave it as &lt;a href="http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-security-guidance"&gt;a place to lock down incoming requests&lt;/a&gt;, since this is where you can disallow certain query parameters, limit records returned, etc.&lt;/p&gt;
&lt;p&gt;The BuildTestData() method is using &lt;a href="http://nbuilder.org/"&gt;NBuilder&lt;/a&gt; to crank out 100 Cat entities and pretend like it's queryable.&lt;/p&gt;
&lt;h2 id="test-it-out"&gt;Test it out&lt;/h2&gt;
&lt;p&gt;That should do it for the server side.  Let's test the route setup and see if we get data back.  I like using the Chrome plugin &lt;a href="https://www.google.com/url?sa=t&amp;amp;rct=j&amp;amp;q=&amp;amp;esrc=s&amp;amp;source=web&amp;amp;cd=1&amp;amp;cad=rja&amp;amp;ved=0CEMQFjAA&amp;amp;url=https%3A%2F%2Fchrome.google.com%2Fwebstore%2Fdetail%2Fadvanced-rest-client%2Fhgmloofddffdnphfgcellkdfbfbjeloo%3Fhl%3Den-US&amp;amp;ei=3UMkUe2rOZHtqAGi4YC4Ag&amp;amp;usg=AFQjCNEkroM42vfwzL0_5_3WgPLuFCnAZg"&gt;Advanced REST Client&lt;/a&gt;, but since we're testing GET requests, you can also just type the URL in your browser.&lt;/p&gt;
&lt;p&gt;For the URL &lt;code&gt;/api/Cats&lt;/code&gt;, the JSON coming back looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-json"&gt;{
  &amp;quot;odata.metadata&amp;quot;: &amp;quot;http://localhost:56126/api/$metadata#Cats&amp;quot;,
  &amp;quot;value&amp;quot;: [
    {
      &amp;quot;Id&amp;quot;: 1,
      &amp;quot;Name&amp;quot;: &amp;quot;Name1&amp;quot;,
      &amp;quot;Color&amp;quot;: &amp;quot;Color1&amp;quot;
    },
    {
      &amp;quot;Id&amp;quot;: 2,
      &amp;quot;Name&amp;quot;: &amp;quot;Name2&amp;quot;,
      &amp;quot;Color&amp;quot;: &amp;quot;Color2&amp;quot;
    },
  ...]}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To add some OData parameters to the URL, let's try &lt;code&gt;/api/Cats?$inlinecount=allpages&lt;/code&gt;.  Now the JSON has &lt;code&gt;odata.count&lt;/code&gt; for the &lt;code&gt;$inlinecount&lt;/code&gt; value:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-json"&gt;{
  &amp;quot;odata.metadata&amp;quot;: &amp;quot;http://localhost:56126/api/$metadata#Cats&amp;quot;,
  &amp;quot;odata.count&amp;quot;: &amp;quot;100&amp;quot;,
  &amp;quot;value&amp;quot;: [
    {
      &amp;quot;Id&amp;quot;: 1,
      &amp;quot;Name&amp;quot;: &amp;quot;Name1&amp;quot;,
      &amp;quot;Color&amp;quot;: &amp;quot;Color1&amp;quot;
    },
    {
      &amp;quot;Id&amp;quot;: 2,
      &amp;quot;Name&amp;quot;: &amp;quot;Name2&amp;quot;,
      &amp;quot;Color&amp;quot;: &amp;quot;Color2&amp;quot;
    },
...]}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;See how the records are coming across in the &lt;code&gt;value&lt;/code&gt; array?  We'll need that and the &lt;code&gt;odata.count&lt;/code&gt; to help the grid know how to parse this JSON.&lt;/p&gt;
&lt;h2 id="client-side"&gt;Client side&lt;/h2&gt;
&lt;p&gt;The HTML for the grid is minimal:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;div id=&amp;quot;grid&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the JavaScript isn't bad:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;$(function () {
    var dataSource = new kendo.data.DataSource({
        type: &amp;quot;odata&amp;quot;,
        transport: {
            read: {
                url: &amp;quot;/api/Cats&amp;quot;,
                dataType: &amp;quot;json&amp;quot;
            },
        },
        schema: {
            data: function (data) {
                return data[&amp;quot;value&amp;quot;];
            },
            total: function (data) {
                return data[&amp;quot;odata.count&amp;quot;];
            },
            model: {
                fields: {
                    Id: { type: &amp;quot;number&amp;quot; },
                    Name: { type: &amp;quot;string&amp;quot; },
                    Color: { type: &amp;quot;string&amp;quot; }
                }
            }
        },
        pageSize: 10,
        serverPaging: true,
        serverFiltering: true,
        serverSorting: true
    });
&lt;pre&gt;&lt;code&gt;$(&amp;amp;quot;#grid&amp;amp;quot;).kendoGrid({
    dataSource: dataSource,
    filterable: true,
    sortable: true,
    pageable: true,
    columns: [
        { field: &amp;amp;quot;Id&amp;amp;quot; },
        { field: &amp;amp;quot;Name&amp;amp;quot; },
        { field: &amp;amp;quot;Color&amp;amp;quot; }
    ]
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;});
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;In the dataSource variable, we're setting the type as &lt;code&gt;odata&lt;/code&gt;.  Seems like that would be enough, but you have to also set the read transport's dataType to &amp;quot;json&amp;quot; or your request will go to the server like &lt;code&gt;/api/Cats?$callback=jQuery183021786115039139986_1361332885733&amp;amp;amp;$inlinecount=allpages&amp;amp;amp;$format=json&amp;amp;amp;$top=10&lt;/code&gt;.  This is a JSONP request.  We want the &lt;code&gt;$callback&lt;/code&gt; and &lt;code&gt;$format&lt;/code&gt; parameters to go away, and setting the dataType to &amp;quot;json&amp;quot; does that and sets the request's Accept headers to &amp;quot;application/json&amp;quot;.&lt;/p&gt;
&lt;p&gt;There is also some extra stuff going on in the schema section.  Normally, this is where you tell Kendo UI what your data types are so it can sort and filter correctly.  Here, we've added data and total to pull the values out of the JSON response so the grid needs can render correctly.  The data function is returning the &lt;code&gt;value&lt;/code&gt; from the JSON we saw above, and the total function is returning the &lt;code&gt;odata.count&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The rest of the dataSource properties are to force things to be done server side and to set the page size.  The remainder of the JavaScript is firing up the grid with this dataSource and setting properties of the grid.&lt;/p&gt;
&lt;p&gt;When you run this, you get a Kendo UI grid working with server-side OData.  In this case, only 10 records are sent per request instead of the 100 Cat records we created on the server.  The OData handling works with sorting, filtering, and paging on the grid.&lt;/p&gt;
&lt;p&gt;If you get it running on your machine, check the XHRs to see the OData query string parameters getting added to the request and the response coming back with just the records requested.&lt;/p&gt;
&lt;h2 id="other-nifty-things"&gt;Other nifty things&lt;/h2&gt;
&lt;p&gt;You can hit a URL to get the schemas of the entities you can query with &lt;code&gt;/api/$metadata&lt;/code&gt;.  You'll get back some XML like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-xml"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;
&amp;lt;edmx:Edmx Version=&amp;quot;1.0&amp;quot;&amp;gt;
 &amp;lt;edmx:DataServices m:DataServiceVersion=&amp;quot;3.0&amp;quot; m:MaxDataServiceVersion=&amp;quot;3.0&amp;quot;&amp;gt;
   &amp;lt;Schema Namespace=&amp;quot;KendoGridWebApiOdata.Models&amp;quot;&amp;gt;
     &amp;lt;EntityType Name=&amp;quot;Cat&amp;quot;&amp;gt;
      &amp;lt;Key&amp;gt;
        &amp;lt;PropertyRef Name=&amp;quot;Id&amp;quot; /&amp;gt;
      &amp;lt;/Key&amp;gt;
      &amp;lt;Property Name=&amp;quot;Id&amp;quot; Type=&amp;quot;Edm.Int32&amp;quot; Nullable=&amp;quot;false&amp;quot; /&amp;gt;
      &amp;lt;Property Name=&amp;quot;Name&amp;quot; Type=&amp;quot;Edm.String&amp;quot; /&amp;gt;
      &amp;lt;Property Name=&amp;quot;Color&amp;quot; Type=&amp;quot;Edm.String&amp;quot; /&amp;gt;
     &amp;lt;/EntityType&amp;gt;
     &amp;lt;EntityType Name=&amp;quot;Dog&amp;quot;&amp;gt;
      &amp;lt;Key&amp;gt;
        &amp;lt;PropertyRef Name=&amp;quot;Id&amp;quot; /&amp;gt;
      &amp;lt;/Key&amp;gt;
      &amp;lt;Property Name=&amp;quot;Id&amp;quot; Type=&amp;quot;Edm.Int32&amp;quot; Nullable=&amp;quot;false&amp;quot; /&amp;gt;
      &amp;lt;Property Name=&amp;quot;Name&amp;quot; Type=&amp;quot;Edm.String&amp;quot; /&amp;gt;
      &amp;lt;Property Name=&amp;quot;Color&amp;quot; Type=&amp;quot;Edm.String&amp;quot; /&amp;gt;
     &amp;lt;/EntityType&amp;gt;
   &amp;lt;/Schema&amp;gt;
  &amp;lt;Schema Namespace=&amp;quot;Default&amp;quot;&amp;gt;
     &amp;lt;EntityContainer Name=&amp;quot;Container&amp;quot; m:IsDefaultEntityContainer=&amp;quot;true&amp;quot;&amp;gt;
      &amp;lt;EntitySet Name=&amp;quot;Cats&amp;quot; EntityType=&amp;quot;KendoGridWebApiOdata.Models.Cat&amp;quot; /&amp;gt;
      &amp;lt;EntitySet Name=&amp;quot;Dogs&amp;quot; EntityType=&amp;quot;KendoGridWebApiOdata.Models.Dog&amp;quot; /&amp;gt;
     &amp;lt;/EntityContainer&amp;gt;
  &amp;lt;/Schema&amp;gt;
 &amp;lt;/edmx:DataServices&amp;gt;
&amp;lt;/edmx:Edmx&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you are worried about exposing your data online, read up on &lt;a href="http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-security-guidance"&gt;OData Security Guidance&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="limitations"&gt;Limitations&lt;/h2&gt;
&lt;p&gt;URLs are case sensitive.  If you browse to &lt;code&gt;/api/Cats&lt;/code&gt;, you get data.  If you browse to &lt;code&gt;/api/cats&lt;/code&gt; (lower case &lt;code&gt;C&lt;/code&gt;), you get a 406 error.&lt;/p&gt;
&lt;p&gt;Kendo UI grid allows sorting by more than one column, but the current Web API OData implementation doesn't seem to support it.&lt;/p&gt;
&lt;h2 id="download"&gt;Download&lt;/h2&gt;
&lt;p&gt;You can &lt;a href="https://github.com/VolareSoftware/KendoGridWebApiOdata"&gt;download the code for this project from GitHub&lt;/a&gt;.&lt;/p&gt;
</description>
      <pubDate>Tue, 19 Feb 2013 13:48:00 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/convert-callback-javascript-to-async-await</guid>
      <link>https://volaresoftware.com/en/technical-posts/convert-callback-javascript-to-async-await</link>
      <title>Convert callback JavaScript to async/await</title>
      <description>&lt;p&gt;If you've done much JavaScript, you've run into the &lt;code&gt;.done()&lt;/code&gt; and &lt;code&gt;.then()&lt;/code&gt; callback functions, where your code is executed AFTER an asynchronous call completes.&lt;/p&gt;
&lt;p&gt;Here, &lt;code&gt;myFunction(myParams)&lt;/code&gt; calls &lt;code&gt;makeXhrCall(myParams)&lt;/code&gt;, an asynchronous XHR API call (the most common type of asynchronous call you will run into). The &lt;code&gt;.then()&lt;/code&gt; function waits for the XHR call to complete. When it does, the XHR call returns &lt;code&gt;data&lt;/code&gt;, which is used inside the &lt;code&gt;.then()&lt;/code&gt; function to call another function, &lt;code&gt;doSomething(data)&lt;/code&gt;. The result of the &lt;code&gt;doSomething(data)&lt;/code&gt; call gets returned out to whoever called the outer function when it's done.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;myFunction(myParams) {
    return makeXhrCall(myParams)
        .then(data =&amp;gt;
            doSomething(data)
        );
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The key thing is, you are using &lt;code&gt;.then()&lt;/code&gt; as a hook to do more work when the asynchronous call completes.&lt;/p&gt;
&lt;p&gt;For a while now, &lt;a href="https://caniuse.com/#feat=async-functions"&gt;you've been able to use &lt;code&gt;async&lt;/code&gt;/&lt;code&gt;await&lt;/code&gt;&lt;/a&gt; syntax as a way to treat asynchronous functions as synchronous, meaning no code AFTER the XHR call executes until the line with the &lt;code&gt;await&lt;/code&gt; has completed executing.&lt;/p&gt;
&lt;p&gt;If you are new to JavaScript, it can be confusing that making asynchronous calls leaves other lines of code UNDER that asynchronous call executing while the asynchronous call is still running. Changing to &lt;code&gt;async&lt;/code&gt;/&lt;code&gt;await&lt;/code&gt; makes your code clearer because each step is followed in top-down sequence.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;async myFunction(myParams) {
    const data = await makeXhrCall(myParams);
    return doSomething(data);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;async&lt;/code&gt; keyword tells JavaScript, &amp;quot;this code is going to use &lt;code&gt;await&lt;/code&gt; at least once&amp;quot;. Then you add &lt;code&gt;await&lt;/code&gt; right before the asynchronous call.  Now the &lt;code&gt;data&lt;/code&gt; won't have a value until the XHR completes, and &lt;code&gt;doSomething(data)&lt;/code&gt; won't run until the line with the &lt;code&gt;await&lt;/code&gt; has finished putting a value in &lt;code&gt;data&lt;/code&gt;.&lt;/p&gt;
</description>
      <pubDate>Sun, 09 Dec 2018 11:40:03 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/comparison-of-typemock-isolator-and-rhino-mocks</guid>
      <link>https://volaresoftware.com/en/technical-posts/comparison-of-typemock-isolator-and-rhino-mocks</link>
      <title>Comparison of Typemock Isolator and Rhino Mocks</title>
      <description>&lt;p&gt;I just started a new project using &lt;a href="http://learn.typemock.com/typemock-isolator/"&gt;Typemock Isolator&lt;/a&gt;.  It's a new tool for me, and since I've mostly used &lt;a href="http://www.ayende.com/projects/rhino-mocks.aspx"&gt;Rhino Mocks&lt;/a&gt;, my learning is from the perspective of &amp;quot;how do you do this with Rhino Mocks&amp;quot;.  These are the differences I see so far.&lt;/p&gt;
&lt;h2 id="general"&gt;General&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Typemock Isolator is a commercial product.  Rhino Mocks is free and open source.  Here's the &lt;a href="http://learn.typemock.com/buy/"&gt;Typemock pricing&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Typemock Isolator can mock just about anything, including not normally mockable things like private methods, static methods, and sealed classes.  Rhino Mocks has traditional mocking from an interface, abstract class, etc.  There has been &lt;a href="http://colinjack.blogspot.com/2007/05/typemock-rhinomocks-designing-for.html"&gt;some hand-wringing&lt;/a&gt;about whether or not Typemock was &lt;em&gt;too&lt;/em&gt; powerful and encouraged untestable software designs.  But I think it's uncommon to create a brand-new stand-alone project, at least in enterprise development.  So you're probably dealing with at least &lt;em&gt;some&lt;/em&gt; code that wasn't written with testing in mind.  You can wrap those static classes and create new default constructors and all kinds of OO jujutsu.  Or you can just leave it alone and mock it as-is with Typemock.&lt;/li&gt;
&lt;li&gt;With Typemock Isolator, everything starts with &amp;quot;Isolate&amp;quot; call.  That's hard to beat for simplicity and discoverability.  You can also use the AAA style syntax.  Rhino Mocks also has AAA style testing in the newer versions.  But there has been some confusion (at least in my mind) over the main entry points, like &lt;code&gt;MockRepository.GenerateMock&amp;lt;ISomeClass&amp;gt;()&lt;/code&gt; and &lt;code&gt;MockRepository.GenerateStub&amp;lt;ISomeClass&amp;gt;()&lt;/code&gt;.  &lt;a href="http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/10/05/three-simple-rhino-mocks-rules.aspx"&gt;Once you understand it, you're all set&lt;/a&gt;, but it's kind of a stumbling block for people new to Rhino Mocks.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;OK, let's move on to other syntax differences.  I grouped these by AAA style (arrange, act, assert).  Since the &amp;quot;act&amp;quot; step should be invoking your system under test, the frameworks should look the same there.  They differ in the setup syntax (arrange) and the verify syntax (assert).&lt;/p&gt;
&lt;h2 id="arrange-syntax"&gt;Arrange Syntax&lt;/h2&gt;
&lt;h3 id="simple-mocking"&gt;Simple mocking&lt;/h3&gt;
&lt;p&gt;For simple mock objects, Typemock uses this syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;// Arrange
var repository = Isolate.Fake.Instance&amp;lt;IContactRepository&amp;gt;();
var contact = new Contact(repository);
&lt;p&gt;// Act
contact.DoSomethingThatUsesARepository();
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;as compared to the Rhino Mocks syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;// Arrange
var repository = MockRepository.GenerateStub&amp;lt;IContactRepository&amp;gt;();
var contact = new Contact(repository);
&lt;p&gt;// Act
contact.DoSomethingThatUsesARepository();
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Not much here.  Just different ways to do the same thing.&lt;/p&gt;
&lt;h3 id="argument-handling"&gt;Argument handling&lt;/h3&gt;
&lt;p&gt;Method call arguments are ignored by default in Typemock, so you don't have quite as much setup to get to the system under test.  You still need to put the correct type in the argument, but it can be null, string.Empty, 0, etc.&lt;/p&gt;
&lt;p&gt;With Rhino Mocks, you have to be explicit when arguments don't matter:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;theClass.Expect(x =&amp;gt; x.theMethod(null)).IgnoreArguments();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or you can use the newer, more readable but maybe more typing Rhino Mocks syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;theClass.Expect(x =&amp;gt; x.theMethod(Arg&amp;lt;theArgument&amp;gt;.Is.Anything));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In Typemock, you use this syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;Isolate.WhenCalled(() =&amp;gt; theClass.theMethod(theArgument)).WithExactArguments();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;only if the arguments &lt;em&gt;are&lt;/em&gt; important to you.&lt;/p&gt;
&lt;p&gt;So you can ignore arguments or use specific arguments with either framework.  They differ on the default setting.&lt;/p&gt;
&lt;h3 id="unmockable-mocking"&gt;Unmockable mocking&lt;/h3&gt;
&lt;p&gt;In Typemock, you can also ignore calls on &amp;quot;live&amp;quot; methods (real instances, not fakes, stubs, or mocks) with:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;Isolate.WhenCalled(() =&amp;gt; theClass.theMethod(theArgument)).IgnoreCall();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The only way to not call into live code with Rhino Mocks that I'm aware of is to use a stub.  This is the traditional testing approach that injects a stubbed dependency into the class under test.&lt;/p&gt;
&lt;p&gt;So let's assume I need to test a Contact class method that does some stuff and then sends an email using EmailService, but I don't want an email to actually go out.  Here's the Typemock arrange and act:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;// Arrange
var emailService = new EmailService();
var contact = new Contact(emailService);
Isolate.WhenCalled(() =&amp;gt; emailService.SendContactInfoToSales(contact)).IgnoreCall();
&lt;p&gt;// Act
contact.DoSomethingThatSendsAnEmail();
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;And the Rhino Mocks arrange and act:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;// Arrange
var emailService = MockRepository.GenerateStub&amp;lt;IEmailService&amp;gt;();
var contact = new Contact(emailService);
&lt;p&gt;// Act
contact.DoSomethingThatSendsAnEmail();
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;For the Rhino Mocks approach, my EmailService has to be mockable.  Again, you can write code to do that, and in this sample I am using an interface to EmailService to do that.  But with Typemock, you just tell the test to ignore that call.  You don't need to write more code to make the EmailService test-friendly.&lt;/p&gt;
&lt;p&gt;Suppose EmailService is in some company-owned assembly you have to use and it's a sealed class.  Yes, you can wrap it with an interface, but why not just tell it to skip email sending with Typemock.  That's pretty powerful.  You can focus on the new code you want to test instead of refactoring existing code you don't really care about but are dependent on.&lt;/p&gt;
&lt;h3 id="simulating-exceptions"&gt;Simulating Exceptions&lt;/h3&gt;
&lt;p&gt;Another cool Typemock thing you can do is force existing code to throw an exception so you can test the robustness of your code.  What if I want to make sure my new code works OK if the mail relay is down on that legacy, sealed EmailService:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;Isolate.WhenCalled(() =&amp;gt; emailService.SendContactInfoToSales(contact)).WillThrow(new SmtpException());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can do the same thing in Rhino Mocks.  Again, just different syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;emailService.Expect(x =&amp;gt; x.SendContactInfoToSales(contact)).Throw(new SmtpException());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I think you would still need to have a mock on an IEmailService to do this with Rhino Mocks.  The Typemock advantage is that it can work around that sealed class.&lt;/p&gt;
&lt;h2 id="assert-syntax"&gt;Assert Syntax&lt;/h2&gt;
&lt;h3 id="simple-verifications"&gt;Simple verifications&lt;/h3&gt;
&lt;p&gt;The interaction testing assert syntax for Rhino Mocks is:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;// Assert
emailService.AssertWasCalled(x =&amp;gt; x.SendContactInfoToSales(null), opt =&amp;gt; opt.IgnoreArguments());
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And for Typemock:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;// Assert
Isolate.Verify.WasCalledWithAnyArguments(() =&amp;gt; emailService.SendContactInfoToSales(null));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is just to test that the code got to that line/made that call internally.  If you want to verify it got there &lt;em&gt;and&lt;/em&gt; arrived with your expected arguments with Rhino Mocks:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;// Assert
emailService.AssertWasCalled(x =&amp;gt; x.SendContactInfoToSales(expectedContact);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And with Typemock:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;// Assert
Isolate.Verify.WasCalled(() =&amp;gt; emailService.SendContactInfoToSales(expectedContact));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So again, both frameworks can get you either assert type, just with different syntax.&lt;/p&gt;
&lt;h2 id="wrap-up"&gt;Wrap up&lt;/h2&gt;
&lt;p&gt;The promise of Typemock Isolator is less time refactoring code that isn't on your roadmap and less setup to get to your system under test.  I've focused here mostly on the arrange syntax for that reason.&lt;/p&gt;
&lt;p&gt;Rhino Mocks can do most of the stuff Typemock can, except for the private, sealed, and static testing.  Some would argue that you shouldn't test that code or if you need to make it testable, you should refactor it anyway.&lt;/p&gt;
&lt;p&gt;Maybe.  But it's also pretty appealing to keep your coding and tests focused on your project mandate, too.&lt;/p&gt;
</description>
      <pubDate>Fri, 16 Oct 2009 00:41:21 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/optimizing-javascript-and-css-files-using-requirejs-and-r-js-in-an-asp-net-mvc-app</guid>
      <link>https://volaresoftware.com/en/technical-posts/optimizing-javascript-and-css-files-using-requirejs-and-r-js-in-an-asp-net-mvc-app</link>
      <title>Optimizing JavaScript and CSS files using RequireJS and R.js in an ASP.NET MVC app</title>
      <description>&lt;p&gt;In my previous blog post, we discussed &lt;a href="https://volaresoftware.com/en/technical-posts/adding-requirejs-to-an-aspnet-mvc-project"&gt;setting up RequireJS for a multi-page ASP.NET MVC app&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;a href="https://github.com/VolareSoftware/RequireJSWithMVC"&gt;code for the reference app&lt;/a&gt; is on GitHub, and when run, it shows us loading seven JavaScript files (409 KB) and four CSS files (31.1 KB):&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/optimize_before_js.png" alt="Optimize Before JS" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/optimize_before_css.png" alt="Optimize Before CSS" /&gt;&lt;/p&gt;
&lt;p&gt;We know we can reduce the number of HTTP requests, and reduce network traffic, if we can load fewer files and smaller files at run time.&lt;/p&gt;
&lt;p&gt;There are several ways to do this bundling and minification: use &lt;a href="https://volaresoftware.com/en/technical-posts/combining-javascript-bundling-minification-cache-busting-and-easier-debugging"&gt;MVC's built in tools&lt;/a&gt;, use &lt;a href="http://vswebessentials.com/"&gt;Web Essentials&lt;/a&gt;, or use &lt;a href="http://requirejs.org/docs/optimization.html"&gt;r.js&lt;/a&gt;, the tool that comes with &lt;a href="http://requirejs.org/"&gt;RequireJS&lt;/a&gt;.  The advantage of the later is you can let RequireJS, which is already tracking your dependency graph, decide which files should be bundled together for a specific page.&lt;/p&gt;
&lt;p&gt;You can also use r.js to bundle ALL the scripts in your project together, and for a single-page app, that may make sense.  But for a multi-page app, you want to have a common set of scripts you need on most pages, and an a la cart bundle for each page.  We'll focus on the later here.&lt;/p&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites&lt;/h2&gt;
&lt;p&gt;You'll need to download r.js, which comes in the &lt;a href="http://www.nuget.org/packages/RequireJS/2.1.11"&gt;RequireJS nuget package&lt;/a&gt;, and you'll need a local version of &lt;a href="http://nodejs.org/download/"&gt;Node&lt;/a&gt; running.&lt;/p&gt;
&lt;p&gt;You'll also likely want to do this optimization only in Release mode, so be sure your project has a Debug and a Release build config.&lt;/p&gt;
&lt;h2 id="what-to-bundle-for-javascript"&gt;What to bundle for JavaScript?&lt;/h2&gt;
&lt;p&gt;Here are the JavaScript files we have to work with:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/optimize_what_to_bundle_js.png" alt="What to bundle JS" /&gt;&lt;/p&gt;
&lt;p&gt;We want page-level bundles, so we can load require.js, then main.js (including common libraries and kickoff.js), then main-currentDateTime.js and anything it needs that we haven't already loaded.&lt;/p&gt;
&lt;p&gt;I usually name the main-*.js file as the name of the main MVC view or controller/action being pulled up on the screen.  Theses main-*.js files are the entry point for firing up the JavaScript for just that page.&lt;/p&gt;
&lt;h2 id="what-to-bundle-for-css"&gt;What to bundle for CSS?&lt;/h2&gt;
&lt;p&gt;We have three CSS files we can combine and a main.css file that references them:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/optimize_what_to_bundle_css.png" alt="What to bundel CSS" /&gt;&lt;/p&gt;
&lt;p&gt;The main.css file uses import statements for the three style sheets:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-css"&gt;/* 3rd party stylesheets */
@import url(&amp;quot;lib/bootstrap.css&amp;quot;);
@import url(&amp;quot;lib/bootstrap-theme.css&amp;quot;);
&lt;p&gt;/* Application stylesheets */
@import url(&amp;quot;app/site.css&amp;quot;);
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;This is usually a no-no for web development, because now there is a fourth style sheet, and a fourth HTTP request as the browser loads main.css, then turns around and loads the three style sheets it wants us to load.  In this case, I think it's fine since this will be the way it works in Debug mode when you are working locally.  When you go to Release mode, everything in main.css will be bundled and combined into one file.&lt;/p&gt;
&lt;p&gt;Now change the link in the _Layout.cshtml file to point to main.css:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;link href=&amp;quot;~/Styles/main.css&amp;quot; rel=&amp;quot;stylesheet&amp;quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;TIP: Be sure your CSS files are listed in main.css in the order in which you want them to override, with your app styles at the bottom.  The last ones listed will take precedence.&lt;/p&gt;
&lt;h2 id="setting-up-r.js-build-scripts.js-build-styles.js"&gt;Setting up r.js, build-scripts.js, build-styles.js&lt;/h2&gt;
&lt;p&gt;I created an App_Build folder at the solution level.  Call yours anything you like.  The point is, this is stuff for building the project, not part of the code that is deployed when running the app.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/optimize_app_build_folder.png" alt="https://cdn.volaresoftware.com/images/posts/2019/12/optimize_app_build_folder.png" /&gt;&lt;/p&gt;
&lt;p&gt;I added the r.js file and two other JavaScript files with build config settings.  One is for the JavaScript code and one is for the CSS.&lt;/p&gt;
&lt;p&gt;The JavaScript config file, &amp;quot;build-scripts.js&amp;quot;, looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;({
    appDir: &amp;quot;../Scripts&amp;quot;,
    dir: &amp;quot;../Scripts-Build&amp;quot;,
    baseUrl: &amp;quot;app&amp;quot;,
    mainConfigFile: &amp;quot;../Scripts/main.js&amp;quot;,
    paths: {
        main: &amp;quot;../main&amp;quot;
    },
    keepBuildDir: false,
    modules: [{
        name: &amp;quot;main&amp;quot;,
        include: [
            // These JS files will be on EVERY page in the main.js file
            // So they should be the files we will almost always need everywhere
            &amp;quot;domReady&amp;quot;,
            &amp;quot;jquery&amp;quot;,
            &amp;quot;jqueryValidate&amp;quot;,
            &amp;quot;jqueryValidateUnobtrusive&amp;quot;,
            &amp;quot;bootstrap&amp;quot;,
            &amp;quot;moment&amp;quot;
        ]
    },
    // These are page-specific bundles, usually named main-*
    { name: &amp;quot;main-currentDateTime&amp;quot;, exclude: [&amp;quot;main&amp;quot;] }
    ],
    onBuildRead: function (moduleName, path, contents) {
        if (moduleName === &amp;quot;main&amp;quot;) {
            return contents.replace(&amp;quot;Scripts&amp;quot;, &amp;quot;Scripts-Build&amp;quot;);
        }
        return contents;
    }
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Most of the paths are relative to the r.js file.  The appDir is the main folder, so the appDir plus the baseUrl is the /Scripts/app folder.  The dir setting is where you want the built scripts to go.  The mainConfigFile is the path to main.js.&lt;/p&gt;
&lt;p&gt;The first argument in the modules section is all the code you want rolled up into main.js.  These are files used on almost every if not every page.  The next argument in modules is each page file.  Here, you need to manually add each page of your app where you want bundling.  I've only got one page/bundle listed here.  RequireJS will inspect that main-*.js file, and its dependencies, and their dependencies, and so on, but it will exclude files already bundled into main.&lt;/p&gt;
&lt;p&gt;For example, the main-currentDateTime module uses &amp;quot;jquery&amp;quot;.  That file is already included in main.js in these build instructions, so it won't be bundled into main-currentDateTime.&lt;/p&gt;
&lt;p&gt;The onBuildRead stuff is for swapping out paths in the built scripts.  More on that down below.&lt;/p&gt;
&lt;p&gt;The CSS config file, &amp;quot;build-styles.js&amp;quot;, looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;({
    keepBuildDir: false,
    optimizeCss: &amp;quot;standard&amp;quot;,
    cssIn: &amp;quot;../Styles/main.css&amp;quot;,
    out: &amp;quot;../Styles-Build/main.css&amp;quot;
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The main configuration settings as the cssIn folder, where the code to bundle comes from, and the out folder, where it's going.&lt;/p&gt;
&lt;p&gt;In both cases, we're outputting to new folders that are cleaned out on every Release build, /Scripts-Build and /Styles-Build.&lt;/p&gt;
&lt;h2 id="bundling-and-minifying-on-release-build"&gt;Bundling and minifying on Release build&lt;/h2&gt;
&lt;p&gt;Open the web project Properties and select Build Events.  In the Pre-build event command line, add:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;if $(ConfigurationName) == Release node &amp;quot;$(ProjectDir)App_Build\r.js&amp;quot; -o &amp;quot;$(ProjectDir)App_Build\build-scripts.js&amp;quot;
if $(ConfigurationName) == Release node &amp;quot;$(ProjectDir)App_Build\r.js&amp;quot; -o &amp;quot;$(ProjectDir)App_Build\build-styles.js&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note the call to execute r.js with Node.  You must have Node set up in your Paths on your machine for this to work.  Now the build scripts will run every time the build is executed in Release mode.&lt;/p&gt;
&lt;p&gt;Change your build configuration to Release mode and build the app.  If it worked, the output window should show:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;1&amp;gt;------ Build started: Project: RequireJSWithMVC, Configuration: Release Any CPU ------
1&amp;gt;  
1&amp;gt;  Tracing dependencies for: main
1&amp;gt;  
1&amp;gt;  Tracing dependencies for: main-currentDateTime
1&amp;gt;  Uglifying file: C:/RequireJSWithMVC/Scripts-Build/app/currentDateTime.js
1&amp;gt;  Uglifying file: C:/RequireJSWithMVC/Scripts-Build/app/kickoff.js
1&amp;gt;  Uglifying file: C:/RequireJSWithMVC/Scripts-Build/app/main-currentDateTime.js
1&amp;gt;  Uglifying file: C:/RequireJSWithMVC/Scripts-Build/lib/bootstrap.js
1&amp;gt;  Uglifying file: C:/RequireJSWithMVC/Scripts-Build/lib/domReady.js
1&amp;gt;  Uglifying file: C:/RequireJSWithMVC/Scripts-Build/lib/jquery-2.1.1.js
1&amp;gt;  Uglifying file: C:/RequireJSWithMVC/Scripts-Build/lib/jquery.validate.js
1&amp;gt;  Uglifying file: C:/RequireJSWithMVC/Scripts-Build/lib/jquery.validate.unobtrusive.js
1&amp;gt;  Uglifying file: C:/RequireJSWithMVC/Scripts-Build/lib/moment.js
1&amp;gt;  Uglifying file: C:/RequireJSWithMVC/Scripts-Build/lib/require.js
1&amp;gt;  Uglifying file: C:/RequireJSWithMVC/Scripts-Build/main.js
1&amp;gt;  
1&amp;gt;  main.js
1&amp;gt;  ----------------
1&amp;gt;  app/kickoff.js
1&amp;gt;  main.js
1&amp;gt;  lib/domReady
1&amp;gt;  lib/jquery-2.1.1.js
1&amp;gt;  lib/jquery.validate.js
1&amp;gt;  lib/jquery.validate.unobtrusive.js
1&amp;gt;  lib/bootstrap.js
1&amp;gt;  lib/moment.js
1&amp;gt;  
1&amp;gt;  app/main-currentDateTime.js
1&amp;gt;  ----------------
1&amp;gt;  app/main-currentDateTime.js
1&amp;gt;  
1&amp;gt;  
1&amp;gt;  C:/RequireJSWithMVC/Styles-Build/main.css
1&amp;gt;  ----------------
1&amp;gt;  C:/RequireJSWithMVC/Styles/lib/bootstrap.css
1&amp;gt;  C:/RequireJSWithMVC/Styles/lib/bootstrap-theme.css
1&amp;gt;  C:/RequireJSWithMVC/Styles/app/site.css
1&amp;gt;  C:/RequireJSWithMVC/Styles/main.css
1&amp;gt;  
1&amp;gt;  RequireJSWithMVC -&amp;gt; C:\RequireJSWithMVC\bin\RequireJSWithMVC.dll
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;r.js does a nice job of reporting back what it's done.  Here, you can see it traces dependencies, minifies (uglifies) every JavaScript file, then it reports the files it bundled for main.js, main-currentDateTime.js, and main.css.&lt;/p&gt;
&lt;p&gt;You should be able to show hidden files in Visual Studio and see the new folders and their files.  Open them up and look at the minification changes&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/optimize_built_folders.png" alt="https://cdn.volaresoftware.com/images/posts/2019/12/optimize_built_folders.png" /&gt;&lt;/p&gt;
&lt;h2 id="dealing-with-paths-with-mvc-helpers"&gt;Dealing with paths with MVC Helpers&lt;/h2&gt;
&lt;p&gt;So great!  We've got the files we want in /Scripts-Build and /Styles-Build.  Unfortunately, our code is still pointing to /Scripts and /Styles.  We can fix this with some MVC Helpers.&lt;/p&gt;
&lt;p&gt;Looking at our _Layout.cshtml, we'll need to fix the path to the stylesheets and the path to require.js,:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    …
    &amp;lt;link href=&amp;quot;~/Styles/main.css&amp;quot; rel=&amp;quot;stylesheet&amp;quot; /&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    …
    &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;
        @RenderBody()
    &amp;lt;/div&amp;gt;
&lt;pre&gt;&lt;code&gt;&amp;amp;lt;script src=&amp;amp;quot;/Scripts/lib/require.js&amp;amp;quot;&amp;amp;gt;&amp;amp;lt;/script&amp;amp;gt;
@RenderSection(&amp;amp;quot;scripts&amp;amp;quot;, required: false)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Here's the C# for the stylesheet and scripts PathHelpers.cs:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;using System.Web;
using System.Web.Mvc;
&lt;p&gt;namespace RequireJSWithMVC.Extensions
{
public static class PathHelpers
{
public static string ScriptsPath(this HtmlHelper helper, string pathWithoutScripts)
{
#if (DEBUG)
var scriptsPath = &amp;quot;&lt;sub&gt;/Scripts/&amp;quot;;
#else
var scriptsPath = &amp;quot;&lt;/sub&gt;/Scripts-Build/&amp;quot;;
#endif&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;        return VirtualPathUtility.ToAbsolute(scriptsPath + pathWithoutScripts);
    }

    public static string StylesPath(this HtmlHelper helper, string pathWithoutStyles)
    {
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;#if (DEBUG)
var stylesPath = &amp;quot;&lt;sub&gt;/Styles/&amp;quot;;
#else
var stylesPath = &amp;quot;&lt;/sub&gt;/Styles-Build/&amp;quot;;
#endif
return VirtualPathUtility.ToAbsolute(stylesPath + pathWithoutStyles);
}
}
}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Now our _Layout.cshtml can be update to this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;@using RequireJSWithMVC.Extensions
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    ...
    &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;@Html.StylesPath(&amp;quot;main.css&amp;quot;)&amp;quot; /&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    ...
    &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;
        @RenderBody()
    &amp;lt;/div&amp;gt;
&lt;pre&gt;&lt;code&gt;&amp;amp;lt;script src=&amp;amp;quot;@Html.ScriptsPath(&amp;amp;quot;lib/require.js&amp;amp;quot;)&amp;amp;quot;&amp;amp;gt;&amp;amp;lt;/script&amp;amp;gt;
@RenderSection(&amp;amp;quot;scripts&amp;amp;quot;, required: false)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;We still need to fix the paths within each page.  They still point to the /Scripts folder and need to point to /Scripts-Build in Release mode.  Let's do that by updating our RequireJsHelper.cs from the last post:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;using System;
using System.Text;
using System.Web;
using System.Web.Mvc;
&lt;p&gt;namespace RequireJSWithMVC.Extensions
{
public static class RequireJsHelpers
{
public static MvcHtmlString InitPageMainModule(this HtmlHelper helper, string pageModule)
{
var require = new StringBuilder();&lt;/p&gt;
&lt;p&gt;#if (DEBUG)
var scriptsPath = &amp;quot;&lt;sub&gt;/Scripts/&amp;quot;;
#else
var scriptsPath = &amp;quot;&lt;/sub&gt;/Scripts-Build/&amp;quot;;
#endif&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;        var absolutePath = VirtualPathUtility.ToAbsolute(scriptsPath);

        require.AppendLine(&amp;amp;quot;&amp;amp;lt;script&amp;amp;gt;&amp;amp;quot;);
        require.AppendFormat(&amp;amp;quot;    require([\&amp;amp;quot;{0}main.js\&amp;amp;quot;],&amp;amp;quot; + Environment.NewLine, absolutePath);
        require.AppendLine(&amp;amp;quot;        function() {&amp;amp;quot;);
        require.AppendFormat(&amp;amp;quot;            require([\&amp;amp;quot;{0}\&amp;amp;quot;, \&amp;amp;quot;domReady!\&amp;amp;quot;]);&amp;amp;quot; + Environment.NewLine, pageModule);
        require.AppendLine(&amp;amp;quot;        }&amp;amp;quot;);
        require.AppendLine(&amp;amp;quot;    );&amp;amp;quot;);
        require.AppendLine(&amp;amp;quot;&amp;amp;lt;/script&amp;amp;gt;&amp;amp;quot;);

        return new MvcHtmlString(require.ToString());
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Both of these helpers rely on the compiler flag for debug.  If you don't like that, you could always branch off an Environment key in appSettings in your web.config or something.&lt;/p&gt;
&lt;p&gt;Now when the page is loaded for this app, we have three scripts and one stylesheet, so we've gone from eleven HTTP requests to four.  Furthermore, the files requested are much smaller after the minification, and we've gone from 440.1 KB to 223.3 KB total.  You could get that down even more if you removed all the license info from the minified JavaScript in the build-scripts.js config with &amp;quot;preserveLicenseComments: false&amp;quot;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/optimize_after_js.png" alt="https://cdn.volaresoftware.com/images/posts/2019/12/optimize_after_js.png" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/optimize_after_css.png" alt="https://cdn.volaresoftware.com/images/posts/2019/12/optimize_after_css.png" /&gt;&lt;/p&gt;
&lt;p&gt;Finally, your users' browsers should cache most of these files after landing on any page on your site. The files require.js, main.js, and main.css will be the same for each page.  Then the user's browser only needs to download the JavaScript for each newly browsed page.&lt;/p&gt;
</description>
      <pubDate>Thu, 29 May 2014 00:39:26 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/sessionless-mvc-without-losing-tempdata</guid>
      <link>https://volaresoftware.com/en/technical-posts/sessionless-mvc-without-losing-tempdata</link>
      <title>Sessionless MVC without losing TempData</title>
      <description>&lt;p&gt;I've blogged before about &lt;a href="https://volaresoftware.com/en/technical-posts/sessionless-mvc-3"&gt;making your MVC controllers sessionless&lt;/a&gt;.  The knock on sessionless controllers is that TempData is off the table because it uses Session as its data store.&lt;/p&gt;
&lt;p&gt;If you see the &lt;code&gt;TempData&lt;/code&gt; name and dismiss it, thinking it's another dictionary like &lt;code&gt;Session[]&lt;/code&gt; and &lt;code&gt;ViewData[]&lt;/code&gt; and you're waaaay past that since your mister type-safe, take another look.  The neat thing about &lt;code&gt;TempData&lt;/code&gt; is that it lasts for one more page load and then &amp;quot;poof&amp;quot; - it's gone.  It self destructs as soon as it has been read.&lt;/p&gt;
&lt;p&gt;Sure, it's a dictionary with magic string keys, but it's a great place to store message like &amp;quot;Your changes were saved&amp;quot; when you redirect to another page.&lt;/p&gt;
&lt;p&gt;So how do we get the benefits of &lt;code&gt;TempData&lt;/code&gt; as an ephemeral application message store, but go all-in on the web farm with sessionless controllers?&lt;/p&gt;
&lt;h2 id="cookies"&gt;Cookies!&lt;/h2&gt;
&lt;p&gt;I can hear you groaning.  Cookies are old school!  They can't hold much information!  They aren't secure!&lt;/p&gt;
&lt;p&gt;Fine, don't put much in there, and don't put your secret fried chicken recipe in there.  We're just going to use this as a little string to tell the user everything is OK or it's not OK.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;TempData&lt;/code&gt; uses a provider model for the data store, and Session is the default data store.  But you can get a cookie data store, CookieTempDataProvider, with &lt;a href="http://www.nuget.org/List/Packages/Mvc3Futures"&gt;Mvc3Futures&lt;/a&gt; NuGet package:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2011/6/image_11.png" alt="image_11.png" /&gt;&lt;/p&gt;
&lt;p&gt;This should work as a TempData provider, but now it has to be wired into the application.  Here's how you can do that:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public class BaseController : Controller
{
    protected override ITempDataProvider CreateTempDataProvider()
    {
        return new CookieTempDataProvider(HttpContext);
    }
}
&lt;/code&gt;&lt;/pre&gt;
</description>
      <pubDate>Thu, 30 Jun 2011 15:32:00 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/don-t-mock-httpcontext</guid>
      <link>https://volaresoftware.com/en/technical-posts/don-t-mock-httpcontext</link>
      <title>Don't mock HttpContext</title>
      <description>&lt;p&gt;HttpContext doesn't like to be mocked!!&lt;/p&gt;
&lt;p&gt;It's so easy to take a direct dependency on &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.httpcontext.aspx"&gt;HttpContext&lt;/a&gt; and not even realize it.  If you're in the code behind in Web Forms or in a controller action in MVC, it's just right there, tempting you to use it to access session variables, application security, etc.&lt;/p&gt;
&lt;p&gt;But don't.&lt;/p&gt;
&lt;p&gt;Some little known facts about HttpContext:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HttpContext is the largest object ever created by humans.&lt;/li&gt;
&lt;li&gt;If you printed out the code for everything in HttpContext, the pages could be stacked end to end to wrap around the Earth's equator 7 times.&lt;/li&gt;
&lt;li&gt;Mocking HttpContext is like trying to calculate the last digit of pi.  There is always a little more to it.&lt;/li&gt;
&lt;li&gt;Chuck Norris gave up trying to mock HttpContext.  He was deep in HttpContext.Response and quit, curled into a ball on the floor, and started whimpering.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="sealed-what-object-reference-what"&gt;Sealed what?  Object reference what?&lt;/h2&gt;
&lt;p&gt;Let's say you've got some MVC security stuff you're trying to work with in a controller action.  You've got code like:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public class OrderController : Controller
{
    [Authorize]
    public ActionResult Process()
    {
        if (User.IsInRole(&amp;quot;Admin&amp;quot;))
        {
            return View(&amp;quot;SecretAdminStuff&amp;quot;);
        }
&lt;pre&gt;&lt;code&gt;    return View(&amp;amp;quot;NotAuthorized&amp;amp;quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;See that &lt;code&gt;User.IsInRole()&lt;/code&gt; code?  That call is really to &lt;code&gt;HttpContext.Current.User.IsInRole()&lt;/code&gt;.  You just took the bait and are tied to &lt;code&gt;HttpContext&lt;/code&gt; now.&lt;/p&gt;
&lt;p&gt;So what? You have to use HttpContext to get that information, right?  Sure, but you don't want to be tied &lt;strong&gt;directly&lt;/strong&gt; to it or you've created untestable code.&lt;/p&gt;
&lt;p&gt;Let's try a couple tests to verify the branching in this action method is returning the correct view based on the user's role.  I'm using &lt;a href="http://www.nunit.org/"&gt;NUnit&lt;/a&gt;, &lt;a href="http://www.ayende.com/projects/rhino-mocks.aspx"&gt;Rhino Mocks&lt;/a&gt;, and the &lt;a href="http://should.codeplex.com/"&gt;Should&lt;/a&gt; assembly below.  Rhino Mocks has .Stub() and .Return() extension methods to set the expected return values for whether the user is or isn't in the Admin role.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;[Test]
public void Should_return_NotAuthorized_view_when_not_Admin_user()
{
    // Arrange
    var mockContext = MockRepository.GenerateMock&amp;lt;HttpContext&amp;gt;();
    mockContext.Stub(x =&amp;gt; x.User.IsInRole(&amp;quot;Admin&amp;quot;)).Return(false);
    var orderController = new OrderController();
&lt;pre&gt;&lt;code&gt;// Act
var result = orderController.Process() as ViewResult;

// Assert
result.ViewName.ShouldEqual(&amp;amp;quot;NotAuthorized&amp;amp;quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;[Test]
public void Should_return_SecretAdminStuff_view_when_Admin_user()
{
// Arrange
var mockContext = MockRepository.GenerateMock&amp;lt;HttpContext&amp;gt;();
mockContext.Stub(x =&amp;gt; x.User.IsInRole(&amp;quot;Admin&amp;quot;)).Return(true);
var orderController = new OrderController();&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Act
var result = orderController.Process() as ViewResult;

// Assert
result.ViewName.ShouldEqual(&amp;amp;quot;SecretAdminStuff&amp;amp;quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;As soon as we run the tests we see &amp;quot;System.NotSupportedException: Can't create mocks of sealed classes&amp;quot;.  Oh yeah, HttpContext is sealed.  That won't work.&lt;/p&gt;
&lt;p&gt;Hmmm.  Aren't there some new classes in System.Web.Abstractions for just this kind of thing?  Let's change HttpContext&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;var mockContext = MockRepository.GenerateMock&amp;lt;HttpContext&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;to &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.httpcontextbase.aspx"&gt;HttpContextBase&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;var mockContext = MockRepository.GenerateMock&amp;lt;HttpContextBase&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and see if that helps.&lt;/p&gt;
&lt;p&gt;The new problem is: &amp;quot;System.NullReferenceException: Object reference not set to an instance of an object.&amp;quot;  Mocking &lt;code&gt;HttpContextBase&lt;/code&gt; isn't helping because the test isn't passing the mock context into the controller.  Every call in the action method to &lt;code&gt;User.IsInRole()&lt;/code&gt; will always call the &lt;strong&gt;real&lt;/strong&gt; &lt;code&gt;HttpContext&lt;/code&gt;, which isn't created because the test is not running in the ASP.NET process.&lt;/p&gt;
&lt;p&gt;You can get around this with &lt;a href="http://site.typemock.com/"&gt;Typemock Isolator&lt;/a&gt;, which goes beyond mocking and can intercept the next call to &lt;code&gt;HttpContext.Current.User.IsInRole()&lt;/code&gt; and swap out a result, but isn't there a simpler way to do this without buying another product or waiting for better abstract classes to work with?&lt;/p&gt;
&lt;h2 id="a-better-way"&gt;A better way&lt;/h2&gt;
&lt;p&gt;We can't test something tied to &lt;code&gt;HttpContext&lt;/code&gt; like this.  We need another approach.  The one I favor is wrapping the calls we care about, delegating out to the untestable code in the wrapper class, then passing an interface to the wrapper class into the constructor of the class using it.&lt;/p&gt;
&lt;p&gt;Here's the wrapping class I've created to access a few &lt;code&gt;HttpContext&lt;/code&gt; current user values and the interface for the wrapping class:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public class CurrentUser : ICurrentUser
{
    public virtual string Name()
    {
        return HttpContext.Current.User.Identity.Name;
    }
&lt;pre&gt;&lt;code&gt;public bool IsLoggedIn()
{
    return HttpContext.Current.User.Identity.IsAuthenticated;
}

public bool IsGuest()
{
    return HttpContext.Current.User.IsInRole(&amp;amp;quot;Guest&amp;amp;quot;);
}

public bool IsAdmin()
{
    return HttpContext.Current.User.IsInRole(&amp;amp;quot;Admin&amp;amp;quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;public interface ICurrentUser
{
string Name();
bool IsLoggedIn();
bool IsGuest();
bool IsAdmin();
}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Now I need to update the controller to inject this dependency into the constructor so it can be mocked, and use a private field set in the constructor for subsequent calls to _currentUser:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public class OrderController : Controller
{
    private readonly ICurrentUser _currentUser;
&lt;pre&gt;&lt;code&gt;public OrderController(ICurrentUser currentUser)
{
    _currentUser = currentUser;
}

[Authorize]
public ActionResult Process()
{
    if (_currentUser.IsAdmin())
    {
        return View(&amp;amp;quot;SecretAdminStuff&amp;amp;quot;);
    }

    return View(&amp;amp;quot;NotAuthorized&amp;amp;quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Now we've got a testable action method.  I mock the CurrentUser with &lt;code&gt;MockRepository.GenerateMock&amp;lt;ICurrentUser&amp;gt;&lt;/code&gt;, set its return value with the Rhino Mocks &lt;code&gt;.Stub()&lt;/code&gt; and &lt;code&gt;.Return()&lt;/code&gt; extension methods, and check for the expected results:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;[Test]
public void Should_return_NotAuthorized_view_when_not_Admin_user()
{
    // Arrange
    var mockCurrentUser = MockRepository.GenerateMock&amp;lt;ICurrentUser&amp;gt;();
    mockCurrentUser.Stub(x =&amp;gt; x.IsAdmin()).Return(false);
    var orderController = new OrderController(mockCurrentUser);
&lt;pre&gt;&lt;code&gt;// Act
var result = orderController.Process() as ViewResult;

// Assert
result.ViewName.ShouldEqual(&amp;amp;quot;NotAuthorized&amp;amp;quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;[Test]
public void Should_return_SecretAdminStuff_view_when_Admin_user()
{
// Arrange
var mockCurrentUser = MockRepository.GenerateMock&amp;lt;ICurrentUser&amp;gt;();
mockCurrentUser.Stub(x =&amp;gt; x.IsAdmin()).Return(true);
var orderController = new OrderController(mockCurrentUser);&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Act
var result = orderController.Process() as ViewResult;

// Assert
result.ViewName.ShouldEqual(&amp;amp;quot;SecretAdminStuff&amp;amp;quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="hey-wait-a-sec"&gt;Hey, wait a sec&lt;/h2&gt;
&lt;p&gt;If you're thinking to yourself: I've just tested the code in the action method and not whether &lt;code&gt;HttpContext&lt;/code&gt; really works, you're exactly right.  The tests should cover the branching in the controller action and are unit tests.  They are &lt;strong&gt;not&lt;/strong&gt; integration tests that check to see if &lt;code&gt;HttpContext&lt;/code&gt; is returning the right values.&lt;/p&gt;
&lt;p&gt;I'm OK with that tradeoff.  I know &lt;code&gt;HttpContext&lt;/code&gt; works.  It's been around forever and it's in a &lt;code&gt;System.&amp;lt;something&amp;gt;&lt;/code&gt; namespace, so I shouldn't be testing it.&lt;/p&gt;
&lt;p&gt;The real question is, do my login and roles and authorization settings work as expected in my application.  That calls for integration testing, and the easiest way to do that is click through those screens and see if it's working.  You can also automate this clicking around with &lt;a href="https://www.nuget.org/packages/WatiN/"&gt;Watin&lt;/a&gt;, or &lt;a href="http://www.specflow.org/"&gt;SpecFlow&lt;/a&gt; (which uses Watin internally to drive the browser).&lt;/p&gt;
</description>
      <pubDate>Thu, 19 Aug 2010 10:40:00 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/which-ioc-container-should-i-use</guid>
      <link>https://volaresoftware.com/en/technical-posts/which-ioc-container-should-i-use</link>
      <title>Which IoC container should I use?</title>
      <description>&lt;p&gt;This came up on the &lt;a href="http://tech.groups.yahoo.com/group/altdotnet/"&gt;Alt.Net Yahoo Group/mailing list&lt;/a&gt; today.  There are tons of tools out there for inversion of control.  They have been compared &lt;a href="http://www.hanselman.com/blog/ListOfNETDependencyInjectionContainersIOC.aspx"&gt;here&lt;/a&gt; and other places online.  Nobody wants their app tied to the &lt;a href="http://en.wikipedia.org/wiki/Betamax"&gt;Betamax&lt;/a&gt; of IoC tools, so people are anxious to pick the best one.&lt;/p&gt;
&lt;p&gt;All containers keep a hash table of your interfaces mapped to your concrete classes.  Most will let you request a specific instance with a string token.  Most will let you control instance creation (singleton, etc.).  The popular IoC containers have fluent configuration and use conventions to figure out that IEmailService maps to EmailService.&lt;/p&gt;
&lt;p&gt;So which one should you pick?  &lt;strong&gt;Go with the one you already know best and/or the one that is easiest for your dev team to configure&lt;/strong&gt;.  That's because with the &lt;a href="http://www.codeplex.com/CommonServiceLocator"&gt;Common Service Locator&lt;/a&gt; wrapping your IoC get instance calls, the provider becomes a moot point.&lt;/p&gt;
&lt;p&gt;This is an old OO principal - encapsulate the stuff that can change.  &lt;a href="http://codebetter.com/blogs/jeremy.miller/archive/2008/08/16/it-s-time-for-ioc-container-detente.aspx"&gt;Jeremy Miller pointed out the need for a common IoC wrapper&lt;/a&gt; to do just this.  Today's hot new open source IoC container could be tomorrow's dormant project.  If you wrap the calls, you can rip out your IoC provider and most of your code stays the same since it's calling the wrapper.&lt;/p&gt;
&lt;p&gt;Here's how I'm doing this using &lt;a href="http://www.castleproject.org/container/index.html"&gt;Castle Windsor&lt;/a&gt; in a Sharp Architecture project.  First, I create a class to wire up my IoC configurations for my app.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public static class RegisterIoCContainer
{
    public static void AddComponentsTo(IWindsorContainer container)
    {
        AddApplicationConcernsTo(container);
        AddCoreConcernsTo(container);
    }
&lt;pre&gt;&lt;code&gt;private static void AddApplicationConcernsTo(IWindsorContainer container)
{
    container.Register(Component
        .For&amp;amp;lt;IMappingEngine&amp;amp;gt;
        .Instance(Mapper.Engine)
        .LifeStyle.Singleton);

    container.Register(AllTypes.Pick()
        .FromAssemblyNamed(&amp;amp;quot;MyApp.ApplicationServices&amp;amp;quot;)
        .WithService.FirstInterface()
        .Configure(c =&amp;amp;gt; c.LifeStyle.Transient));
}

private static void AddCoreConcernsTo(IWindsorContainer container)
{
    container.Register(AllTypes.Pick()
        .FromAssemblyNamed(&amp;amp;quot;MyApp.Infrastructure&amp;amp;quot;)
        .WithService.FirstNonGenericCoreInterface(&amp;amp;quot;MyApp.Core&amp;amp;quot;)
        .Configure(c =&amp;amp;gt; c.LifeStyle.Transient));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Note the use of convention-based mappings between assemblies and the different instance lifestyles.  &lt;code&gt;Mapper.Engine&lt;/code&gt; has a Singleton lifestyle.  Not that there's anything wrong with that. :&amp;gt;&lt;/p&gt;
&lt;p&gt;Next, I create a class to tell Common Service Locator to use Castle Windsor as the provider and to load up those IoC configurations:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public static class RegisterServiceLocator
{
    public static void Register()
    {
        var container = new WindsorContainer();
&lt;pre&gt;&lt;code&gt;    ServiceLocator.SetLocatorProvider(() =&amp;amp;gt; new WindsorServiceLocator(container));

    RegisterIoCContainer.AddComponentsTo(container);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Then I call &lt;code&gt;RegisterServiceLocator.Register()&lt;/code&gt; on &lt;code&gt;Application_Start()&lt;/code&gt; in the &lt;code&gt;Global.asax&lt;/code&gt;.  From then on, I can call the Common Service Locator to get my instance from my interface:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;var instance = ServiceLocator.Current.GetInstance&amp;lt;IEmailService&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I don't often need to use this syntax, since I'm usually pushing external dependencies into a constructor and letting auto-wiring resolve the dependency chain for me.  But I do use this syntax for testing that Common Service Locator is finding the instance I want.&lt;/p&gt;
</description>
      <pubDate>Sat, 10 Oct 2009 00:41:32 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/adding-requirejs-to-an-aspnet-mvc-project</guid>
      <link>https://volaresoftware.com/en/technical-posts/adding-requirejs-to-an-aspnet-mvc-project</link>
      <title>Adding RequireJS to an ASP.NET MVC project</title>
      <description>&lt;h2 id="why-requirejs"&gt;Why RequireJS?&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://requirejs.org/"&gt;RequireJS&lt;/a&gt; is a popular JavaScript module loader.  RequireJS solves the problem of needing to invoke some JavaScript code from another file, but not knowing if that file has been loaded yet.&lt;/p&gt;
&lt;p&gt;It does this with either a define or a require declaration, which takes an array of strings and a callback function, then passes in the module names as arguments so you can reference them in your JavaScript code.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;define([&amp;quot;jquery&amp;quot;, &amp;quot;moment&amp;quot;],
    function ($, moment) {
        &amp;quot;use strict&amp;quot;;
&lt;pre&gt;&lt;code&gt;    var init = function () {
        // Requires MomentJS to be loaded. 
        // &amp;amp;quot;moment&amp;amp;quot; is the argument passed in by RequireJS for the MomentJS module, aliased as &amp;amp;quot;moment&amp;amp;quot; in the define/require statement.
        var now = new moment().format(&amp;amp;quot;M/D/YYYY h:mm:ss A&amp;amp;quot;);

        // Requires jQuery to be loaded. 
        // &amp;amp;quot;$&amp;amp;quot; is the argument passed in by RequireJS for the &amp;amp;quot;jquery&amp;amp;quot; module in the define/require statement.
        $(&amp;amp;quot;#currentDateTime&amp;amp;quot;).text(now);
    };

    return {
        init: init
    };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;);
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Here &amp;quot;moment&amp;quot; is both the name of the module to load, and the argument passed in for that module name.  It could have been &amp;quot;m&amp;quot; throughout, and it would still work.  The same is also true for &amp;quot;jquery at the top in the define, which tells RequireJS what module to load, and &amp;quot;&lt;span class="math"&gt;\(&amp;quot; below that, which tells RequireJS to load that module into an argument named &amp;quot;\)&lt;/span&gt;&amp;quot;.  We're using &amp;quot;moment&amp;quot; and &amp;quot;&lt;span class="math"&gt;\(&amp;quot; inside the function so the code looks conventional, but the &amp;quot;\)&lt;/span&gt;&amp;quot; could have been &amp;quot;j&amp;quot; if you wanted it to be.&lt;/p&gt;
&lt;p&gt;RequireJS guarantees that the external modules are loaded by the time your code runs.  It also keeps track of which modules have already been loaded on the page, so it doesn't pull in the same module twice.&lt;/p&gt;
&lt;h2 id="so-which-is-it-require-or-define"&gt;So which is it – require() or define()?&lt;/h2&gt;
&lt;p&gt;The require and define statement are the main ways you use RequireJS. The API signature is the same for both, but they work differently: &amp;quot;define&amp;quot; is for modules that will be loaded and run by code that uses a &amp;quot;require&amp;quot; statement to pull that module in. So think of &amp;quot;define&amp;quot; as your module definitions, and &amp;quot;require&amp;quot; as the way to execute them.&lt;/p&gt;
&lt;p&gt;As you can see, the RequireJS usage is very simple and clean.  The setup can be a headache, especially around paths, so I'll take you through how I've done it.&lt;/p&gt;
&lt;h2 id="configuring-your-paths-in-main.js"&gt;Configuring your paths in main.js&lt;/h2&gt;
&lt;p&gt;RequireJS needs to be configured.  When we said &amp;quot;jquery&amp;quot; and &amp;quot;moment&amp;quot; above, we have to tell RequireJS where those files are so we can use those aliases.  That's where &lt;code&gt;main.js&lt;/code&gt; and &lt;code&gt;required.config()&lt;/code&gt; come in:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;require.config({
    baseUrl: &amp;quot;/Scripts/app&amp;quot;,
    paths: {
        jquery: &amp;quot;../lib/jquery-2.1.1&amp;quot;,
        jqueryValidate: &amp;quot;../lib/jquery.validate&amp;quot;,
        jqueryValidateUnobtrusive: &amp;quot;../lib/jquery.validate.unobtrusive&amp;quot;,
        bootstrap: &amp;quot;../lib/bootstrap&amp;quot;,
        moment: &amp;quot;../lib/moment&amp;quot;
    },
    shim: {
        jqueryValidate: [&amp;quot;jquery&amp;quot;],
        jqueryValidateUnobtrusive: [&amp;quot;jquery&amp;quot;, &amp;quot;jqueryValidate&amp;quot;]
    }
});
&lt;p&gt;require([&amp;quot;kickoff&amp;quot;], function(kickoff) {
kickoff.init();
}
);
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;RequireJS uses the baseUrl setting in main.js if you pass it a script name that is not an alias in the paths section.  In other words, if you call &amp;quot;jquery&amp;quot; in your define/require, it knows from your paths setting where to go.  If you call &amp;quot;myScript&amp;quot; in define/require, it looks for it in the baseUrl path, which is &lt;code&gt;/Scripts/app&lt;/code&gt; in this case.&lt;/p&gt;
&lt;p&gt;Notice there are no &lt;code&gt;.js&lt;/code&gt; extensions to the end of the file names?  This is something RequireJS does to help you.  It's a JavaScript loader; it knows those are JavaScript files.  In my view, this just adds to some of the confusion of configuring this thing.&lt;/p&gt;
&lt;p&gt;Here's how I've got my paths configured under my Scripts folder in Visual Studio:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2014/5/image_thumb.png" alt="https://cdn.volaresoftware.com/images/posts/2014/5/image_thumb.png" /&gt;&lt;/p&gt;
&lt;p&gt;You can set up different folder structures or names based on your preferences, but it probably makes sense for &lt;code&gt;main.js&lt;/code&gt;, which is the entry point of the app, to be at the root of &lt;code&gt;/Scripts&lt;/code&gt;, or at least above your &lt;code&gt;/app&lt;/code&gt; and&lt;code&gt; /lib&lt;/code&gt; script folders.  Also, you don't have to name your file &lt;code&gt;main.js&lt;/code&gt;. that's just a RequireJS convention.&lt;/p&gt;
&lt;p&gt;The shim section in the code above is to tell RequireJS about any dependencies your files have before they can be used.  Here, we are saying if we call &amp;quot;jqueryValidate&amp;quot; to load that module, we have to load &amp;quot;jquery&amp;quot; first.  The &amp;quot;jqueryValidateUnobtrusive&amp;quot; module has to load &amp;quot;jqueryValidate&amp;quot; and &amp;quot;jquery&amp;quot; first, before it can be used.  You could probably shorten the shim for &amp;quot;jqueryValidateUnobtrusive&amp;quot; to just &amp;quot;jqueryValidate&amp;quot;, since that module requires &amp;quot;jquery&amp;quot;, and RequireJS tracks the whole dependency graph for you.  It doesn't hurt to leave it in, either.&lt;/p&gt;
&lt;p&gt;For many apps, it makes sense to call code to load the app or run code on every page from the main.js file, and we've done that here with a call to &amp;quot;kickoff.init()&amp;quot;.&lt;/p&gt;
&lt;h2 id="calling-the-main.js-file"&gt;Calling the main.js file&lt;/h2&gt;
&lt;p&gt;The normal advice for adding RequireJS to an app is to put this line in the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; section of &lt;code&gt;_Layout.cshtml&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;script data-main=&amp;quot;Scripts/main&amp;quot; src=&amp;quot;/Scripts/lib/require.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is a kind of weird looking script tag.  The src attribute is normal enough for pulling in RequireJS, but the data-main is new.  That's RequireJS's special attribute for getting the path to main.js.  Notice again there is no &amp;quot;.js&amp;quot; in the data-main.  RequireJS knows it's a .js file and appends that automatically.&lt;/p&gt;
&lt;p&gt;This script tag is usually all you need for a single page app, where all modules run inside one full page request.&lt;/p&gt;
&lt;h2 id="set-up-for-multi-page-apps"&gt;Set up for multi-page apps&lt;/h2&gt;
&lt;p&gt;I don't see too many single-page apps in the wild.  More often, they are multi-page apps where each page has a LOT going on.  If you aren't building a single page app, you can still take advantage of RequireJS, but we need to change some things.&lt;/p&gt;
&lt;p&gt;We need to change the code that loads RequireJS and main.js in &lt;code&gt;_Layout.cshtml&lt;/code&gt; from:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;script data-main=&amp;quot;Scripts/main&amp;quot; src=&amp;quot;/Scripts/lib/require.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;to:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;    &amp;lt;script src=&amp;quot;/Scripts/lib/require.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
    @RenderSection(&amp;quot;scripts&amp;quot;, required: false)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can put this right before the closing &lt;code&gt;&amp;lt;/body&amp;gt;&lt;/code&gt; tag if you like, but RequireJS will inject &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags with the &lt;code&gt;async&lt;/code&gt; attribute in the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; section like this:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/script_before_closing_body_tag.png" alt="https://cdn.volaresoftware.com/images/posts/2019/12/script_before_closing_body_tag.png" /&gt;&lt;/p&gt;
&lt;p&gt;Now we've got a common layout, and a hook in each page (the Razor &lt;code&gt;@RenderSection&lt;/code&gt;) where we can load THAT page's scripts.  In each page, you'll then need something like:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;@section scripts
{
    &amp;lt;script&amp;gt;
        require([&amp;quot;Scripts/main&amp;quot;],
            function () {
                require([&amp;quot;currentDateTime&amp;quot;],
                    function (currentDateTime) {
                        currentDateTime.init();
                    }
                );
            }
        );
    &amp;lt;/script&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each page will be different, depending on what you need to load and run, but you will always load and run main.js, then when that's done, you'll load the scripts just for that page in the inner require().  Note this inner require() is pulling in the code that was in the define() at the top of this post.&lt;/p&gt;
&lt;p&gt;Now drop this code in on every page in your app, but first…&lt;/p&gt;
&lt;h2 id="what-about-jquery-and-dom-loading"&gt;What about jQuery and DOM loading?&lt;/h2&gt;
&lt;p&gt;What if your JavaScript loads before the DOM is loaded?  With jQuery, we normally call:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;$(function () {
    ...the code to run on DOM ready...
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So how do we know the DOM is loaded before we start touching it in RequireJS world?  We need to use the &lt;a href="http://requirejs.org/docs/download.html#domReady"&gt;domReady plugin&lt;/a&gt; with:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;require([&amp;quot;domReady!&amp;quot;],
    function() {
        ...the code to run on DOM ready...
    }
);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Download the plugin and put it in the /Scripts/lib folder.  Now we have a new file we want to alias, so we need to add that to our &lt;code&gt;require.config&lt;/code&gt; paths in &lt;code&gt;main.js&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;paths: {
    jquery: &amp;quot;../lib/jquery-2.1.1&amp;quot;,
    jqueryValidate: &amp;quot;../lib/jquery.validate&amp;quot;,
    jqueryValidateUnobtrusive: &amp;quot;../lib/jquery.validate.unobtrusive&amp;quot;,
    bootstrap: &amp;quot;../lib/bootstrap&amp;quot;,
    moment: &amp;quot;../lib/moment&amp;quot;,
    domReady: &amp;quot;../lib/domReady&amp;quot;,
},
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There we go.  We have another piece of our run-on-every-page code snippet.&lt;/p&gt;
&lt;h2 id="mvc-helpers"&gt;MVC Helpers&lt;/h2&gt;
&lt;p&gt;When you start repeating yourself in an MVC view, consider adding an HTML Helper.  What we want generically is:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;require([&amp;quot;Scripts/main&amp;quot;],
    function () {
        require([&amp;quot;...the module to load...&amp;quot;, &amp;quot;domReady!&amp;quot;],
            ...run the module...
        );
    }
);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We also don't want to have to think about relative paths.  We want the scripts to find &lt;code&gt;main.js&lt;/code&gt; and the &lt;code&gt;/Scripts/app&lt;/code&gt; and &lt;code&gt;/Scripts/lib&lt;/code&gt; folder whether the page is located at the root (&lt;code&gt;/&lt;/code&gt;) or &lt;code&gt;/Deep/Within/The/Site&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Here's the C# to do that:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;using System;
using System.Text;
using System.Web;
using System.Web.Mvc;
&lt;p&gt;namespace RequireJSWithMVC.Extensions
{
public static class RequireJsHelpers
{
public static MvcHtmlString InitPageMainModule(this HtmlHelper helper, string pageModule)
{
var require = new StringBuilder();
var scriptsPath = &amp;quot;~/Scripts/&amp;quot;;
var absolutePath = VirtualPathUtility.ToAbsolute(scriptsPath);&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;        require.AppendLine(&amp;amp;quot;&amp;amp;lt;script&amp;amp;gt;&amp;amp;quot;);
        require.AppendFormat(&amp;amp;quot;    require([\&amp;amp;quot;{0}main.js\&amp;amp;quot;],&amp;amp;quot; + Environment.NewLine, absolutePath);
        require.AppendLine(&amp;amp;quot;        function() {&amp;amp;quot;);
        require.AppendFormat(&amp;amp;quot;            require([\&amp;amp;quot;{0}\&amp;amp;quot;, \&amp;amp;quot;domReady!\&amp;amp;quot;]);&amp;amp;quot; + Environment.NewLine, pageModule);
        require.AppendLine(&amp;amp;quot;        }&amp;amp;quot;);
        require.AppendLine(&amp;amp;quot;    );&amp;amp;quot;);
        require.AppendLine(&amp;amp;quot;&amp;amp;lt;/script&amp;amp;gt;&amp;amp;quot;);

        return new MvcHtmlString(require.ToString());
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;What we're going for is having several things loaded on every page: 1) require.js, 2) main.js, 3) the DOM, and 4) the main JavaScript module for that page and anything that module needs.  This &amp;quot;main module&amp;quot; concept works well to just run as it's loaded instead of forcing the caller to invoke it with an init() call, so let's change our &amp;quot;currentDateTime.js&amp;quot; module from above to do that and create &amp;quot;main-currentDateTime.js&amp;quot; instead:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;require([&amp;quot;jquery&amp;quot;, &amp;quot;moment&amp;quot;],
    function ($, moment) {
        &amp;quot;use strict&amp;quot;;
&lt;pre&gt;&lt;code&gt;    // Requires MomentJS to be loaded. 
    // &amp;amp;quot;moment&amp;amp;quot; is the argument passed in by RequireJS for the MomentJS module, aliased as &amp;amp;quot;moment&amp;amp;quot; in the require statement.
    var now = new moment().format(&amp;amp;quot;M/D/YYYY h:mm:ss A&amp;amp;quot;);

    // Requires jQuery to be loaded. 
    // &amp;amp;quot;$&amp;amp;quot; is the argument passed in by RequireJS for the &amp;amp;quot;jquery&amp;amp;quot; module in the require statement.
    $(&amp;amp;quot;#currentDateTime&amp;amp;quot;).text(now);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;);
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;We've also changed from define() to require() since this is a self-loading module, not one a caller has to invoke.  We got rid of the init() function so this code runs when the module is loaded.&lt;/p&gt;
&lt;h2 id="download"&gt;Download&lt;/h2&gt;
&lt;p&gt;That should do it for adding RequireJS to your MVC mutli-page app.  All the code above is available for &lt;a href="https://github.com/VolareSoftware/RequireJSWithMVC"&gt;view/download on GitHub&lt;/a&gt;.&lt;/p&gt;
</description>
      <pubDate>Wed, 28 May 2014 00:39:29 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/why-im-using-moq-instead-of-rhino-mocks-these-days</guid>
      <link>https://volaresoftware.com/en/technical-posts/why-im-using-moq-instead-of-rhino-mocks-these-days</link>
      <title>Why I'm using Moq instead of Rhino Mocks these days</title>
      <description>&lt;p&gt;On my last &lt;a href="http://en.wikipedia.org/wiki/Greenfield_project"&gt;greenfield project&lt;/a&gt; I got to pick the unit testing and mocking tools.  I've been a regular &lt;a href="http://www.ayende.com/projects/rhino-mocks.aspx"&gt;Rhino Mocks&lt;/a&gt; user for a long time, but I've seen lots of code samples with &lt;a href="http://code.google.com/p/moq/"&gt;Moq&lt;/a&gt; and liked the syntax, so I gave it a try.&lt;/p&gt;
&lt;p&gt;I have to say, I did prefer Moq slightly to Rhino Mocks.  The newer Arrange, Act, Assert (AAA) style syntax in Rhino Mocks is a huge improvement over the old Record/Replay mess.  But Moq has the benefit of being born at the right time and has AAA style calls without the burden of supporting deprecated syntax.  This means Moq has cleaner documentation, fewer options, and fewer ways to get confused by the API.  I really couldn't find anything I needed to do in Moq that I couldn't do.  I did get a little tripped up having to get the object out of the mock, with myMock.Object calls, but that wasn't a big deal.&lt;/p&gt;
&lt;p&gt;Here's the &lt;a href="http://nuget.org/List/Packages/Moq"&gt;NuGet Moq install package&lt;/a&gt; syntax to add Moq to your unit test project:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2011/3/image7_1.png" alt="image7_1.png" /&gt;&lt;/p&gt;
&lt;p&gt;I'm using mocking frameworks less these days.  Instead, I'll write a fake object myself or just try to avoid interaction testing altogether.  But if I needed to pull one off the shelf today, I'd grab Moq first.&lt;/p&gt;
</description>
      <pubDate>Thu, 10 Mar 2011 01:40:15 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/lazy-load-off-screen-images-with-lazysizes</guid>
      <link>https://volaresoftware.com/en/technical-posts/lazy-load-off-screen-images-with-lazysizes</link>
      <title>Lazy load off-screen images with lazysizes</title>
      <description>&lt;p&gt;Many users will never scroll all the way down to see the awesome images below the fold on your web site. If you load all your images when the page loads, you are wasting bandwidth and slowing down the page start-up experience.&lt;/p&gt;
&lt;p&gt;Instead, you can lazy-load images as they are about to come into view. The latest way to do this is using Intersectional Observer, but &lt;a href="https://caniuse.com/#feat=intersectionobserver"&gt;it isn't supported on Safari, iOS Safari, or IE11&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I opted to use &lt;a href="https://www.npmjs.com/package/lazysizes"&gt;lazysizes&lt;/a&gt; to deal with cross-browser differences, viewport size differences, scroll speeds, and the other headaches you could get rolling your own solution. To see it in action, &lt;a href="http://afarkas.github.io/lazysizes/"&gt;go to their test page&lt;/a&gt;, open your browser tools Network tab, filter for Images, and scroll down.  You'll see new images loaded as you get closer to them. It's slick.&lt;/p&gt;
&lt;p&gt;The easiest way to use lazysizes is to reference the script in your page:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;script src=&amp;quot;lazysizes.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then change &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tags from &lt;code&gt;src=&amp;quot;myImage.jpg&amp;quot;&lt;/code&gt; to &lt;code&gt;data-src=&amp;quot;myImage.jpg&amp;quot;&lt;/code&gt; and add &lt;code&gt;class=&amp;quot;lazyload&amp;quot;&lt;/code&gt; like:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;img data-src=&amp;quot;myImage.jpg&amp;quot; class=&amp;quot;lazyload&amp;quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can get fancier with &lt;a href="https://github.com/aFarkas/lazysizes#responsive-image-support-picture-andor-srcset"&gt;responsive image sets&lt;/a&gt; and &lt;a href="https://github.com/aFarkas/lazysizes#responsive-image-support-picture-andor-srcset"&gt;lazy loading CSS background images&lt;/a&gt;, too.&lt;/p&gt;
</description>
      <pubDate>Mon, 23 Apr 2018 00:39:09 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/where-should-validation-go</guid>
      <link>https://volaresoftware.com/en/technical-posts/where-should-validation-go</link>
      <title>Where should validation go?</title>
      <description>&lt;p&gt;&lt;code&gt;&amp;lt;groan&amp;gt;&lt;/code&gt;Not this argument again!&lt;code&gt;&amp;lt;/groan&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The short answer: I don't know.&lt;/p&gt;
&lt;p&gt;The long answer: Yeah, I &lt;strong&gt;really&lt;/strong&gt; don't know.&lt;/p&gt;
&lt;p&gt;There is still no widely accepted answer on this one.  Reasonable people disagree.  One camp pushes it up closer to the UI, the other down lower so it shelters the domain from invalid states.  Some like it sprinkled across layers; some like it centralized.&lt;/p&gt;
&lt;p&gt;I think Steve Sanderson is correct that &lt;a href="http://blog.codeville.net/2008/09/08/thoughts-on-validation-in-aspnet-mvc-applications/"&gt;validation falls on a continuum&lt;/a&gt; from easy UI validation, like required fields, to complex business rules that need to be checked closer to or in the domain entities.&lt;/p&gt;
&lt;p&gt;I also think Jimmy Bogard is correct that &lt;a href="http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/02/15/validation-in-a-ddd-world.aspx"&gt;context matters when it comes to validation&lt;/a&gt;.  This object is valid for what?  Saving to the database?  Emailing to sales?  Displaying on the screen?  The validation rules depend on the the behavior you are validating.&lt;/p&gt;
&lt;p&gt;These days, I think of validation as either UI Validation (required fields, min/max length, etc.), Domain Validation (start date/time must be before end date/time, order must have at least one item, etc.), or Database Validation (is this value unique, is this ID value going to throw a foreign key violation).  This is based on &lt;strong&gt;when&lt;/strong&gt; you can validate in the call chain more than &lt;strong&gt;what&lt;/strong&gt; it's valid for.  I still like validation in context, but those business rules end up in my Domain Validation logic with method names like &lt;code&gt;CanSendEmailToCustomer()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.sharparchitecture.net/"&gt;Sharp Architecture&lt;/a&gt; uses &lt;a href="http://nhforge.org/wikis/validator/nhibernate-validator-1-0-0-documentation.aspx"&gt;NHibernate Validators&lt;/a&gt; as attributes on the domain entities.  The best thing about this is your validation is centralized.  It's sitting right there in your domain, and you know where to go if there is a rule change.&lt;/p&gt;
&lt;p&gt;The other good thing about this approach is your entity should always be valid when saved.  The built-in &lt;code&gt;Repository&amp;lt;TEntity&amp;gt;&lt;/code&gt; calls in Sharp Architecture enforce validation before inserts and updates, so you're covered there.  If you want to call &lt;code&gt;MyEntity.IsValid()&lt;/code&gt; in a method, you can do that as well.&lt;/p&gt;
&lt;p&gt;The bad thing is those validation attributes can start looking like UI concerns when they have user-centric error messages in them (&amp;quot;Hey, user, that's not a valid format for a phone number&amp;quot;).  And if there is a rule that doesn't lend itself to attributes (e.g., orders must have at least one order item), you are on your own.&lt;/p&gt;
&lt;p&gt;I started with validation attributes on my domain entities, and when my attribute messages got too UI-looking, I moved to using &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.aspx"&gt;Data Annotations&lt;/a&gt; on DTOs in my application service layer for UI validation.  The DTOs are made to be client facing, so I'm not bothered by user-specific messages in them.&lt;/p&gt;
&lt;p&gt;Then when Domain or Database Validation problems come up, a &lt;code&gt;ValidationException&lt;/code&gt; is thrown up through the application service to the UI so the calling app can either display or handle it.  I haven't played with it yet, but I think this is what &lt;a href="http://xval.codeplex.com/"&gt;xVal&lt;/a&gt; is doing, too.&lt;/p&gt;
&lt;p&gt;The more I think about it, the more I see my web app as just another client calling into my application service layer which is encapsulating my domain.  So my web app is the &amp;quot;user&amp;quot; and the message needs to be just enough for &lt;strong&gt;that&lt;/strong&gt; user, not necessarily the end user.  Maybe a validation exception token is sent out from the application service layer to the UI, and the UI translates that to a string from a very UI-centric resource file?&lt;/p&gt;
&lt;p&gt;Bu I'm still not happy with this.  I feel like I have the right kind of validation in the right places, but I would still like a more centralized approach for easier refactoring of business rules.  I've used the &lt;a href="http://en.wikipedia.org/wiki/Specification_pattern"&gt;Specification Pattern&lt;/a&gt; before, and it does a great job of centralizing the rules.  But making yet another class for yet another required field and adding it to yet another Composite Specification?  Seems like your walking away from a lot of the productivity attributes can give you.&lt;/p&gt;
&lt;p&gt;Obviously, my thoughts on validation are still not fully formed.  I'm still arguing with myself.  My dream validation would be:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;centralized for easy refactoring and rule changes&lt;/li&gt;
&lt;li&gt;automatically called for routine things so I don't forget (like saving the order to the database)&lt;/li&gt;
&lt;li&gt;allow ad hoc calls for non-routine things (like validating the order confirmation email can be sent to the customer)&lt;/li&gt;
&lt;li&gt;handle simple validation like attributes so I can be productive&lt;/li&gt;
&lt;li&gt;handle complex validation like specifications so I'm not limited&lt;/li&gt;
&lt;li&gt;UI-agnostic so the centralized validation goo isn't holding end-user strings, except when I'm too lazy to set up the resource file, in which case strings can be passed up from this layer&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I told you I didn't know! :)&lt;/p&gt;
</description>
      <pubDate>Tue, 15 Sep 2009 00:41:26 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/specifying-args-with-rhino-mocks</guid>
      <link>https://volaresoftware.com/en/technical-posts/specifying-args-with-rhino-mocks</link>
      <title>Specifying Args with Rhino Mocks</title>
      <description>&lt;h2 id="the-problem"&gt;The problem&lt;/h2&gt;
&lt;p&gt;I ran into a snag testing some code today with Rhino Mocks.  I was mocking calls to a repository and inspecting the repository method calls and arguments passed.&lt;/p&gt;
&lt;p&gt;Everything started off pretty normal with the repository dependency injected into the class under test:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;// Arrange
var repository = MockRepository.GenerateMock&amp;lt;ICustomerRepository&amp;gt;();
var passenger = new Passenger(repository);
&lt;p&gt;// Act
passenger.CallTheMethodUnderTest(arg1, arg2);
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;In my Assert section, I needed to check that the correct repository methods were called with the correct arguments.  The catch was, one of the arguments was a class created &lt;strong&gt;within&lt;/strong&gt; the method under test.  I thought I could create and assert the equivalent Customer in my test like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;// Assert
var expectedCustomer = new Customer
                           {
                               CustomerID = &amp;quot;1234&amp;quot;,
                               FirstName = &amp;quot;Joe&amp;quot;,
                               LastName = &amp;quot;Wilson&amp;quot;
                           };
repository.AssertWasCalled(x =&amp;gt; x.SomeRepositoryMethod(
    arg1, 
    arg2, 
    expectedCustomer));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The two Customer objects (in the test and in the method under test) had the same values, but of course, were not the same objects.  They were two different Customer objects that happened to have the same values.  So Rhino Mocks told me that my expected Assert wasn't met.&lt;/p&gt;
&lt;h2 id="the-answer"&gt;The answer&lt;/h2&gt;
&lt;p&gt;I knew Rhino Mocks could ignore arguments with&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;Args&amp;lt;T&amp;gt;.Is.Anything
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But I knew what the values should be.  In fact, for this test, the values being passed into the repository calls were just as important as the calls themselves.&lt;/p&gt;
&lt;p&gt;So I tried comparing the &lt;strong&gt;values&lt;/strong&gt; of the two Customer objects instead of the objects themselves:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;repository.AssertWasCalled(x =&amp;gt; x.SomeRepositoryMethod(
    arg1,
    arg2,
    Arg&amp;lt;Customer&amp;gt;.Matches(c =&amp;gt; 
        c.CustomerID.Equals(&amp;quot;1234&amp;quot;) &amp;amp;amp;&amp;amp;amp;
        c.FirstName.Equals(&amp;quot;Joe&amp;quot;) &amp;amp;amp;&amp;amp;amp;
        c.LastName.Equals(&amp;quot;Wilson&amp;quot;))));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So close!  But now Rhino Mocks told me if I used Arg for one parameter, I'd better use it for all of them.  No biggie. I made the change and this worked:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;repository.AssertWasCalled(x =&amp;gt; x.SomeRepositoryMethod(
    Arg&amp;lt;int&amp;gt;.Is.Equal(arg1),
    Arg&amp;lt;int&amp;gt;.Is.Equal(arg2),
    Arg&amp;lt;Customer&amp;gt;.Matches(c =&amp;gt; 
        c.CustomerID.Equals(&amp;quot;1234&amp;quot;) &amp;amp;amp;&amp;amp;amp;
        c.FirstName.Equals(&amp;quot;Joe&amp;quot;) &amp;amp;amp;&amp;amp;amp;
        c.LastName.Equals(&amp;quot;Wilson&amp;quot;))));
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="postmortem"&gt;Postmortem&lt;/h2&gt;
&lt;p&gt;The Arg statement let's you specify a type and tell Rhino Mocks you don't know or don't care about the value:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;Args&amp;lt;int&amp;gt;.Is.Anything
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can also tell Rhino Mocks you know the type &lt;strong&gt;and&lt;/strong&gt; what the value should be:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;Args&amp;lt;int&amp;gt;.Is.Equal(7)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you have a non-primitive type or complex assert, you can also inspect values with the Matches statement:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;Arg&amp;lt;Customer&amp;gt;.Matches(c =&amp;gt; 
    c.CustomerID.Equals(&amp;quot;1234&amp;quot;) &amp;amp;amp;&amp;amp;amp;
    c.FirstName.Equals(&amp;quot;Joe&amp;quot;) &amp;amp;amp;&amp;amp;amp;
    c.LastName.Equals(&amp;quot;Wilson&amp;quot;))));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I realize the code in these tests is probably way too familiar with the code under test.  I prefer testing state over this kind of interaction testing where possible.  But this was a case where the code under test had a void return and didn't do much besides parse some values and call repository methods based on those values.&lt;/p&gt;
&lt;p&gt;In times like this, I'm glad I have interaction testing to fall back on so I can verify my code is behaving the way it should.&lt;/p&gt;
</description>
      <pubDate>Thu, 26 Nov 2009 01:41:11 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/review-of-sharp-architecture</guid>
      <link>https://volaresoftware.com/en/technical-posts/review-of-sharp-architecture</link>
      <title>Review of Sharp Architecture</title>
      <description>&lt;p&gt;I've been using the open-source project &lt;a href="http://code.google.com/p/sharp-architecture/"&gt;Sharp Architecture&lt;/a&gt; for about 6 months now, and version 1.0 was recently released.  It's a really great way to get rolling quickly on a project using ASP.NET MVC, Domain Driven Design (DDD), NHibernate, and Castle Windsor.&lt;/p&gt;
&lt;p&gt;I won't go into the details about what Sharp Architecture does.  I'll just cover what I like in the first version and what I hope makes it into future releases.&lt;/p&gt;
&lt;h2 id="what-i-like"&gt;What I like&lt;/h2&gt;
&lt;h3 id="decoupled-design"&gt;Decoupled Design&lt;/h3&gt;
&lt;p&gt;The Sharp Architecture framework uses inversion of control right out of the box with &lt;a href="http://www.castleproject.org/"&gt;Castle Windsor&lt;/a&gt; and the &lt;a href="http://www.codeplex.com/CommonServiceLocator"&gt;Common Service Locator&lt;/a&gt; wrapping container calls.  The &lt;code&gt;MyProject.Core&lt;/code&gt; assembly holds your domain model and interfaces to your repositories.  Implementations of those repositories are in &lt;code&gt;MyProject.Data&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;There is also a &lt;code&gt;MyProject.ApplicationServices&lt;/code&gt; assembly for times when your controller logic starts to look heavier than it should or you prefer to push all your logic into an application layer so you can skim off the MVC UI for something else at some point (Silverlight?  WCF?).  I like this approach with very lightweight controllers and views for just this reason.&lt;/p&gt;
&lt;h3 id="nhibernate-training-wheels"&gt;NHibernate Training Wheels&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/blogs/billy_mccafferty/"&gt;Billy McCafferty&lt;/a&gt;, the principal author on the project, is &lt;a href="http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspx"&gt;one of the gurus on NHibernate best practices&lt;/a&gt;.  NHibernate is very powerful, but some tools, like &lt;a href="http://fluentnhibernate.org/"&gt;Fluent NHibernate&lt;/a&gt;, which uses C# code to map your domain to your database instead of XML, are.well.kind of fluid.and still under construction.&lt;/p&gt;
&lt;p&gt;I'm still new to NHibernate and very new to Fluent NHibernate, so I get tripped up often.  It's nice to know that my solution is using best practices for tools where my footing is not as sure, like NHibernate session management.&lt;/p&gt;
&lt;h3 id="templates-conventions"&gt;Templates + Conventions&lt;/h3&gt;
&lt;p&gt;The Visual Studio solution and T4 templates inside Sharp Architecture are the things that makes it different from being just another reference implementation or architecture guidance.  You can get a new, empty Sharp Architecture solution going in about 30 seconds with the Visual Studio solution template.  The T4 templates help you add controllers and views built around conventions and the property names in your domain entity.&lt;/p&gt;
&lt;p&gt;I used to be a big fan of code generation.  It's nice to spit out a bunch of classes very quickly, but there really has to be a balance.  If it gens too much code, is it all stuff you really need?  If it only gens a little bit, did you need a code generator at all?&lt;/p&gt;
&lt;p&gt;Sharp Architecture does a good job of giving you a jump start on stuff you will probably want or at least a place-holder for stuff you will want.  It doesn't litter the solution with too much junk.&lt;/p&gt;
&lt;p&gt;For instance, it doesn't generate a repository for your domain entity because you can use use the &lt;code&gt;IRepository&amp;lt;MyDomainEntity&amp;gt;&lt;/code&gt; and Repository&lt;MyDomainEntity&gt; in the Sharp Architecture assemblies.  It doesn't generate NHibernate mappings for your domain entity because the mapping conventions cover most cases.  If you do need additional repository methods or have unconventional database mappings, it's easy to inherit from and override these.  Sharp Architecture uses generics, base classes, and conventions to keep from needing a lot of code generation.&lt;/p&gt;
&lt;h3 id="documentation-sample-code-wiki-and-forum-support"&gt;Documentation, Sample Code, Wiki, and Forum Support&lt;/h3&gt;
&lt;p&gt;This project is much better documented than most open-source projects.  In addition to the &amp;quot;getting started&amp;quot; and 'using the framework&amp;quot; documents, there is a sample Northwind project that comes with the download files.  Online, there is a &lt;a href="http://wiki.sharparchitecture.net/MainPage.ashx"&gt;wiki&lt;/a&gt; and a &lt;a href="http://groups.google.com/group/sharp-architecture"&gt;Google Group&lt;/a&gt; that is actively monitored if you need additional help.&lt;/p&gt;
&lt;p&gt;I know real programmers only use &lt;a href="http://en.wikipedia.org/wiki/.NET_Reflector"&gt;Reflector&lt;/a&gt; for documentation.  :&amp;gt;  But don't underestimate the value of documentation for widespread adoption.  You can have a great open source project that doesn't get very far if people don't know how to get up and running quickly and fully exploit the framework.  That won't be a problem for Sharp Architecture.&lt;/p&gt;
&lt;h3 id="helpers"&gt;Helpers&lt;/h3&gt;
&lt;p&gt;Sharp Architecture libraries are chock full of all kinds of convenience methods and helpers.  Want to write a database integration test using &lt;a href="http://sqlite.org/"&gt;SQLite&lt;/a&gt;?  Just have your test class inherit from &lt;code&gt;RepositoryTestsBase()&lt;/code&gt;.  Want to hit the live database?  Inherit from &lt;code&gt;DatabaseRepositoryTestsBase()&lt;/code&gt;.  Want to design by contract and check incoming parameters and return values easily?  Look into the Check.Require() and Check.Ensure().&lt;/p&gt;
&lt;p&gt;There are a ton of things like this that all of us have written before.  Most developers I know walk around with a couple assemblies to make coding their next project easier.  With Sharp Architecture, these are referenced in your solution right after File &amp;gt; New Project.&lt;/p&gt;
&lt;h3 id="folder-structure"&gt;Folder Structure&lt;/h3&gt;
&lt;p&gt;Everyone has their own preferred solution and folder structure.  The default project and folder organization in a new Sharp Architecture solution is pretty close to what I was already using and is simple for any developer to jump in and follow along.&lt;/p&gt;
&lt;p&gt;This may not seem like a big deal because a good structure looks obvious in hindsight, but it's nice to not have to dig around for things.  I've worked on solutions that have 20+ projects.  Sharp Architecture goes the other way and you end up with about four projects in a normal MVC app.&lt;/p&gt;
&lt;h2 id="what-i-would-like-to-see-in-future-releases"&gt;What I would like to see in future releases&lt;/h2&gt;
&lt;p&gt;I don't have any strong objections to the design choices in Sharp Architecture.  Most of the things here are more a matter of style/taste than anything.&lt;/p&gt;
&lt;h3 id="controllers-back-in-myproject.web-project"&gt;Controllers back in MyProject.Web project&lt;/h3&gt;
&lt;p&gt;You can read &lt;a href="http://devlicio.us/blogs/billy_mccafferty/archive/2009/01/09/an-argument-for-moving-asp-net-mvc-controllers-to-a-separate-assembly.aspx"&gt;Billy's view on putting the controllers in the web project&lt;/a&gt;. His main point is that controllers should be written and tested independent of the other assemblies so you don't succumb to temptation and do things like go straight to your repository from your controller instead of asking your IoC tool to give you the concrete repository instance.&lt;/p&gt;
&lt;p&gt;That's fair.  But my controllers don't do much besides call into my application services layer, render views, and redirect to other controller actions. I don't mind having a reference to the entire web project in my unit test project so I can test routes and the very little logic I have in my controllers.&lt;/p&gt;
&lt;p&gt;In his article, Billy describes the pain of having done it the way I prefer.  Maybe this is one of those lessons where you have to experience it yourself to internalize it.  Like my dad telling me the stove was hot when I was a kid. :&amp;gt;&lt;/p&gt;
&lt;h3 id="myproject.infrastructure-instead-of-myproject.data"&gt;MyProject.Infrastructure instead of MyProject.Data&lt;/h3&gt;
&lt;p&gt;Maybe I've looked at &lt;a href="http://code.google.com/p/codecampserver/"&gt;Code Camp Server&lt;/a&gt; or listened to Jeffery Palermo talk too much, but I lump data handling into a larger category of infrastructure concerns.  Sharp Architecture's solution template gives you &lt;code&gt;MyProject.Data&lt;/code&gt;, which holds the NHibernate mappings and conventions and the repository classes.&lt;/p&gt;
&lt;p&gt;But I have other utility/infrastructure things I need to put somewhere, like logging, emailing, etc.  I prefer having &lt;code&gt;MyProject.Infrastructure&lt;/code&gt; with Data as a folder underneath it so I can throw all my infrastructure implementation code into that assembly.  The interfaces for these guys still go in &lt;code&gt;MyProject.Core&lt;/code&gt;, just like the repository interfaces.&lt;/p&gt;
&lt;h3 id="more-emphasis-on-myproject.applicationservices"&gt;More emphasis on MyProject.ApplicationServices&lt;/h3&gt;
&lt;p&gt;I prefer to have as little logic as possible in my views and controllers.  I push as much as I can to an application layer so the UI can be replaced or added to with minimal impact.  In Sharp Architecture, you've got &lt;code&gt;MyProject.ApplicationServices&lt;/code&gt; for exactly that.  There is one Northwind example that uses this layer, but in the other samples, the controllers are doing the application flow work.&lt;/p&gt;
&lt;p&gt;I think it's better to have an application service passed into the controller's constructor so the controller doesn't need to know much except routing, views, redirects, the app service method to call, etc.  I don't mind having these UI logic concerns in the controller, but anything beyond that needs to be in an application layer.&lt;/p&gt;
&lt;p&gt;I've borrowed a metaphor from the SQL Server installer that talk about &amp;quot;surface area&amp;quot;.  I think of the &lt;code&gt;MyProject.ApplicationServices&lt;/code&gt; layer as a wrapper around &lt;strong&gt;all&lt;/strong&gt; the app logic.  The methods in this layer are the surface area of my application, and they encapsulates all the implementation code my domain is dealing with.  Calls into this layer can kick off multi-step processes, handle workflow, and usually have long, explicit method names.  But this is the &lt;strong&gt;only&lt;/strong&gt; part of my domain's surface area that is exposed externally.&lt;/p&gt;
&lt;p&gt;The MVC web project is one client calling into this application layer, but there may be others someday on even medium-sized projects.  If your app becomes more popular and you've followed this approach, you can add other clients that call into your application service layer like a WCF service, a system tray tool, etc.  These guys may have their own specialized methods or may use something the web application was using.  Either way, you are very intentional on the surface area you expose.&lt;/p&gt;
&lt;p&gt;I think Sharp Architecture gets this right.  I would just like to give it a little nudge to make it a point of emphasis.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I've used a lot of different frameworks, but Sharp Architecture comes closest to the way I want to work already.  The templates and documentation put it well beyond a reference implementation, and you can work with a simplified solution sitting on top of a lot of abstracted complexity to get you productive right away.&lt;/p&gt;
</description>
      <pubDate>Tue, 15 Sep 2009 00:41:29 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/true-is-truthy-but-truthy-isnt-the-same-as-true</guid>
      <link>https://volaresoftware.com/en/technical-posts/true-is-truthy-but-truthy-isnt-the-same-as-true</link>
      <title>True is Truthy, but Truthy isn't the same as True</title>
      <description>&lt;p&gt;Most JavaScript developers are familiar with the concepts of &lt;code&gt;truthy&lt;/code&gt; and &lt;code&gt;falsy&lt;/code&gt;.  As a quick refresher, the &lt;code&gt;falsy&lt;/code&gt; values are:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;false
null
undefined
0 (the number zero)
&amp;quot;&amp;quot; (an empty string)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Everything else is &lt;code&gt;truthy&lt;/code&gt;.  This is one of those things you just have to memorize, but it's simpler if you think of the &lt;code&gt;falsy&lt;/code&gt; stuff as things that are false or have no value.  Just watch out for zero and empty string.&lt;/p&gt;
&lt;p&gt;I got burned by a bug today in a passing Jasmine test by not paying enough attention to the &lt;code&gt;truthy&lt;/code&gt; values.  The code I was testing was a little function to make sure &lt;code&gt;scaleMin&lt;/code&gt; was smaller than &lt;code&gt;scaleMax&lt;/code&gt;, but if they were both set to 0, that was OK.  If &lt;code&gt;scaleMin&lt;/code&gt; was greater than or equal to &lt;code&gt;scaleMax&lt;/code&gt;, we'd return an error message.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://jsfiddle.net/joewilson0/9adyhc1f/"&gt;Here are the function and tests I started with&lt;/a&gt;.  All the tests pass.  Done, right?!?!&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;// Code under test
var MyApp = function () {
&lt;pre&gt;&lt;code&gt;var isValid = function (scaleMin, scaleMax) {
    if (scaleMax &amp;amp;lt;= scaleMin) {
        return &amp;amp;quot;Scale max must be greater than Scale min.&amp;amp;quot;;
    }

    return true;
};

return {
    isValid: isValid
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;};&lt;/p&gt;
&lt;p&gt;// Specs
describe(&amp;quot;isValid&amp;quot;, function () {&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var myApp = new MyApp();

it(&amp;amp;quot;Should be valid when scale min/max are both 0&amp;amp;quot;, function () {
    var scaleMin = 0,
        scaleMax = 0;

    expect(myApp.isValid(scaleMin, scaleMax)).toBeTruthy();
});

it(&amp;amp;quot;Should be valid when scale min is less than scaleMax&amp;amp;quot;, function () {
    var scaleMin = 0,
        scaleMax = 1;

    expect(myApp.isValid(scaleMin, scaleMax)).toBeTruthy();
});

it(&amp;amp;quot;Should be invalid when scale min is equal to scaleMax&amp;amp;quot;, function () {
    var scaleMin = 1,
        scaleMax = 1;

    expect(myApp.isValid(scaleMin, scaleMax)).toBe(&amp;amp;quot;Scale max must be greater than Scale min.&amp;amp;quot;);
});

it(&amp;amp;quot;Should be invalid when scale min is greater than scaleMax&amp;amp;quot;, function () {
    var scaleMin = 1,
        scaleMax = 0;

    expect(myApp.isValid(scaleMin, scaleMax)).toBe(&amp;amp;quot;Scale max must be greater than Scale min.&amp;amp;quot;);
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;});
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Not so much.&lt;/p&gt;
&lt;p&gt;Jasmine's &lt;code&gt;toBeTruthy()&lt;/code&gt; checks for any &lt;code&gt;truthy&lt;/code&gt; value, and a string with something in it is &lt;code&gt;truthy&lt;/code&gt;.  So in the test where I'm checking that it's OK if &lt;code&gt;scaleMin&lt;/code&gt; and &lt;code&gt;scaleMax&lt;/code&gt; are both 0, I'm getting the error string, which is &lt;code&gt;truthy&lt;/code&gt;.  Since the error string and the value true are both &lt;code&gt;truthy&lt;/code&gt;, my check for &lt;code&gt;toBeTruthy()&lt;/code&gt; will always pass.  I'm getting false positives.&lt;/p&gt;
&lt;p&gt;This is why you are supposed to write a failing test, then a passing test to prove your code was the thing that made the test pass.  I skipped that here because this code was so simple.  What could go wrong?  Oops!&lt;/p&gt;
&lt;p&gt;&lt;a href="https://jsfiddle.net/joewilson0/q46z3wer/"&gt;Here's the fixed function and test code&lt;/a&gt;, which uses Jasmine's &lt;code&gt;toBe(true)&lt;/code&gt; instead of &lt;code&gt;toBeTruthy()&lt;/code&gt; to tease apart error strings and the value true:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;// Code under test
var MyApp = function () {
&lt;pre&gt;&lt;code&gt;var isValid = function (scaleMin, scaleMax) {
    if (scaleMin === 0 &amp;amp;amp;&amp;amp;amp; scaleMax === 0) {
        return true;
    }
    
    if (scaleMax &amp;amp;lt;= scaleMin) {
        return &amp;amp;quot;Scale max must be greater than Scale min.&amp;amp;quot;;
    }

    return true;
};

return {
    isValid: isValid
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;};&lt;/p&gt;
&lt;p&gt;// Specs
describe(&amp;quot;isValid&amp;quot;, function () {&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var myApp = new MyApp();

it(&amp;amp;quot;Should be valid when scale min/max are both 0&amp;amp;quot;, function () {
    var scaleMin = 0,
        scaleMax = 0;

    expect(myApp.isValid(scaleMin, scaleMax)).toBe(true);
});

it(&amp;amp;quot;Should be valid when scale min is less than scaleMax&amp;amp;quot;, function () {
    var scaleMin = 0,
        scaleMax = 1;

    expect(myApp.isValid(scaleMin, scaleMax)).toBe(true);
});

it(&amp;amp;quot;Should be invalid when scale min is equal to scaleMax&amp;amp;quot;, function () {
    var scaleMin = 1,
        scaleMax = 1;

    expect(myApp.isValid(scaleMin, scaleMax)).toBe(&amp;amp;quot;Scale max must be greater than Scale min.&amp;amp;quot;);
});

it(&amp;amp;quot;Should be invalid when scale min is greater than scaleMax&amp;amp;quot;, function () {
    var scaleMin = 1,
        scaleMax = 0;

    expect(myApp.isValid(scaleMin, scaleMax)).toBe(&amp;amp;quot;Scale max must be greater than Scale min.&amp;amp;quot;);
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;});
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
</description>
      <pubDate>Fri, 24 Apr 2015 11:08:00 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/unit-testing-untestable-code</guid>
      <link>https://volaresoftware.com/en/technical-posts/unit-testing-untestable-code</link>
      <title>Unit testing untestable code</title>
      <description>&lt;p&gt;Let's say you've got a static or sealed class, or a class with non-virtual members that your code needs to use.  You need to unit test your code, but you can't get an instance of this class and/or you can't mock it.&lt;/p&gt;
&lt;p&gt;There are two ways to go:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Buy a tool that let's you mock things like this, such as &lt;a href="http://site.typemock.com/"&gt;Typemock Isolator&lt;/a&gt; or the newly announced &lt;a href="http://www.telerik.com/products/mocking.aspx"&gt;Telerik JustMock&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Code around it.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="buy-it"&gt;Buy it&lt;/h2&gt;
&lt;p&gt;I've already &lt;a href="https://volaresoftware.com/en/technical-posts/comparison-of-typemock-Isolator-and-rhino-mocks"&gt;compared&lt;/a&gt; Typemock Isolator (&lt;a href="http://www.typemock.com/BuyCommercial.php"&gt;$799&lt;/a&gt;) to RhinoMocks (&lt;a href="http://www.ayende.com/projects/rhino-mocks.aspx"&gt;free&lt;/a&gt;).  Typemock Isolator works as advertised.  The biggest issue is the price.  It's hard enough to get management approval for introducing external tools.  But when buy-in literally means &lt;strong&gt;BUY&lt;/strong&gt; in, it's even harder.&lt;/p&gt;
&lt;h2 id="build-it"&gt;Build it&lt;/h2&gt;
&lt;p&gt;Don't despair if you're stuck with &amp;quot;code around it&amp;quot; and using free mocking tools!  If you can change the code that is static, sealed, private, non-virtual, etc. fix it that way.  That's the best thing.&lt;/p&gt;
&lt;p&gt;But if it's in a legacy assembly you have to use, and you can't just change the original code, use this simple technique.&lt;/p&gt;
&lt;p&gt;Here's the untestable class we need to use.  It's static, so we can't mock an instance of it with Rhino Mocks.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public static class StaticSendOrderClass
{
    public static void SendOrderToAccountsPayable(Order order)
    {
        // Pretend code here...
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here's the new code you're working on that uses this static class to process an order:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public class OrderProcessor
{
    public void ProcessTheOrder(Order order, bool useStaticClass)
    {
        if (useStaticClass == true)
        {
            StaticSendOrderClass.SendOrderToAccountsPayable(order);
        }
        else
        {
            // Notify accounts payable some other way
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;First, we need to create an interface with &lt;strong&gt;just&lt;/strong&gt; the functionality we need from the untestable class.  Name the class and method(s) whatever makes sense for your app.  You're not tied to the legacy code naming convention; this is your code now.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public interface INotifyAccountsPayable
{
    void SendOrder(Order order);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, create a new class to implement this interface and wrap the untestable code.  In the method calls in the new class, turn around and delegate the call to the untestable class.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public class NotifyAccountsPayable : INotifyAccountsPayable
{
    public void SendOrder(Order order)
    {
        StaticSendOrderClass.SendOrderToAccountsPayable(order);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now inject the new interface into the constructor of your new class as an argument.  You'll also want to create a private field and set its value to the instance argument in the constructor.  Now you can swap out your old code that calls the untestable code, and instead use your new private field.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public class OrderProcessor
{
    private readonly INotifyAccountsPayable _notifyAccountsPayable;
&lt;pre&gt;&lt;code&gt;public OrderProcessor(INotifyAccountsPayable notifyAccountsPayable)
{
    _notifyAccountsPayable = notifyAccountsPayable;
}

public void ProcessTheOrder(Order order, bool useStaticClass)
{
    if (useStaticClass == true)
    {
        _notifyAccountsPayable.SendOrder(order);
    }
    else
    {
        // Notify accounts payable some other way
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Now you've got a unit testable &lt;code&gt;OrderProcessor&lt;/code&gt; class!  Mock the &lt;code&gt;INotifyAccountsPayable&lt;/code&gt; interface with Rhino Mocks and inject that mocked dependency into your class under test.  Then you can verify the call was made as expected.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;[Test]
public void Should_call_untestable_code_when_useStaticClass_is_set_to_true()
{
    // Arrange
    var mockNotifyAccountsPayable = MockRepository.GenerateMock&amp;lt;INotifyAccountsPayable&amp;gt;();
    var orderProcessor = new OrderProcessor(mockNotifyAccountsPayable);
    var stubOrder = MockRepository.GenerateStub&amp;lt;Order&amp;gt;();
    var useStaticClass = true;
&lt;pre&gt;&lt;code&gt;// Act
orderProcessor.ProcessTheOrder(stubOrder, useStaticClass);

// Assert
mockNotifyAccountsPayable.AssertWasCalled(x =&amp;amp;gt; x.SendOrder(stubOrder));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Please note this is &lt;strong&gt;not&lt;/strong&gt; testing the internals of the untestable, static code.  But you don't need to worry about unit testing the internals of that code.  You don't own that code.  Testing that is really an integration test, not a unit test.  Using this approach, you isolate your new code from an external dependency and keep all your new code testable.&lt;/p&gt;
</description>
      <pubDate>Tue, 06 Apr 2010 05:44:00 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/upgrading-fontawesome-from-4-to-5</guid>
      <link>https://volaresoftware.com/en/technical-posts/upgrading-fontawesome-from-4-to-5</link>
      <title>Upgrading FontAwesome from 4 to 5</title>
      <description>&lt;p&gt;&lt;a href="http://fontawesome.io/"&gt;FontAwesome 4&lt;/a&gt; has been around a long time, and it's…well, awesome! Remember their &lt;a href="https://www.kickstarter.com/projects/232193852/font-awesome-5"&gt;Kickstarter with those videos&lt;/a&gt;? Well &lt;a href="https://fontawesome.com/"&gt;FontAwesome 5&lt;/a&gt; is out now, and as promised, it has some big improvements. But to get the benefits, you'll have to work through some breaking changes. Here's what I learned from my upgrade.&lt;/p&gt;
&lt;p&gt;Let's start with a simple page with &lt;a href="https://codepen.io/joewilson0/pen/WdmQPJ"&gt;3 icons using Font Awesome 4&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The big improvement in FontAwesome 5 is that the icons are drawn with SVG now. Yay for sharp scaling up or down! Now you reference a JavaScript file with the SVG specs embedded in it instead of a CSS file. I'll change the pen to remove the CSS reference and add the JavaScript reference from the CDN:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;script defer src=&amp;quot;https://use.fontawesome.com/releases/v5.0.3/js/all.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then &lt;a href="https://codepen.io/joewilson0/pen/KZEdYG/"&gt;check the results&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;You can see the icons, but they changed a little. The calendar is very dark, and the arrow is a little more narrow. That's because the way you reference the icons has changed in version 5. Instead of &lt;code&gt;fa&lt;/code&gt; as a style preceding every icon style, you need to pick from &lt;code&gt;fas&lt;/code&gt; for solid, &lt;code&gt;far&lt;/code&gt; for regular, &lt;code&gt;fal&lt;/code&gt; for light, or &lt;code&gt;fab&lt;/code&gt; for brand. It looks like &lt;code&gt;fas&lt;/code&gt; is the fallback, so you get solid if you leave your old &lt;code&gt;fa&lt;/code&gt; references. For most icons, this change makes the icon heavier or lighter.&lt;/p&gt;
&lt;p&gt;If you are biting your nails thinking of all the places you have icons that will now need to change, you can upgrade to 5 and use a shim.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;script defer src=&amp;quot;https://use.fontawesome.com/releases/v5.0.3/js/v4-shims.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="https://codepen.io/joewilson0/pen/WdmQqy/"&gt;That's better&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;But if you've got the time and the inclination, skip the shim and change your icon classes to take advantage of the new, lighter styles. If I change all the icons in the same from &lt;code&gt;fa&lt;/code&gt; to &lt;code&gt;far&lt;/code&gt; &lt;a href="https://codepen.io/joewilson0/pen/qpvOeb/"&gt;we get this&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;That's one of the other big changes. FontAwesome has lots more icons, but to get all of them, you'll need to &lt;a href="https://fontawesome.com/buy/standard"&gt;buy the PRO version&lt;/a&gt; starting at $60 for 5 seats. I think that's a good deal, but the old icons are still free if you only need those.&lt;/p&gt;
&lt;p&gt;Finally, &lt;a href="https://fontawesome.com/how-to-use/upgrading-from-4#icon-name-changes"&gt;some icons changed names&lt;/a&gt;, and you'll need to swap them out if you don't want to use the shim.&lt;/p&gt;
</description>
      <pubDate>Mon, 22 Jan 2018 06:33:00 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/cache-busting-with-requirejs-and-r-js-in-an-asp-net-mvc-app</guid>
      <link>https://volaresoftware.com/en/technical-posts/cache-busting-with-requirejs-and-r-js-in-an-asp-net-mvc-app</link>
      <title>Cache busting with RequireJS and R.js in an ASP.NET MVC app</title>
      <description>&lt;p&gt;Browser caching is great, except when it's not.  What if you deploy a new version to production, but the fix you made to a JavaScript or CSS file isn't showing up?  How can we force the browser to download files at least once with each build?&lt;/p&gt;
&lt;p&gt;In previous posts, I showed &lt;a href="https://volaresoftware.com/en/technical-posts/adding-requirejs-to-an-aspnet-mvc-project"&gt;how to use RequireJS in an MVC app&lt;/a&gt;, and &lt;a href="https://volaresoftware.com/en/technical-posts/optimizing-javascript-and-css-files-using-requirejs-and-rjs-in-an-aspnet-mvc-app"&gt;how to optimize JavaScript and CSS using r.js&lt;/a&gt; in that project.  Now we'll tackle cache busting to fix this problem.&lt;/p&gt;
&lt;p&gt;The code for this project is available for &lt;a href="https://github.com/VolareSoftware/RequireJSWithMVC"&gt;view/download on GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="concept"&gt;Concept&lt;/h3&gt;
&lt;p&gt;We're going to put a small query string on every optimized JavaScript and CSS file with a unique code tied to that deployment.  I'll use the build number of the main web assembly, since that's easy to get.  The pattern will be like:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;/Scripts-Build/app/main-fileName.js?v=1234
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you don't like using the build number for whatever reason, you can use anything you like, as long as it it changes when you build or deploy the files, but doesn't change all the time.  So something like a build date makes sense, but not the current date/time, because that will always be different on each request.&lt;/p&gt;
&lt;p&gt;Finally, be aware this is not a perfect solution.  If someone is sitting behind a proxy server, they may not see the changes &lt;strong&gt;IF&lt;/strong&gt; the proxy server doesn't honor the query strings and refetch the files.  If that applies in your situation, you may need a path and some extra routing work to get past the proxy with something like:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;/Scripts-Build/app/1234/main-fileName.js
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I'll only be showing the build version style, and I've found that works in most situations.&lt;/p&gt;
&lt;h3 id="getting-the-build-version"&gt;Getting the build version&lt;/h3&gt;
&lt;p&gt;This is not the kind of code you write very often, but here's how I got the build number from the current assembly:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;using System.Globalization;
using System.Reflection;
using System.Web;
using System.Web.Caching;
using System.Web.Mvc;
&lt;p&gt;namespace RequireJSWithMVC.Extensions
{
public static class ApplicationVersionHelpers
{
private const string _assemblyRevisionNumberKey = &amp;quot;AssemblyRevisionNumber&amp;quot;;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    public static string AssemblyRevisionNumber(this HtmlHelper helper)
    {
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;#if (DEBUG)
return string.Empty;
#else
if (HttpRuntime.Cache[_assemblyRevisionNumberKey] == null)
{
var assembly = Assembly.GetExecutingAssembly();
var assemblyRevisionNumber = assembly.GetName().Version.Revision.ToString(CultureInfo.InvariantCulture);&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;            HttpRuntime.Cache.Insert(_assemblyRevisionNumberKey, assemblyRevisionNumber,
                new CacheDependency(assembly.Location));
        }

        return HttpRuntime.Cache[_assemblyRevisionNumberKey] as string;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;#endif
}
}
}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;We are just returning an empty string in Debug mode.  In Release mode, we are caching the build revision number so we don't have to re-lookup that value every time we request it.&lt;/p&gt;
&lt;p&gt;Now we need a way to access this version number from JavaScript.  Let's put this version number in a global variable inside &lt;code&gt;_Layout.cshtml&lt;/code&gt; in the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; section so it's available on every page.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;script&amp;gt;var version = &amp;quot;@Html.AssemblyRevisionNumber()&amp;quot;;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We all know global variables are a sin, so paste it in and say your penance.&lt;/p&gt;
&lt;h3 id="using-the-build-version"&gt;Using the build version&lt;/h3&gt;
&lt;p&gt;In the &lt;a href="https://volaresoftware.com/en/technical-posts/optimizing-javascript-and-css-files-using-requirejs-and-rjs-in-an-aspnet-mvc-app"&gt;previous post&lt;/a&gt;, we had a &lt;code&gt;PathHelpers.cs&lt;/code&gt; file that toggled between the &lt;code&gt;/Scripts&lt;/code&gt; and the &lt;code&gt;/Scripts-Build&lt;/code&gt; and between the &lt;code&gt;/Styles&lt;/code&gt; and the &lt;code&gt;/Styles-Build&lt;/code&gt; folders.  We need to update that to use our version number based on Debug/Release build mode:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;using System.Web;
using System.Web.Mvc;
&lt;p&gt;namespace RequireJSWithMVC.Extensions
{
public static class PathHelpers
{
public static string ScriptsPath(this HtmlHelper helper, string pathWithoutScripts)
{
var fullPath = &amp;quot;&amp;quot;;
#if (DEBUG)
var scriptsPath = &amp;quot;&lt;sub&gt;/Scripts/&amp;quot;;
fullPath = VirtualPathUtility.ToAbsolute(scriptsPath + pathWithoutScripts);
#else
var scriptsPath = &amp;quot;&lt;/sub&gt;/Scripts-Build/&amp;quot;;
fullPath = VirtualPathUtility.ToAbsolute(scriptsPath + pathWithoutScripts + &amp;quot;?v=&amp;quot; + helper.AssemblyRevisionNumber());
#endif
return fullPath;
}&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    public static string StylesPath(this HtmlHelper helper, string pathWithoutStyles)
    {
        var fullPath = &amp;amp;quot;&amp;amp;quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;#if (DEBUG)
var stylesPath = &amp;quot;&lt;sub&gt;/Styles/&amp;quot;;
fullPath = VirtualPathUtility.ToAbsolute(stylesPath + pathWithoutStyles);
#else
var stylesPath = &amp;quot;&lt;/sub&gt;/Styles-Build/&amp;quot;;
fullPath = VirtualPathUtility.ToAbsolute(stylesPath + pathWithoutStyles + &amp;quot;?v=&amp;quot; + helper.AssemblyRevisionNumber());
#endif
return fullPath;
}
}
}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;This covers the &lt;code&gt;_Layout.cshtml&lt;/code&gt; scripts, but  we also need to update &lt;code&gt;RequireJsHelpers.cs&lt;/code&gt;, our helper that is used for page-level scripts and pulls in &lt;code&gt;main.js&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;using System;
using System.Text;
using System.Web;
using System.Web.Mvc;
&lt;p&gt;namespace RequireJSWithMVC.Extensions
{
public static class RequireJsHelpers
{
public static MvcHtmlString InitPageMainModule(this HtmlHelper helper, string pageModule)
{
var require = new StringBuilder();&lt;/p&gt;
&lt;p&gt;#if (DEBUG)
var scriptsPath = &amp;quot;&lt;sub&gt;/Scripts/&amp;quot;;
#else
var scriptsPath = &amp;quot;&lt;/sub&gt;/Scripts-Build/&amp;quot;;
#endif&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;        var absolutePath = VirtualPathUtility.ToAbsolute(scriptsPath);

        require.AppendLine(&amp;amp;quot;&amp;amp;lt;script&amp;amp;gt;&amp;amp;quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;#if (DEBUG)
require.AppendFormat(&amp;quot;    require([&amp;amp;quot;{0}main.js&amp;amp;quot;],&amp;quot; + Environment.NewLine, absolutePath);
#else
require.AppendFormat(&amp;quot;    require([&amp;amp;quot;{0}main.js?v={1}&amp;amp;quot;],&amp;quot; + Environment.NewLine, absolutePath, helper.AssemblyRevisionNumber());
#endif
require.AppendLine(&amp;quot;        function() {&amp;quot;);
require.AppendFormat(&amp;quot;            require([&amp;amp;quot;{0}&amp;amp;quot;, &amp;amp;quot;domReady!&amp;amp;quot;]);&amp;quot; + Environment.NewLine, pageModule);
require.AppendLine(&amp;quot;        }&amp;quot;);
require.AppendLine(&amp;quot;    );&amp;quot;);
require.AppendLine(&amp;quot;&amp;lt;/script&amp;gt;&amp;quot;);&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;        return new MvcHtmlString(require.ToString());
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Both of these now put &lt;code&gt;?v=1234&lt;/code&gt; in the JavaScript or CSS path.&lt;/p&gt;
&lt;p&gt;We still need to do some work so our &lt;code&gt;/app&lt;/code&gt; and &lt;code&gt;/lib&lt;/code&gt; scripts get the same treatment.  We'll do that in main.js by adding this line:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;urlArgs: version === &amp;quot;&amp;quot; ? &amp;quot;&amp;quot; : &amp;quot;v=&amp;quot; + version
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Remember our awful global variable &amp;quot;version&amp;quot; in &lt;code&gt;_Layout.cshtml&lt;/code&gt;?  This is where it's being used.  In my &lt;code&gt;main.js&lt;/code&gt; file, I have this right under the &lt;code&gt;baseUrl&lt;/code&gt; setting:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;require.config({
    baseUrl: &amp;quot;/Scripts/app&amp;quot;,
    urlArgs: version === &amp;quot;&amp;quot; ? &amp;quot;&amp;quot; : &amp;quot;v=&amp;quot; + version
    paths: {
        jquery: &amp;quot;../lib/jquery-2.1.1&amp;quot;,
        jqueryValidate: &amp;quot;../lib/jquery.validate&amp;quot;,
        jqueryValidateUnobtrusive: &amp;quot;../lib/jquery.validate.unobtrusive&amp;quot;,
        bootstrap: &amp;quot;../lib/bootstrap&amp;quot;,
        moment: &amp;quot;../lib/moment&amp;quot;,
        domReady: &amp;quot;../lib/domReady&amp;quot;,
    },
    shim: {
        jqueryValidate: [&amp;quot;jquery&amp;quot;],
        jqueryValidateUnobtrusive: [&amp;quot;jquery&amp;quot;, &amp;quot;jqueryValidate&amp;quot;]
    }
});
&lt;p&gt;require([&amp;quot;kickoff&amp;quot;], function(kickoff) {
kickoff.init();
}
);
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Now you should be able to run the web app in Release mode and get this, with &lt;code&gt;?v=1234&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/cache_bust_with_querystring_js.png" alt="https://cdn.volaresoftware.com/images/posts/2019/12/cache_bust_with_querystring_js.png" /&gt;
&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/cache_bust_with_querystring_css.png" alt="https://cdn.volaresoftware.com/images/posts/2019/12/cache_bust_with_querystring_css.png" /&gt;&lt;/p&gt;
&lt;p&gt;Or run in Debug mode and get this, without the bundling, minification, and the extra query string stuff:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/cache_bust_without_querystring_js.png" alt="https://cdn.volaresoftware.com/images/posts/2019/12/cache_bust_without_querystring_js.png" /&gt;
&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/cache_bust_without_querystring_css.png" alt="https://cdn.volaresoftware.com/images/posts/2019/12/cache_bust_without_querystring_css.png" /&gt;&lt;/p&gt;
&lt;p&gt;If you get this far and your build version in the query strings is 0, you need to update your &lt;code&gt;AssemblyInfo.cs&lt;/code&gt; file:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;[assembly: AssemblyVersion(&amp;quot;1.0.*&amp;quot;)]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;*&lt;/code&gt; is the auto increment of the build revision number.&lt;/p&gt;
</description>
      <pubDate>Sat, 31 May 2014 00:39:24 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/optimizing-bundle-size-with-telerik-asp-net-core-controls-bootstrap-and-webpack</guid>
      <link>https://volaresoftware.com/en/technical-posts/optimizing-bundle-size-with-telerik-asp-net-core-controls-bootstrap-and-webpack</link>
      <title>Optimizing bundle size with Telerik ASP.NET Core controls, Bootstrap, and Webpack</title>
      <description>&lt;p&gt;I am working on a mobile web application project using Telerik ASP.NET Core controls. These are the C# equivalent of the Kendo UI JavaScript controls. In fact, the Telerik ASP.NET Core controls are really Razor and tag helper wrappers that emit JavaScript to the browser to save you from the trouble of writing the JavaScript yourself.&lt;/p&gt;
&lt;p&gt;Because this is a mobile web app that will be used in the field, we want fast page download speeds. Having worked with Kendo UI before, I knew I could import only the components I needed, rather than pull in code for sliders and other components not used in this app.&lt;/p&gt;
&lt;p&gt;We are also using webpack and import only the JavaScript for the Telerik components used in each module.&lt;/p&gt;
&lt;h2 id="styles"&gt;Styles&lt;/h2&gt;
&lt;p&gt;In this project, we have a &lt;code&gt;variables.scss&lt;/code&gt; file where we keep the common Sass variables, a &lt;code&gt;site.scss&lt;/code&gt; files with the site-specific styles and overrides, and a &lt;code&gt;common.scss&lt;/code&gt; file that brings these two project Sass files together with the vendor files - in this case, Bootstrap and Kendo UI styles.&lt;/p&gt;
&lt;p&gt;Notice we are pulling in all Bootstrap styles, but we are not importing every Kendo UI styles or a combined file with all the Kendo UI styles for all the components. We are using only a handful of Kendo UI components in this app, so we don't want the extra weight of all those styles that will never be used in the app.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-scss"&gt;// All variables
@import &amp;quot;variables&amp;quot;;
&lt;p&gt;// Bootstrap
@import &amp;quot;node_modules/bootstrap/scss/bootstrap&amp;quot;;&lt;/p&gt;
&lt;p&gt;// Kendo UI
@import &amp;quot;node_modules/@progress/kendo-theme-bootstrap/scss/autocomplete&amp;quot;;
@import &amp;quot;node_modules/@progress/kendo-theme-bootstrap/scss/grid&amp;quot;;
@import &amp;quot;node_modules/@progress/kendo-theme-bootstrap/scss/combobox&amp;quot;;
@import &amp;quot;node_modules/@progress/kendo-theme-bootstrap/scss/datetime&amp;quot;;&lt;/p&gt;
&lt;p&gt;// Site
@import &amp;quot;site&amp;quot;;
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="scripts"&gt;Scripts&lt;/h2&gt;
&lt;p&gt;The webpack entry points for this web app are pages. It's a multi-page, not a single-page application. Here's what the &lt;code&gt;home.js&lt;/code&gt; page script looks like. It imports the components it needs, which in turn import whatever they need. For this app, the home page is static and shows a splash, and that's about it.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;import &amp;quot;common.scss&amp;quot;;
import $ from &amp;quot;jquery&amp;quot;;
import &amp;quot;components/top-menu&amp;quot;;
import &amp;quot;components/header&amp;quot;;
import &amp;quot;components/footer&amp;quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here's the script for &lt;code&gt;search.js&lt;/code&gt; a page that uses the Kendo UI autocomplete search and a gid to show search results. It also uses the Bootstrap alert module to show the user if there are no records found in the search.&lt;/p&gt;
&lt;p&gt;Finally, I had to import &lt;code&gt;@progress/kendo-ui/js/kendo.aspnetmvc&lt;/code&gt; in the page's JavaScript module. This is the secret sauce to get client-side behavior from server-side Telerik ASP.NET Core controls we used in Razor views (below).&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;import &amp;quot;common.scss&amp;quot;;
import $ from &amp;quot;jquery&amp;quot;;
import &amp;quot;components/top-menu&amp;quot;;
import &amp;quot;components/header&amp;quot;;
import &amp;quot;components/footer&amp;quot;;
import &amp;quot;bootstrap/js/dist/alert&amp;quot;;
import &amp;quot;@progress/kendo-ui/js/kendo.autocomplete&amp;quot;;
import &amp;quot;@progress/kendo-ui/js/kendo.grid&amp;quot;;
import &amp;quot;@progress/kendo-ui/js/kendo.aspnetmvc&amp;quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="razor"&gt;Razor&lt;/h2&gt;
&lt;p&gt;The Razor views were like normal ASP.NET Razor views or pages, but with client-side behavior coming from the page's &lt;code&gt;import &amp;quot;@progress/kendo-ui/js/kendo.aspnetmvc&amp;quot;;&lt;/code&gt;. This means you can sort or filter the results in a grid without a server call, but you don't have to write all the JavaScript client code to handle that.&lt;/p&gt;
&lt;p&gt;We tried the Telerik ASP.NET Core control tag-helpers, and I kind of prefer the syntax, but we quickly found there were not enough examples on the Telerik site or out in the wild to figure out the API. Guessing got pretty old pretty fast, so we went to the more traditional HTML helper syntac in the Razor code.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;&amp;lt;form id=&amp;quot;searchForm&amp;quot; asp-controller=&amp;quot;Search&amp;quot; asp-action=&amp;quot;Index&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;
    &amp;lt;div class=&amp;quot;input-group&amp;quot;&amp;gt;
        @(
        Html.Kendo().AutoComplete()
            .Name(&amp;quot;searchText&amp;quot;)
            .DataTextField(&amp;quot;HitString&amp;quot;)
            .HtmlAttributes(new {@class=&amp;quot;form-control&amp;quot;})
            .DataSource(source =&amp;gt;
            {
                source.Read(read =&amp;gt;
                {
                    read.Action(&amp;quot;GetAutoCompleteAccounts&amp;quot;, &amp;quot;Search&amp;quot;).Data(&amp;quot;() =&amp;gt; { return { text: $('#searchText').val() }; }&amp;quot;);
                }).ServerFiltering(true);
            })
            .Placeholder(&amp;quot;Address, Owner Name, Legal Description, Account Number, or Parcel Number&amp;quot;)
            .Value(Model)
            .Filter(FilterType.Contains)
            .MinLength(2)
        )
        &amp;lt;div class=&amp;quot;input-group-append&amp;quot;&amp;gt;
            &amp;lt;button type=&amp;quot;submit&amp;quot; class=&amp;quot;btn btn-primary text-light&amp;quot;&amp;gt;
                &amp;lt;span class=&amp;quot;fas fa-search&amp;quot;&amp;gt;&amp;lt;/span&amp;gt; Search
            &amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="optimizing"&gt;Optimizing&lt;/h2&gt;
&lt;p&gt;When webpack starts build the entry points, in this case, &lt;code&gt;home.js&lt;/code&gt; and &lt;code&gt;search.js&lt;/code&gt;, it grabs only the styles in &lt;code&gt;common.scss&lt;/code&gt; and only the modules in the pages and the components they use, so we get a smaller bundle than if we put style and script links in the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; section of the &lt;code&gt;_Layout.cshtml&lt;/code&gt; page.&lt;/p&gt;
</description>
      <pubDate>Mon, 21 Dec 2020 07:45:51 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/getting-the-sql-and-parameters-out-of-dapper-for-display-in-glimpse</guid>
      <link>https://volaresoftware.com/en/technical-posts/getting-the-sql-and-parameters-out-of-dapper-for-display-in-glimpse</link>
      <title>Getting the SQL and Parameters out of Dapper for display in Glimpse</title>
      <description>&lt;p&gt;&lt;a href="http://getglimpse.com/"&gt;Glimpse&lt;/a&gt; is a really nice tracing and diagnostic tool for what's happening on the server in an ASP.NET app.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2013/9/image_58.png" alt="https://cdn.volaresoftware.com/images/posts/2013/9/image_58.png" /&gt;&lt;/p&gt;
&lt;p&gt;It has a tab for showing the SQL and the query parameters being passed to SQL Server, but my tab looked like this when using &lt;a href="https://www.nuget.org/packages/Dapper"&gt;Dapper dot net&lt;/a&gt;, a light-weight ORM that takes your SQL result and maps it to a C# object:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2013/9/image_59.png" alt="https://cdn.volaresoftware.com/images/posts/2013/9/image_59.png" /&gt;&lt;/p&gt;
&lt;p&gt;I knew Glimpse worked with ADO.NET, I had installed that &lt;a href="http://www.nuget.org/packages/Glimpse.Ado/"&gt;plugin&lt;/a&gt;, and Dapper was using ADO.NET somewhere inside its framework, but my SQL tab was disabled.  I thought maybe I needed to install a Glimpse Dapper plugin, but there was none on &lt;a href="http://getglimpse.com/Packages"&gt;the official Glimpse plugins page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I found &lt;a href="http://www.codelyfe.com/Blog/Entry/View/3"&gt;this unofficial Glimpse Dapper plugin&lt;/a&gt;, but it still seemed like it was trying too hard.  This should be easier.&lt;/p&gt;
&lt;p&gt;I was getting my Dapper SQL connection through a factory like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public static class ConnectionFactory
{
    public static IDbConnection CreateConnection(string connectionString)
    {
        var cnn = new SqlConnection(connectionString);
        cnn.Open();
&lt;pre&gt;&lt;code&gt;    return cnn;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;I finally found the &lt;a href="http://getglimpse.com/Help/ADO-Integration"&gt;Glimpse ADO integration help&lt;/a&gt;, and it said, &amp;quot;If you're not using an ADO connection that uses the &lt;a href="http://msdn.microsoft.com/en-us/library/system.data.common.dbproviderfactories.aspx"&gt;DbProviderFactories&lt;/a&gt; class, Glimpse won't collect any data for the SQL tab (out of the box).&amp;quot;&lt;/p&gt;
&lt;p&gt;Oh.  Ok.  So I changed my code to this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public static class ConnectionFactory
{
    public static IDbConnection CreateConnection(string connectionString)
    {
        var factory = DbProviderFactories.GetFactory(&amp;quot;System.Data.SqlClient&amp;quot;);
        var cnn = factory.CreateConnection();
        cnn.ConnectionString = connectionString;
        cnn.Open();
&lt;pre&gt;&lt;code&gt;    return cnn;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;and now the SQL and parameters are showing on the Glimpse SQL tab:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2013/9/image_61.png" alt="https://cdn.volaresoftware.com/images/posts/2013/9/image_61.png" /&gt;&lt;/p&gt;
&lt;p&gt;Yay!&lt;/p&gt;
</description>
      <pubDate>Mon, 02 Sep 2013 22:49:00 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/evolution-of-a-view-in-aspnet-mvc</guid>
      <link>https://volaresoftware.com/en/technical-posts/evolution-of-a-view-in-aspnet-mvc</link>
      <title>Evolution of a View in ASP.NET MVC</title>
      <description>&lt;p&gt;Many developers prefer working with ASP.NET MVC over Web Forms because they are more connected with the HTML, have better control over the rendered output, and can easily build their own HTML helpers to get consistent output.&lt;/p&gt;
&lt;p&gt;But making the views can be a hassle when your building a CRUD app or something that has a lot of very similar views.  Let's look at some ways around that you can use today and in the future.&lt;/p&gt;
&lt;h2 id="past"&gt;Past&lt;/h2&gt;
&lt;p&gt;When MVC first came out, most people were coding their inputs in views like this.  Just straight HTML with some helpers:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-aspnet"&gt;&amp;lt;% using (Html.BeginForm()) { %&amp;gt;
  &amp;lt;fieldset&amp;gt;	
    &amp;lt;label for=&amp;quot;Name&amp;quot;&amp;gt;Name&amp;lt;/label&amp;gt; &amp;lt;%= Html.TextBox(&amp;quot;Name&amp;quot;) %&amp;gt;	
    &amp;lt;label for=&amp;quot;Email&amp;quot;&amp;gt;Email address&amp;lt;/label&amp;gt; &amp;lt;%= Html.TextBox(&amp;quot;Email&amp;quot;) %&amp;gt;	
    &amp;lt;label for=&amp;quot;Phone&amp;quot;&amp;gt;Phone&amp;lt;/label&amp;gt; &amp;lt;%= Html.TextBox(&amp;quot;Phone&amp;quot;) %&amp;gt;	
    &amp;lt;%= Html.SubmitButton() %&amp;gt;
  &amp;lt;/fieldset&amp;gt;
&amp;lt;% } %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Simple, but a little too much reliance on strings.  This made the code error prone, so developers made their own HTML Helpers to crank out consistent views with fewer strings by using lambda expressions:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-aspnet"&gt;&amp;lt;% using (Html.BeginForm()) { %&amp;gt;
  &amp;lt;fieldset&amp;gt;	
    &amp;lt;label for=&amp;quot;Name&amp;quot;&amp;gt;Name&amp;lt;/label&amp;gt; &amp;lt;%= Html.TextBoxFor(c =&amp;gt; c.Name) %&amp;gt;	
    &amp;lt;label for=&amp;quot;Email&amp;quot;&amp;gt;Email address&amp;lt;/label&amp;gt; &amp;lt;%= Html.TextBoxFor(c =&amp;gt; c.Email) %&amp;gt; 	
    &amp;lt;label for=&amp;quot;Phone&amp;quot;&amp;gt;Phone&amp;lt;/label&amp;gt; &amp;lt;%= Html.TextBoxFor(c =&amp;gt; c.Phone) %&amp;gt; 
    &amp;lt;%= Html.SubmitButton() %&amp;gt;
  &amp;lt;/fieldset&amp;gt;
&amp;lt;% } %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That's better.  We get IntelliSense for the model's fields and we get the leave some of the strings behind.&lt;/p&gt;
&lt;h2 id="present"&gt;Present&lt;/h2&gt;
&lt;p&gt;The next step was to get rid of some of those label statements and get those rolled into the output automatically.  They did this in &lt;a href="http://code.google.com/p/codecampserver/"&gt;Code Camp Server&lt;/a&gt; and you can see the step-by-step progression in &lt;a href="http://www.lostechies.com/blogs/hex/archive/2009/06/09/opinionated-input-builders-for-asp-net-mvc-using-partials-part-i.aspx"&gt;Eric Hexter's blog&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-aspnet"&gt;&amp;lt;% using (Html.BeginForm()) { %&amp;gt;
  &amp;lt;fieldset&amp;gt;	
    &amp;lt;%= Html.Input(c =&amp;gt; c.Name) %&amp;gt;	
    &amp;lt;%= Html.Input(c =&amp;gt; c.Email) %&amp;gt; 	
    &amp;lt;%= Html.Input(c =&amp;gt; c.Phone) %&amp;gt; 	
    &amp;lt;%= Html.SubmitButton() %&amp;gt;
  &amp;lt;/fieldset&amp;gt;
&amp;lt;% } %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nice!  Now we're on the road to consistent output in all forms in our MVC app and we won't spend as much time typing up view code.  Eric even shows us &lt;a href="http://www.lostechies.com/blogs/hex/archive/2009/06/17/opinionated-input-builders-part-8-the-auto-form.aspx"&gt;he can name that view in one note&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-aspnet"&gt;&amp;lt;%= Html.InputForm() %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="future"&gt;Future&lt;/h2&gt;
&lt;p&gt;If you've been following the latest on ASP.NET MVC, you've seen the announcement for MVC 2 Preview 1 &lt;a href="http://weblogs.asp.net/scottgu/archive/2009/07/31/asp-net-mvc-v2-preview-1-released.aspx"&gt;here&lt;/a&gt;, &lt;a href="http://www.hanselman.com/blog/HanselminutesOn9ASPNETMVC2Preview1Released.aspx"&gt;here&lt;/a&gt;, and &lt;a href="http://haacked.com/archive/2009/07/30/asp.net-mvc-released.aspx"&gt;here&lt;/a&gt;.  Microsoft is going the same direction as these open-source extensions and making it easier to get a consistent view rendered:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-aspnet"&gt;&amp;lt;% using (Html.BeginForm()) { %&amp;gt;
  &amp;lt;fieldset&amp;gt;	
    &amp;lt;%= Html.LabelFor(c =&amp;gt; c.Name) %&amp;gt;	
    &amp;lt;%= Html.EditorFor(c =&amp;gt; c.Name) %&amp;gt;	
    &amp;lt;%= Html.LabelFor(c =&amp;gt; c.Email) %&amp;gt;	
    &amp;lt;%= Html.EditorFor(c =&amp;gt; c.Email) %&amp;gt; 	
    &amp;lt;%= Html.LabelFor(c =&amp;gt; c.Phone) %&amp;gt;	
    &amp;lt;%= Html.EditorFor(c =&amp;gt; c.Phone) %&amp;gt; 	
    &amp;lt;%= Html.SubmitButton() %&amp;gt;
  &amp;lt;/fieldset&amp;gt;
&amp;lt;% } %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;MVC 2 also has an almost one-liner form that you define with templates, one of the new features:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-aspnet"&gt;&amp;lt;% using (Html.BeginForm()) { %&amp;gt;
  &amp;lt;fieldset&amp;gt;	
    &amp;lt;%= Html.EditorFor(c =&amp;gt; c) %&amp;gt;
    &amp;lt;%= Html.SubmitButton() %&amp;gt;
  &amp;lt;/fieldset&amp;gt;
&amp;lt;% } %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So we've seen views getting simpler and smaller and even one-line forms.  Can it get any smaller than a one-line form?  What if there was no view?  Can you have a view with &lt;strong&gt;zero&lt;/strong&gt; lines of code?&lt;/p&gt;
&lt;p&gt;Kind of.  &lt;a href="http://haacked.com/archive/2009/08/04/default-templated-views.aspx"&gt;Phil Haack&lt;/a&gt; took the MVC 2 Preview 1 code out for a spin to try what he calls &amp;quot;default templated views&amp;quot;.  The idea is that your controller gets a model and displays a virtual view by using templates from your web project's &amp;quot;~\Views\Shared&amp;quot; folder.  You can make as many templates as you need for different purposes.&lt;/p&gt;
&lt;p&gt;This is ideal for CRUD apps or places in your app where the view is the same except for the model data it renders.  You don't need a physical file for each view other than the template itself.  The controller just renders a view that is one of the shared views/templates.&lt;/p&gt;
&lt;p&gt;I like this approach because you can crank out code more quickly for the easy stuff, but if you have a view that needs something more complex, you still have the normal HTML inputs and helpers to fall back on.  I hope Microsoft gets this idea fully flushed out and it ends up in the final MVC 2 release.  It would make developers more productive on repetitive views and would have wider acceptance if it was in the MVC base-class libraries.&lt;/p&gt;
</description>
      <pubDate>Tue, 08 Dec 2009 05:00:00 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/combining-batch-edit-and-detail-template-edit-on-a-kendo-ui-grid</guid>
      <link>https://volaresoftware.com/en/technical-posts/combining-batch-edit-and-detail-template-edit-on-a-kendo-ui-grid</link>
      <title>Combining batch edit and detail template edit on a Kendo UI grid</title>
      <description>&lt;p&gt;A client recently asked for something I didn't know a Kendo UI grid could do. They wanted &lt;strong&gt;both&lt;/strong&gt; batch edit and a detail/expand edit of the &lt;strong&gt;same record&lt;/strong&gt; in the grid.&lt;/p&gt;
&lt;p&gt;They liked the Excel-like editing experience of working in batch mode, where you make a bunch of edits and send all the changes at once. But they also wanted several  UI features in the expanded/detail view that don't make sense in a grid row (e.g., charts, hyperlinks, buttons to calculate things, etc.). The idea was that users could use whatever fit their needs or preference, then save all grid changes as usual in a batch.&lt;/p&gt;
&lt;p&gt;I got it mostly working with this code, which is using this HTML and JavaScript: &lt;a href="https://jsfiddle.net/joewilson0/jwcLhtg2/"&gt;https://jsfiddle.net/joewilson0/jwcLhtg2/&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;div id=&amp;quot;myGrid&amp;quot;&amp;gt;&amp;lt;/div&amp;gt; 
&lt;p&gt;&amp;lt;script type=&amp;quot;text/x-kendo-template&amp;quot; id=&amp;quot;myDetailTemplate&amp;quot;&amp;gt;
&amp;lt;div class=&amp;quot;form-group&amp;quot;&amp;gt;
&amp;lt;label for=&amp;quot;testNumber&amp;quot;&amp;gt;Test Number&amp;lt;/label&amp;gt;
&amp;lt;input name=&amp;quot;testNumber&amp;quot; class=&amp;quot;form-control w-25&amp;quot; data-bind=&amp;quot;value: testNumber&amp;quot; /&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div class=&amp;quot;form-group&amp;quot;&amp;gt;
&amp;lt;label for=&amp;quot;testString&amp;quot;&amp;gt;Test String&amp;lt;/label&amp;gt;
&amp;lt;input name=&amp;quot;testString&amp;quot; class=&amp;quot;form-control w-25&amp;quot; data-bind=&amp;quot;value: testString&amp;quot; /&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div class=&amp;quot;form-group&amp;quot;&amp;gt;
&amp;lt;label for=&amp;quot;testDate&amp;quot; class=&amp;quot;d-block&amp;quot;&amp;gt;Test Date&amp;lt;/label&amp;gt;
&amp;lt;input name=&amp;quot;testDate&amp;quot; class=&amp;quot;form-control&amp;quot; data-bind=&amp;quot;value: testDate&amp;quot; data-role=&amp;quot;datepicker&amp;quot; /&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;$(document).ready(() =&amp;gt; {
  const testData = [
    { testNumber: 123, testString: &amp;quot;apple&amp;quot;, testDate: new Date(2020, 10, 14) },
    { testNumber: 456, testString: &amp;quot;pear&amp;quot;, testDate: new Date(2020, 10, 15) },
    { testNumber: 789, testString: &amp;quot;plum&amp;quot;, testDate: new Date(2020, 10, 16) },
  ];

  $(&amp;quot;#myGrid&amp;quot;).kendoGrid({
    dataSource: {
      data: testData,
      schema: {
        model: {
          fields: {
            testNumber: { type: &amp;quot;number&amp;quot; },
            testString: { type: &amp;quot;string&amp;quot; },
            testDate: { type: &amp;quot;date&amp;quot; }
          }
        }
      }
    },
    columns: [
      { field: &amp;quot;testNumber&amp;quot;, title: &amp;quot;Test Number&amp;quot; },
      { field: &amp;quot;testString&amp;quot;, title: &amp;quot;Test String&amp;quot; },
      { field: &amp;quot;testDate&amp;quot;, title: &amp;quot;Test Date&amp;quot;, format: &amp;quot;{0:d}&amp;quot; }
    ],
    editable: true,
    detailTemplate: kendo.template($(&amp;quot;#myDetailTemplate&amp;quot;).html()),
    detailInit: event =&amp;gt; kendo.bind(event.detailRow, event.data)
  });
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This line is the key to having the grid row and the expanded view share the same view model:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;detailInit: event =&amp;gt; kendo.bind(event.detailRow, event.data)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now when you change a value in the grid row, it updates immediately in the expanded row. Great! But when you do the reverse, and update the expanded row value, the grid row updates, but the expanded row immediately collapses. Arg!&lt;/p&gt;
&lt;p&gt;The fix to prevent closing the expanded row was to ignore the &lt;code&gt;itemchange&lt;/code&gt; action in the &lt;code&gt;dataBinding&lt;/code&gt; event:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;function dataBinding(event) {
    // Prevent closing the expanded detail row when the itemchange action in the databinding event is fired so it doesn't close the expanded view
    if (event.action === &amp;quot;itemchange&amp;quot;) {
        event.preventDefault();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But this workaround fixes one thing and breaks another. Now the row doesn't collapse every time you change a value in the expanded view, but it also doesn't update the grid row values when you collapse because you just short-circuited that event.&lt;/p&gt;
&lt;p&gt;To fix this new problem, I added a &amp;quot;Done&amp;quot; button to the template that collapses the expanded row and wired up a function to repaint the values in the grid row on collapse.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;button class=&amp;quot;btn btn-secondary btn-collapse&amp;quot;&amp;gt;Done&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If the user changes 3 things in the expanded view and keeps the expanded view open, the grid row still shows the original, unchanged values. Once the user clicks the &amp;quot;Done&amp;quot; button or collapses the expanded view with the icon on the left, the grid row is repainted with the values from the shared view model.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;function repaintRow(row) {
    const grid = $(row).closest(&amp;quot;.k-grid&amp;quot;).data(&amp;quot;kendoGrid&amp;quot;);
    const dataItem = grid.dataItem(row);
    const rowChildren = $(row).children(&amp;quot;td[role='gridcell']&amp;quot;);
&lt;pre&gt;&lt;code&gt;for (let i = 0; i &amp;amp;lt; grid.columns.length; i++) {
    const column = grid.columns[i];
    const template = column.template;
    const cell = rowChildren.eq(i);

    if (column.field !== undefined) {
        if (template !== undefined) {
            // Handle templated columns
            const kendoTemplate = kendo.template(template);
            cell.html(kendoTemplate(dataItem));
        } else {
            const fieldValue = dataItem[column.field];
            const format = column.format;
            const values = column.values;

            if (fieldValue &amp;amp;amp;&amp;amp;amp; values) {
                // Handle drop downs
                for (let j = 0; j &amp;amp;lt; values.length; j++) {
                    const value = values[j];
                    if (value.value === fieldValue.toString()) {
                        cell.html(value.text);
                        break;
                    }
                }
            } else if (format !== undefined) {
                // Handle formatted columns (like dates and currency)
                cell.html(kendo.format(format, fieldValue));
            } else {
                // Handle unformatted, untemplated, non-drop down values
                cell.html(fieldValue);
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Now we have to wire up the Kendo UI grid and button events:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;$(&amp;quot;#myGrid&amp;quot;).kendoGrid({
     ...other grid settings...
    detailInit: detailInit,
    detailCollapse: detailCollapse,
    dataBinding: dataBinding,
    ...other grid settings...
});
&lt;p&gt;function detailInit(event) {
const grid = $(event.masterRow).closest(&amp;quot;.k-grid&amp;quot;).data(&amp;quot;kendoGrid&amp;quot;);
const masterRow = event.masterRow;
const detailRow = event.detailRow;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Bind the expanded view (detailRow) to the values in the master row
kendo.bind(detailRow, event.data);    

// Handle the detail row &amp;amp;quot;Done&amp;amp;quot; button click
detailRow.find(&amp;amp;quot;.btn-collapse&amp;amp;quot;).click(() =&amp;amp;gt; grid.collapseRow(masterRow));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Here's the final working version that keeps the Kendo UI grid row and the expanded view in sync: &lt;a href="https://jsfiddle.net/joewilson0/e3p70jac/2/"&gt;https://jsfiddle.net/joewilson0/e3p70jac/2/&lt;/a&gt;&lt;/p&gt;
</description>
      <pubDate>Sat, 13 Feb 2021 07:11:25 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/do-we-still-need-coding-standards</guid>
      <link>https://volaresoftware.com/en/technical-posts/do-we-still-need-coding-standards</link>
      <title>Do we still need coding standards?</title>
      <description>&lt;h2 id="the-dark-ages"&gt;The dark ages&lt;/h2&gt;
&lt;p&gt;I used to be &lt;strong&gt;really&lt;/strong&gt; big on coding standards in the late 1990's.  It was so easy to slip into spaghetti code in classic ASP and VB6, and at the time, the best antidote was rigid standards and uncompromising code reviews.&lt;/p&gt;
&lt;p&gt;I was a hard ass about our coding standards.  Then, as now, the rationale was that coding standards would make the code easier to read and maintain in the inevitable and long maintenance phase.&lt;/p&gt;
&lt;p&gt;The development process we used at the time was to stand around the white board and talk about the development tasks, then the developers would go off and separately code it up.  That was the other reason the coding standards mattered - we didn't want two code files to look totally different if written by different developers.&lt;/p&gt;
&lt;p&gt;My teams used the naming conventions Microsoft came up with for Access/VBA/VB, including Hungarian notation prefixes, but a lot of the standards were about code comments, error handling code, whitespace and indenting, etc.&lt;/p&gt;
&lt;h2 id="net-comes-on-the-scene"&gt;.NET comes on the scene&lt;/h2&gt;
&lt;p&gt;Fast forward maybe 5 or so years to the introduction of .NET and C#, and coding changed.  ASP.NET HTML didn't require &amp;lt;% %&amp;gt; tags anymore.  We could put the C# in code behind files and other project files.  We didn't need On Error anymore, we had Try-Catch.  XML comments seemed like a cool feature to show Intellisense drop downs for code &lt;strong&gt;you&lt;/strong&gt; wrote in addition to framework Intellisense.&lt;/p&gt;
&lt;p&gt;So we updated our coding standards to reflect the language and IDE changes, but they became more like guidelines instead of hard and fast rules.  By convention, we would avoid the spaghetti code just by keeping the right code in the right place.  Hungarian notation went away (slowly but surely).  The coding standards document was mostly reference code snippets and justifications for the conventions we used.  Code reviews became less common because it wasn't as big of an issue.&lt;/p&gt;
&lt;h2 id="today"&gt;Today&lt;/h2&gt;
&lt;p&gt;A lot has changed since .NET first came out, and I code differently now.  I'm trying to make my code a lot more terse these days.  I'm a big fan of having clean, succinct, expressive code.  The fewer non-essential things on the screen to wade through, the better.  It's more readable and easier to refactor.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I could put Try-Catch blocks everywhere, but isn't it simpler to &lt;a href="https://volaresoftware.com/en/technical-posts/handling-exceptions-in-aspnet-mvc"&gt;catch unhandled exceptions in one place&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;I could add XML comments, but why?  It's either code in my same web project or a project that is owned by my solution.  I don't usually work on common library code where an assembly will be used across projects and Intellisense might be needed.&lt;/li&gt;
&lt;li&gt;I don't put the variable type on the left side of the equal sign anymore and use &amp;quot;var&amp;quot; instead.&lt;/li&gt;
&lt;li&gt;I've walked away from code regions and just order the items in the class file by convention.  &lt;a href="http://www.jetbrains.com/resharper/"&gt;ReSharper&lt;/a&gt; likes to put new fields under the last field declaration in the class, so region wrapping all the fields in a class with &amp;quot;#region Fields&amp;quot; just wastes time when refactoring to pull it back up into the region.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Not only has the way I code changed, but the tools have changed. ReSharper code cleanup templates and &lt;a href="http://stylecopforresharper.codeplex.com/"&gt;StyleCop&lt;/a&gt; warnings can be used to keep your team writing code in a style that you've all agreed on.  Just run the tool and have it clean up the code for you or flag code that doesn't meet the style guidelines.&lt;/p&gt;
&lt;p&gt;Having tests around the code lets me refactor and use auto-code-cleanup tools freely.  I understand the project a little more fully every day, so I can rename my class, method, and variable names to be more descriptive and accurate without worrying about breaking code.&lt;/p&gt;
&lt;p&gt;I'm also doing more pair programming these days, and this is a good way to enforce and socialize team coding styles.  It also means we don't have to refer to a coding standards document as often.  Since we're more story-focused, we're thinking more about the feature and less about coding style.  Taking ceremony code off the screen helps us keep that focus.&lt;/p&gt;
&lt;h2 id="if-i-had-to-do-it-over"&gt;If I had to do it over&lt;/h2&gt;
&lt;p&gt;If I was going to write a coding standards document today, it would be more like a style guide to reflect my current less-is-more thinking, and I'd probably give my peers a ReSharper template to auto-clean their code as they go instead of a document to refer to.  &lt;a href="http://stylecopforresharper.codeplex.com/wikipage?title=Overview"&gt;StyleCop for ReSharper&lt;/a&gt; looks promising as a gentle background reminder of team coding styles.&lt;/p&gt;
&lt;p&gt;What about your team?  Do you have a coding standards document people refer to?  Do you use tools to enforce standards/styles? Does your &lt;a href="https://www.g2i.co/blog/telling-a-story-with-your-code"&gt;code tell a story&lt;/a&gt; other developers can read?&lt;/p&gt;
</description>
      <pubDate>Thu, 08 Jul 2010 00:40:47 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/making-spiffy-buttons-with-css-and-mvc-razor-helpers</guid>
      <link>https://volaresoftware.com/en/technical-posts/making-spiffy-buttons-with-css-and-mvc-razor-helpers</link>
      <title>Making spiffy buttons with CSS and MVC Razor helpers</title>
      <description>&lt;p&gt;For most web apps, gray buttons with black text is fine.  But if you take some time to jazz up your buttons a little, you are making your app a little nicer to use and giving your users small visual cues to let them know their options.&lt;/p&gt;
&lt;p&gt;Going from this:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2012/9/image_13.png" alt="image_13.png" /&gt;&lt;/p&gt;
&lt;p&gt;to this:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2012/9/image_16.png" alt="image_16.png" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2012/9/image_14.png" alt="image_14.png" /&gt;&lt;/p&gt;
&lt;p&gt;with hover colors of green and red, which, in the U.S. at least, usually mean &amp;quot;go&amp;quot; and &amp;quot;stop&amp;quot;, can be just enough of a nudge to help your users and make them just a little happier.  Here's how I built these.&lt;/p&gt;
&lt;h2 id="credit"&gt;Credit&lt;/h2&gt;
&lt;p&gt;The bulk of the concept and CSS work for this came from someone else, but I can't remember who anymore.  It's been over a year since I started using this technique.  It might be from an old version of &lt;a href="http://html5boilerplate.com/"&gt;HTML5 Boilerplate&lt;/a&gt;, &lt;a href="http://www.blueprintcss.org/"&gt;Blueprint CSS&lt;/a&gt;, &lt;a href="http://960.gs/"&gt;960 Grid System&lt;/a&gt;, or something Rob Conery did on &lt;a href="http://tekpub.com/"&gt;TekPub&lt;/a&gt;.  I wish I could give more specific attribution, but it was probably one of these.  My main contributions have been some CSS tweaks, the JavaScript, and the MVC Razor helpers.&lt;/p&gt;
&lt;h2 id="html-and-images"&gt;HTML and images&lt;/h2&gt;
&lt;p&gt;This is what we're going for as the emitted HTML.  We want these &amp;quot;buttons&amp;quot; to really be hyperlinks, not HTML buttons, so we don't have as much browser style sheet nonsense getting in the way.&lt;/p&gt;
&lt;p&gt;This does add some complexity for submitting, which has to be done with JavaScript now, but the same script (see below) can be used throughout the app.&lt;/p&gt;
&lt;p&gt;The positive CSS class gives the green hover effect, and the negative one gives the red effect.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;div class=&amp;quot;buttons&amp;quot;&amp;gt;
    &amp;lt;a href=&amp;quot;#&amp;quot; class=&amp;quot;button positive&amp;quot;&amp;gt;
        &amp;lt;img width=&amp;quot;16&amp;quot; height=&amp;quot;16&amp;quot; src=&amp;quot;/Content/Images/Icons/tick.png&amp;quot; alt=&amp;quot;&amp;quot;&amp;gt;
        Save
    &amp;lt;/a&amp;gt;
    &amp;lt;a href=&amp;quot;https://volaresoftware.com/en/posts/archive&amp;quot; class=&amp;quot;button negative&amp;quot;&amp;gt;
        &amp;lt;img width=&amp;quot;16&amp;quot; height=&amp;quot;16&amp;quot; src=&amp;quot;/Content/Images/Icons/cross.png&amp;quot; alt=&amp;quot;&amp;quot;&amp;gt;
        Cancel
    &amp;lt;/a&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The icons I used are from the &lt;a href="http://www.famfamfam.com/lab/icons/silk/"&gt;Silk Icons&lt;/a&gt; collection.  There are lots of great icon libraries out there, so use your favorite.  Anything 16x16 should work, but you can go bigger or smaller and adjust the CSS and &lt;code&gt;HtmlHelper&lt;/code&gt; tags.&lt;/p&gt;
&lt;h2 id="javascriptjquery"&gt;JavaScript/jQuery&lt;/h2&gt;
&lt;p&gt;An anchor tag with a href to &amp;quot;#&amp;quot; won't get your values submitted back to the server, so we'll use some JavaScript and a touch of jQuery for that.  You'll want to include this script on every page where you're using these buttons.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;$(function () {
    global.initButtons();
});
&lt;p&gt;var global = {
initButtons: function () {
$('a.button.positive').click(function (e) {
e.preventDefault();
var parentForm = $(this).closest('form');
if (!parentForm.valid()) {
global.flashMessage('Error validating these values', 'error');
}
else {
$(this).css(global.disableCss).unbind('click');
parentForm.submit();
}
});
},
disableCss: { opacity: 0.5, display: 'inline-block' }
};
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="css"&gt;CSS&lt;/h2&gt;
&lt;p&gt;The CSS for this is pretty simple.  The div.buttons puts the buttons on one line and give a little vertical space around them.  The .button and .button img styles do most of the work, with block styling, light and medium gray borders, a light gray background, some padding around the text and icon to fatten the button up a little, margins so there is space before the next adjacent button on the right, and a small shadow effect.&lt;/p&gt;
&lt;p&gt;The :hover effects are where the color is flipped to darker gray, green, or red, with corresponding border colors.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-css"&gt;/*--------------------------*/
/* Buttons
/*--------------------------*/
div.buttons
{
    display: inline-block;
    margin: 10px 0;
}
.button
{
    display: block;
    float: left;
    border-top: 1px solid #CCC;
    border-left: 1px solid #CCC;
    border-bottom: 1px solid #AAA;
    border-right: 1px solid #AAA;
    background-color: #E3E3E3;
    font-family: Verdana, Helvetica, sans-serif;
    font-size: 100%;
    line-height: 110%;
    text-decoration: none !important;
    color: #333 !important;
    margin: 0 15px 0 0;
    padding: 5px 10px 5px 7px;
    cursor: pointer;
    box-shadow: 1px 1px 2px #969696;
    -moz-box-shadow: 1px 1px 2px #969696; /* Firefox */
    -webkit-box-shadow: 1px 1px 2px #969696; /* Safari and Chrome */
}
.button img
{
    margin: 0 3px -3px 0 !important;
    padding: 0;
    border: none;
    width: 16px;
    height: 16px;
    float: none;
}
&lt;p&gt;/&lt;em&gt;--------------------------&lt;/em&gt;/
/* Button colors - Standard
/&lt;em&gt;--------------------------&lt;/em&gt;/
.button:hover
{
border: 1px solid #999;
background-color: #D6D6D6;
color: #333 !important;
}&lt;/p&gt;
&lt;p&gt;/&lt;em&gt;--------------------------&lt;/em&gt;/
/* Button colors - Positive
/&lt;em&gt;--------------------------&lt;/em&gt;/
.positive:hover
{
background-color: #E6EFC2;
border: 1px solid #C6D880;
color: #264409 !important;
}&lt;/p&gt;
&lt;p&gt;/&lt;em&gt;--------------------------&lt;/em&gt;/
/* Button colors - Negative
/&lt;em&gt;--------------------------&lt;/em&gt;/
.negative:hover
{
background-color: #FBE3E4;
border: 1px solid #FBC2C4;
color: #8A1F11 !important;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="mvc-razor-htmlhelpers"&gt;MVC Razor HtmlHelpers&lt;/h2&gt;
&lt;p&gt;So now we know the HTML and CSS we want.  You could stop there and code your MVC views with that HTML.  But if you want your Razor views to be able to user simple helpers like this, keep reading.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-aspnet"&gt;&amp;lt;div class=&amp;quot;buttons&amp;quot;&amp;gt;
    @Html.LinkButtonForSave()
    @Html.LinkButtonForCancel()
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The helpers here have two public entry points, &lt;code&gt;LinkButtonForSave&lt;/code&gt; and &lt;code&gt;LinkButtonForCancel&lt;/code&gt;. The rest of the code is refactoring out some of the route parsing and tag building work.  It's probably overkill for just these two methods, but it makes sense when you keep adding helpers for other buttons, like add, edit, delete, confirm, print, etc.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;using System.Web;
using System.Web.Mvc;
&lt;p&gt;namespace Extensions
{
public static class ButtonHelpers
{
public static MvcHtmlString LinkButtonForSave(this HtmlHelper helper)
{
var imageTag = ImageTag(&amp;quot;tick.png&amp;quot;);
var anchorHtml = FormSubmitAnchorTag(imageTag, &amp;quot;Save&amp;quot;);
return MvcHtmlString.Create(anchorHtml);
}&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    public static MvcHtmlString LinkButtonForCancel(this HtmlHelper helper)
    {
        var areaName = AreaName(helper);
        var controllerName = ControllerName(helper);
        var imageTag = ImageTag(&amp;amp;quot;cross.png&amp;amp;quot;);
        var anchorHtml = AnchorTagWithImageAndText(areaName, controllerName, &amp;amp;quot;Index&amp;amp;quot;, null, &amp;amp;quot;button negative&amp;amp;quot;, imageTag, &amp;amp;quot;Cancel&amp;amp;quot;);
        return MvcHtmlString.Create(anchorHtml);
    }

    private static TagBuilder ImageTag(string iconName)
    {
        var imageTag = new TagBuilder(&amp;amp;quot;img&amp;amp;quot;);
        imageTag.MergeAttribute(&amp;amp;quot;src&amp;amp;quot;, VirtualPathUtility.ToAbsolute(string.Format(&amp;amp;quot;~/Content/Images/Icons/{0}&amp;amp;quot;, iconName)));
        imageTag.MergeAttribute(&amp;amp;quot;width&amp;amp;quot;, &amp;amp;quot;16&amp;amp;quot;);
        imageTag.MergeAttribute(&amp;amp;quot;height&amp;amp;quot;, &amp;amp;quot;16&amp;amp;quot;);
        imageTag.MergeAttribute(&amp;amp;quot;alt&amp;amp;quot;, &amp;amp;quot;&amp;amp;quot;);
        return imageTag;
    }

    private static string AreaName(HtmlHelper helper)
    {
        var routeData = helper.ViewContext.RouteData;
        return routeData.DataTokens[&amp;amp;quot;area&amp;amp;quot;] == null ? string.Empty : routeData.DataTokens[&amp;amp;quot;area&amp;amp;quot;].ToString();
    }

    private static string ControllerName(HtmlHelper helper)
    {
        var routeData = helper.ViewContext.RouteData;
        return routeData.GetRequiredString(&amp;amp;quot;controller&amp;amp;quot;);
    }

    private static string FormSubmitAnchorTag(TagBuilder imageTag, string anchorText)
    {
        var anchorTag = new TagBuilder(&amp;amp;quot;a&amp;amp;quot;);
        anchorTag.MergeAttribute(&amp;amp;quot;href&amp;amp;quot;, &amp;amp;quot;#&amp;amp;quot;);
        anchorTag.AddCssClass(&amp;amp;quot;button positive&amp;amp;quot;);
        anchorTag.InnerHtml = imageTag.ToString(TagRenderMode.SelfClosing) + anchorText;
        return anchorTag.ToString();
    }

    private static string AnchorTagWithImageAndText(string areaName, string controllerName, string actionName, int? id, string cssClass, TagBuilder imageTag, string anchorText)
    {
        var anchorTag = new TagBuilder(&amp;amp;quot;a&amp;amp;quot;);
        if (areaName != string.Empty)
        {
            anchorTag.MergeAttribute(&amp;amp;quot;href&amp;amp;quot;, id == null
                                                 ? string.Format(&amp;amp;quot;/{0}/{1}/{2}&amp;amp;quot;, areaName, controllerName, actionName)
                                                 : string.Format(&amp;amp;quot;/{0}/{1}/{2}/{3}&amp;amp;quot;, areaName, controllerName, actionName, id));               
        }
        else
        {
            anchorTag.MergeAttribute(&amp;amp;quot;href&amp;amp;quot;, id == null
                                                 ? string.Format(&amp;amp;quot;/{0}/{1}&amp;amp;quot;, controllerName, actionName)
                                                 : string.Format(&amp;amp;quot;/{0}/{1}/{2}&amp;amp;quot;, controllerName, actionName, id));
        }
        anchorTag.AddCssClass(cssClass);
        anchorTag.InnerHtml = imageTag.ToString(TagRenderMode.SelfClosing) + anchorText;
        return anchorTag.ToString();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
</description>
      <pubDate>Sun, 16 Sep 2012 06:07:00 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/using-the-should-assembly-for-testing</guid>
      <link>https://volaresoftware.com/en/technical-posts/using-the-should-assembly-for-testing</link>
      <title>Using the Should assembly for testing</title>
      <description>&lt;p&gt;&lt;a href="http://should.codeplex.com/"&gt;Should&lt;/a&gt; is a .NET assembly of extension methods for building easy to write and easy to read assert statements.  The advantage of using this assembly is the syntax is more clear and more like human language.  It's free, open source, and it doesn't matter if you're using NUnit or MSTest or any test runner (Test Driven .NET, ReSharper, etc.).  The project is in Beta 1.1, but I've used it on a couple of projects now with no problems.&lt;/p&gt;
&lt;p&gt;I've never really liked the MSTest way of doing an assert.  The whole expected and actual arguments always seemed flipped around to me.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;// Assert
Assert.AreEqual(&amp;quot;eggs&amp;quot;, breakfast.Foods.First());
Assert.AreEqual(&amp;quot;bacon&amp;quot;, breakfast.Foods.Last()); 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Instead, just reference the Should assembly and add the&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;using Should;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;statement to the top of your test code and you can change it to:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;// Assert
breakfast.Foods.First().ShouldEqual(&amp;quot;eggs&amp;quot;);
breakfast.Foods.Last().ShouldEqual(&amp;quot;bacon&amp;quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I think one of the tricks to writing good tests is to have code that is dead simple to read when you come back to it much later.  The Should assembly gives you that.&lt;/p&gt;
&lt;p&gt;Here are some other calls from the CodePlex home page for the project:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public void Should_String_assertions()
{
    var obj = new object();
    obj.ShouldBeInRange(1,2);
    obj.ShouldBeNull();
    obj.ShouldBeSameAs(new object());
    obj.ShouldBeType(typeof (object));
    obj.ShouldEqual(obj);
    obj.ShouldNotBeInRange(1,2);
    obj.ShouldNotBeNull();
    obj.ShouldNotBeSameAs(new object());
    obj.ShouldNotBeType(typeof(string));
    obj.ShouldNotEqual(&amp;quot;foo&amp;quot;);
&lt;pre&gt;&lt;code&gt;&amp;amp;quot;This String&amp;amp;quot;.ShouldContain(&amp;amp;quot;this&amp;amp;quot;);
&amp;amp;quot;This String&amp;amp;quot;.ShouldNotBeEmpty();
&amp;amp;quot;This String&amp;amp;quot;.ShouldNotContain(&amp;amp;quot;foobar&amp;amp;quot;);

false.ShouldBeFalse();
true.ShouldBeTrue();

var list = new List&amp;amp;lt;object&amp;amp;gt;();
list.ShouldBeEmpty();
list.ShouldNotContain(new object());

var item = new object();
list.Add(item);
list.ShouldNotBeEmpty();
list.ShouldContain(item);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;You should check it out!&lt;/p&gt;
</description>
      <pubDate>Tue, 24 Aug 2010 00:40:45 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/tree-shaking-with-font-awesome-and-webpack</guid>
      <link>https://volaresoftware.com/en/technical-posts/tree-shaking-with-font-awesome-and-webpack</link>
      <title>Tree shaking with Font Awesome and webpack</title>
      <description>&lt;p&gt;&lt;a href="https://fontawesome.com"&gt;Font Awesome 5&lt;/a&gt; has a new tree shaking feature that works with &lt;a href="https://webpack.js.org/guides/tree-shaking/"&gt;webpack's tree shaking&lt;/a&gt;.  This is really helpful so you don't have to download one giant JavaScript file with a bunch of SVG icon definitions in it like:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;script defer src=&amp;quot;https://use.fontawesome.com/releases/v5.0.6/js/all.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which gets you file sizes like below, where all.js is 657 KB (278 KB gzipped) and index.js is 88 bytes.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/web_console_font_awesome_all.png" alt="https://cdn.volaresoftware.com/images/posts/2019/12/web_console_font_awesome_all.png" /&gt;&lt;/p&gt;
&lt;p&gt;Instead, you can limit the file size to only the icons you use in your project through ES2015+ module imports and get file sizes like this, where all.js is gone and index.js is now 33.3 KB gzipped. We just saved 600+ KB (or about 250 KB gzipped)!&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/web_console_font_awesome_index.png" alt="https://cdn.volaresoftware.com/images/posts/2019/12/web_console_font_awesome_index.png" /&gt;&lt;/p&gt;
&lt;p&gt;The Font Awesome team wrote &lt;a href="https://fontawesome.com/how-to-use/use-with-node-js#tree-shaking"&gt;some nice documentation on how to do this&lt;/a&gt;, but I didn't need to reference the shakable modules to get the smaller file size benefits. Here's how I got it working with Font Awesome 5 and webpack 3.&lt;/p&gt;
&lt;h3 id="what-worked"&gt;What worked&lt;/h3&gt;
&lt;p&gt;This is the HTML for the index.html test page.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;quot;utf-8&amp;quot; /&amp;gt;
    &amp;lt;title&amp;gt;Tree shaking with FontAwesome and webpack&amp;lt;/title&amp;gt;
    &amp;lt;link href=&amp;quot;https://volaresoftware.com/blog/node_modules/bootstrap/dist/css/bootstrap.min.css&amp;quot; rel=&amp;quot;stylesheet&amp;quot; /&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;div class=&amp;quot;text-center&amp;quot; style=&amp;quot;font-size: 24px; margin-top: 30px;&amp;quot;&amp;gt;
        &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;
            &amp;lt;div class=&amp;quot;col-xs-2&amp;quot;&amp;gt;
                &amp;lt;div&amp;gt;
                    &amp;lt;I class=&amp;quot;far fa-calendar-alt&amp;quot;&amp;gt;&amp;lt;/I&amp;gt;
                &amp;lt;/div&amp;gt;
                Calendar
            &amp;lt;/div&amp;gt;
            &amp;lt;div class=&amp;quot;col-xs-2&amp;quot;&amp;gt;
                &amp;lt;div&amp;gt;
                    &amp;lt;I class=&amp;quot;far fa-envelope&amp;quot;&amp;gt;&amp;lt;/I&amp;gt;
                &amp;lt;/div&amp;gt;
                Email
            &amp;lt;/div&amp;gt;
            &amp;lt;div class=&amp;quot;col-xs-2&amp;quot;&amp;gt;
                &amp;lt;div&amp;gt;
                    &amp;lt;I class=&amp;quot;fas fa-arrow-up&amp;quot;&amp;gt;&amp;lt;/I&amp;gt;
                &amp;lt;/div&amp;gt;
                Arrow Up
            &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;script src=&amp;quot;/dist/lib.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src=&amp;quot;/dist/index.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And this is index.js.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;import fontawesome from &amp;quot;@fortawesome/fontawesome&amp;quot;;
import farCalendar from &amp;quot;@fortawesome/fontawesome-free-regular/faCalendarAlt&amp;quot;;
import farEnvelope from &amp;quot;@fortawesome/fontawesome-free-regular/faEnvelope&amp;quot;;
import fasArrowUp from &amp;quot;@fortawesome/fontawesome-free-solid/faArrowUp&amp;quot;;
&lt;p&gt;fontawesome.library.add(farCalendar, farEnvelope, fasArrowUp);
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;In the markup, I'm pulling in lib.js, which webpack will figure out from the commons chunk (see below about what that is), and index.js, whose code is nothing but some icon imports.&lt;/p&gt;
&lt;p&gt;In Font Awesome 5, you can now import a single icon, multiple icons, a full set of icons (the solid, regular, light, or brand sets), or every icon they make (free or pro).  If you want the tree shaking and small file size benefit, you have to import the Font Awesome library and add your newly imported icons to the library before they can be used, like I've done above.&lt;/p&gt;
&lt;p&gt;Here is the webpack.config.js file.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;const webpack = require(&amp;quot;webpack&amp;quot;);
const path = require(&amp;quot;path&amp;quot;);
const CleanWebpackPlugin = require(&amp;quot;clean-webpack-plugin&amp;quot;);
const UglifyJsPlugin = require(&amp;quot;uglifyjs-webpack-plugin&amp;quot;);
&lt;p dead_code:="" true=""&gt;module.exports = () =&amp;gt; {&lt;br /&gt;
return {
entry: {
index: &amp;quot;index.js&amp;quot;
},
output: {
filename: &amp;quot;[name].js&amp;quot;,
path: path.resolve(__dirname, &amp;quot;dist&amp;quot;),
publicPath: &amp;quot;/dist&amp;quot;
},
devtool: &amp;quot;source-map&amp;quot;,
plugins: [
new CleanWebpackPlugin([&amp;quot;dist&amp;quot;]),
new webpack.optimize.CommonsChunkPlugin({
name: &amp;quot;lib&amp;quot;
}),
new UglifyJsPlugin({
sourceMap: true,
uglifyOptions: })
],
resolve: {
extensions: [
&amp;quot;.js&amp;quot;
],
modules: [
path.resolve(__dirname, &amp;quot;scripts&amp;quot;),
&amp;quot;node_modules&amp;quot;
]
},
module: {
rules: [
{
test: /.js$/,
exclude: /node_modules/,
use: {
loader: &amp;quot;babel-loader&amp;quot;,
options: {
presets: [&amp;quot;env&amp;quot;],
babelrc: false,
cacheDirectory: true,
plugins: [
&amp;quot;transform-runtime&amp;quot;]
}
}
}
]
}
};
};
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;If you're used to seeing webpack.config files, there isn't anything too novel going on. If you aren't, here's the gist: There is one application entry point, index.js. Files will be output to the /dist folder. Source maps are turned on. We clean the /dist folder before a build. We have a commons chunk called lib.js, which means webpack figures out code shared across modules that can be extracted into a common file. We are minifying with UglifyJS and setting its source map flags to true also. We have the UglifyJS dead code (tree shaking) flag set to true, but I get the same results with or without that setting turned on. The resolve section tells webpack where to look for files, and the module rule we have set is to use Babel to load *.js files unless the file comes from the node_modules folder (so use Babel's loader for our projects' scripts).&lt;/p&gt;
&lt;p&gt;I'm pretty happy with this, and for a project with a handful or even several handfuls of icons, it probably makes sense to import just the ones your project uses.  One option is to make a selectedIcons.js file, set up all your imports and Font Awesome library additions there, and import selectedIcons.js in your single entry or for pages with icons if you have a multiple entries project.&lt;/p&gt;
&lt;h3 id="what-didnt-work"&gt;What didn't work&lt;/h3&gt;
&lt;p&gt;The Font Awesome documentation describes some special modules you can set up through webpack.config aliases, and when you import from those files, you get tree shaking.&lt;/p&gt;
&lt;p&gt;I changed the webpack.config.js resolve section to this.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;resolve: {
    extensions: [
        &amp;quot;.js&amp;quot;
    ],
    modules: [
        path.resolve(__dirname, &amp;quot;scripts&amp;quot;),
       &amp;quot;node_modules&amp;quot;
    ],
    alias: {
        &amp;quot;@fortawesome/fontawesome-free-solid$&amp;quot;: &amp;quot;@fortawesome/fontawesome-free-solid/shakable.es.js&amp;quot;,
        &amp;quot;@fortawesome/fontawesome-free-regular$&amp;quot;: &amp;quot;@fortawesome/fontawesome-free-regular/shakable.es.js&amp;quot;
    }
},
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then I changed index.js to import with a different syntax.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;import fontawesome from &amp;quot;@fortawesome/fontawesome&amp;quot;;
import { faCalendarAlt, faEnvelope } from &amp;quot;@fortawesome/fontawesome-free-regular&amp;quot;;
import faArrowUp from &amp;quot;@fortawesome/fontawesome-free-solid&amp;quot;;
&lt;p&gt;fontawesome.library.add(faCalendarAlt, faEnvelope, faArrowUp);
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Then I re-built the code.  The page still works, but the index.js file got waaaay bigger.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2019/12/web_console_font_awesome_final.png" alt="https://cdn.volaresoftware.com/images/posts/2019/12/web_console_font_awesome_final.png" /&gt;&lt;/p&gt;
&lt;p&gt;I don't know if I missed something in my webpack.config.js, or I've imported with the wrong syntax, or I've referenced the special shakable files incorrectly, but I couldn't get it working. If you see my mistake, please comment below and I'll update the post.&lt;/p&gt;
&lt;p&gt;Either way, it works to import and add individual icons, and you get smaller files. All the &lt;a href="https://github.com/VolareSoftware/TreeShakingWithFontAwesome"&gt;code for this post can be found on GitHub&lt;/a&gt;.&lt;/p&gt;
</description>
      <pubDate>Mon, 29 Jan 2018 06:30:00 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/stop-making-hay</guid>
      <link>https://volaresoftware.com/en/technical-posts/stop-making-hay</link>
      <title>Stop making hay</title>
      <description>&lt;h2 id="straw-men"&gt;Straw men&lt;/h2&gt;
&lt;p&gt;When &lt;a href="http://en.wikipedia.org/wiki/Test_driven_development"&gt;test-driven development (TDD)&lt;/a&gt; or other test-first methods are first introduced, many people object with different variations of the same argument &amp;quot;if you can't test everything, it's flawed&amp;quot;.  People seem to get mentally stuck when they can't automate all test cases.  Sometimes, the point gets really stretched, like, &amp;quot;What if the user enters a negative salary lower than &lt;code&gt;int.MinValue&lt;/code&gt;?  We don't have a test for &lt;strong&gt;that&lt;/strong&gt;, do we?&amp;quot; or &amp;quot;What if the database or web server goes down?  How do we do TDD for &lt;strong&gt;that&lt;/strong&gt;?&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://twitter.com/darrencauthon"&gt;Darren Cauthon&lt;/a&gt; made this observation on Twitter a few months ago:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2010/12/darrencauthonquote.png" alt="https://cdn.volaresoftware.com/images/posts/2010/12/darrencauthonquote.png" /&gt;&lt;/p&gt;
&lt;p&gt;All these arguments are &lt;a href="http://en.wikipedia.org/wiki/Straw_man"&gt;straw men&lt;/a&gt;, where an exaggeration or misrepresentation of the point is used to discount the entire thing.&lt;/p&gt;
&lt;h2 id="getting-started"&gt;Getting started&lt;/h2&gt;
&lt;p&gt;TDD won't make all your problems go away or  all your dreams come true.  It's something that takes a lot of practice to get better at it.  I consider myself pretty mediocre at it.  You will be slower at coding when you start out, but you will get faster, and I believe it is worth the investment in terms of the cleaner design it yields.  The tests are nice, too. :&amp;gt;&lt;/p&gt;
&lt;p&gt;The trick for me to getting started with TDD was to start small.  This has also been the only way I've been able to do TDD successfully - in very small steps.  Create one test for the happy path for the feature you are trying to implement. This usually has to be broken down into sub steps.  Write the least amount of code you can write to get the test to pass.  Once the test is passing, refactor the code to clean it up and add some polish.  Then run your test again to make sure it still passes.&lt;/p&gt;
&lt;h2 id="unhappy-paths"&gt;Unhappy paths&lt;/h2&gt;
&lt;p&gt;Occasionally test the unhappy paths, based on how likely they are and how important they are to the business.  If your product owner isn't worried about &lt;code&gt;int.MinValue&lt;/code&gt;, you shouldn't be.  Move on to the next feature you're building.&lt;/p&gt;
&lt;p&gt;You probably won't automate all your test cases, but that's OK.  Your code will be decoupled, easier to refactor, and easier to read.  Plus you will have automated tests for whatever percentage of tests cases you came up with.&lt;/p&gt;
&lt;p&gt;There are far too many benefits to dismiss test-first approaches based on what it &lt;strong&gt;can't&lt;/strong&gt; do well.  So let's stop with the straw man arguments against test-first and start reaping the benefits.&lt;/p&gt;
</description>
      <pubDate>Sat, 25 Dec 2010 01:40:33 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/why-bother-writing-unit-tests</guid>
      <link>https://volaresoftware.com/en/technical-posts/why-bother-writing-unit-tests</link>
      <title>Why bother writing unit tests?</title>
      <description>&lt;p&gt;More developers are coming around to the idea of writing unit tests for their code.  But not everyone is sold.  Let's take a look at the arguments for just writing code and either manually testing or handing the app over to QA:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It takes too long to write unit tests.&lt;/li&gt;
&lt;li&gt;This is really simple code.  I could see maybe testing something complex, but this is just a CRUD app.&lt;/li&gt;
&lt;li&gt;Write my tests &lt;strong&gt;before&lt;/strong&gt; my code?  Are you kidding me?  I've always done it the other way and it's worked out just fine.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let's take these one by one and see if they are still valid.&lt;/p&gt;
&lt;h2 id="time-argument"&gt;Time Argument&lt;/h2&gt;
&lt;p&gt;It doesn't take long to run the test.  I think there is consensus there.  But writing units tests &lt;strong&gt;and&lt;/strong&gt; writing code is more lines of code than just writing the code.  More lines = more time, right?&lt;/p&gt;
&lt;p&gt;Sure, as long as manual testing is less than the automated testing &lt;strong&gt;over time&lt;/strong&gt;.  Not just the first time, but for the &lt;strong&gt;lifetime of that code&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;If I'm using your old assembly from 2004 or web service from last month, I want some assurances it still works the way it was supposed to.  If you knew the secret way to manually test it, but have forgotten it, I don't fully trust your code.  I have to spend time going over that code and testing it out myself.&lt;/p&gt;
&lt;p&gt;Code with a lifespan longer than your memory and availability to manually regression test it benefits from having a suite of unit tests that can be run in milliseconds.&lt;/p&gt;
&lt;h2 id="simplicity-argument"&gt;Simplicity Argument&lt;/h2&gt;
&lt;p&gt;&amp;quot;If the code is really simple, there is no point in writing unit tests.&amp;quot;&lt;/p&gt;
&lt;p&gt;This is a good point.  Unit testing can help work through complex code, but what if the code is really easy?&lt;/p&gt;
&lt;p&gt;I agree that there isn't a need to bother testing setting and getting properties and methods that just call other methods.  And please don't spend time testing code that is part of the .NET framework or an assembly you bought.  That's a waste of time.&lt;/p&gt;
&lt;p&gt;But if you're using test-driven development, you start with the functionality, not the implementation.  So you write tests that cover the important/core stuff in your requirements.  You don't bother testing properties and call wrappers, which are just technical artifacts of the important stuff you are coding.  If it's the important stuff, shouldn't it be covered with unit tests?&lt;/p&gt;
&lt;h2 id="tdd-my-world-upside-down"&gt;TDD = My World Upside Down&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2009/7/mad_hatter_thumb.gif" alt="https://cdn.volaresoftware.com/images/posts/2009/7/mad_hatter_thumb.gif" /&gt;&lt;/p&gt;
&lt;p&gt;&amp;quot;Writing test before writing code is crazy talk.&amp;quot; I also have had a great career without doing this, so what's the point?&lt;/p&gt;
&lt;p&gt;I agree it is crazy.  I also agree it's a 180 on the conventional wisdom.  And I completely agree that it's harder than just writing the code.&lt;/p&gt;
&lt;p&gt;But here's where I depart from the TDD crowd.  If you're new to unit testing, I just want you to write unit tests to cover the critical code for now.  It might lead you to TDD at some point, it might not.  But &lt;strong&gt;it's not an all or nothing thing&lt;/strong&gt;.  Let's just try to work in as many tests as we can and leave it there for now. How many tests do you need?  What code coverage levels are you shooting for?  That's up to you.  If you feel good showing the code to your peers and are happy to be held accountable for the quality of your code, you're probably done.&lt;/p&gt;
&lt;p&gt;I'll make the case for TDD another time.  Just baby steps for now.&lt;/p&gt;
</description>
      <pubDate>Thu, 08 Oct 2009 00:41:38 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/htmlencode-and-urlencode-arent-the-same-thing</guid>
      <link>https://volaresoftware.com/en/technical-posts/htmlencode-and-urlencode-arent-the-same-thing</link>
      <title>HtmlEncode and UrlEncode aren't the same thing</title>
      <description>&lt;p&gt;The other day I was trying to pass an encoded version of &lt;code&gt;id=123&lt;/code&gt; to a customer's search API.  I tried&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;var result = HttpUtility.HtmlEncode(&amp;quot;id=123&amp;quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;but it returned &lt;code&gt;id=123&lt;/code&gt;.  I stared at the screen, scratched my head, and jumped on Google.&lt;/p&gt;
&lt;p&gt;A quick search reminded me that &lt;a href="http://msdn.microsoft.com/en-us/library/73z22y6h.aspx"&gt;HtmlEncode&lt;/a&gt; is for escaping HTML, but it leaves everything else alone.  So&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;var result = HttpUtility.HtmlEncode(&amp;quot;&amp;lt;br/&amp;gt;&amp;quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;returns &lt;code&gt;&amp;lt;br/&amp;gt;&lt;/code&gt;.  All the less thans and greater thans get escaped, but the rest is pretty much the same.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/4fkewx0t.aspx"&gt;UrlEncode&lt;/a&gt; is for cases where you want to escape a URL, so&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;var result = HttpUtility.UrlEncode(&amp;quot;id=123&amp;quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;returns &lt;code&gt;id%3d123&lt;/code&gt;, which is what I wanted in the first place.  By comparison, if you UrlEncode the &lt;code&gt;&amp;lt;br/&amp;gt;&lt;/code&gt; tag, like&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;var result = HttpUtility.UrlEncode(&amp;quot;&amp;lt;br/&amp;gt;&amp;quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;you'll get back &lt;code&gt;%3cbr%2f%3e&lt;/code&gt;.  It's encoding the less than, the slash, and the greater than, but it's encoding them with URL-type escapes instead of HTML-style ones.&lt;/p&gt;
&lt;p&gt;I guess it's been a while since I paid attention to encoding.  Not all encoding methods are equal in the ASP.NET framework, so be careful which one you use.&lt;/p&gt;
</description>
      <pubDate>Sat, 29 Jan 2011 07:43:00 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/resizing-a-kendo-ui-drop-down-to-fit-its-data-without-wrapping</guid>
      <link>https://volaresoftware.com/en/technical-posts/resizing-a-kendo-ui-drop-down-to-fit-its-data-without-wrapping</link>
      <title>Resizing a Kendo UI drop down to fit its data without wrapping</title>
      <description>&lt;p&gt;Telerik's Kendo UI Web makes a spiffy looking drop down with JavaScript and CSS.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2013/2/image_31.png" alt="image_31.png" /&gt;&lt;/p&gt;
&lt;p&gt;The &lt;a href="http://demos.kendoui.com/web/dropdownlist/index.html"&gt;demos on the Telerik site&lt;/a&gt; show drop downs with default widths and not much text.&lt;/p&gt;
&lt;p&gt;That breaks down when the text in the drop down gets longer because it wraps.  I don't like this look.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2013/2/image_32.png" alt="image_32.png" /&gt;&lt;/p&gt;
&lt;p&gt;So I wrote a JavaScript function that resizes the drop down to fit the width of the data so you avoid the wrapping and get:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2013/2/image_33.png" alt="image_33.png" /&gt;&lt;/p&gt;
&lt;p&gt;Here's the JavaScript:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;var resizeDropDown = function (e) {
    var $dropDown = $(e.sender.element),
        dataWidth = $dropDown.data(&amp;quot;kendoDropDownList&amp;quot;).list.width(),
        listWidth = dataWidth + 20,
        containerWidth = listWidth + 6;
&lt;pre&gt;&lt;code&gt;// Set widths to the new values
$dropDown.data(&amp;amp;quot;kendoDropDownList&amp;amp;quot;).list.width(listWidth);
$dropDown.closest(&amp;amp;quot;.k-widget&amp;amp;quot;).width(containerWidth);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;You have to call this on the drop down's dataBound event.  That way, if you're pulling remote data through something like Web API, you won't resize until you've gotten the data back and fired the dataBound event.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://jsfiddle.net/joewilson0/GxSpN/"&gt;Here's a JSFiddle to play around with it&lt;/a&gt;.  The fiddle shows two drop downs – one with the default sizing and wrapping, and the other with the resizeDropDown function called on the dataBound event.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;div&amp;gt;
    &amp;lt;label for=&amp;quot;defaultSize&amp;quot;&amp;gt;Default drop down&amp;lt;/label&amp;gt;
    &amp;lt;select id=&amp;quot;defaultSize&amp;quot;&amp;gt;
        &amp;lt;option id=&amp;quot;1&amp;quot;&amp;gt;Apress Pro ASP.NET MVC 4 Framework&amp;lt;/option&amp;gt;
        &amp;lt;option id=&amp;quot;2&amp;quot;&amp;gt;Head First Object Oriented Analysus and Design&amp;lt;/option&amp;gt;
        &amp;lt;option id=&amp;quot;3&amp;quot;&amp;gt;Working Effectively with Legacy Code&amp;lt;/option&amp;gt;
    &amp;lt;/select&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div&amp;gt;
    &amp;lt;label for=&amp;quot;resized&amp;quot;&amp;gt;Resized drop down&amp;lt;/label&amp;gt;
    &amp;lt;select id=&amp;quot;resized&amp;quot;&amp;gt;
        &amp;lt;option id=&amp;quot;1&amp;quot;&amp;gt;Apress Pro ASP.NET MVC 4 Framework&amp;lt;/option&amp;gt;
        &amp;lt;option id=&amp;quot;2&amp;quot;&amp;gt;Head First Object Oriented Analysus and Design&amp;lt;/option&amp;gt;
        &amp;lt;option id=&amp;quot;3&amp;quot;&amp;gt;Working Effectively with Legacy Code&amp;lt;/option&amp;gt;
    &amp;lt;/select&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;var resizeDropDown = function (e) {
    var $dropDown = $(e.sender.element),
        dataWidth = $dropDown.data(&amp;quot;kendoDropDownList&amp;quot;).list.width(),
        listWidth = dataWidth + 20,
        containerWidth = listWidth + 6;
&lt;pre&gt;&lt;code&gt;// Set widths to the new values
$dropDown.data(&amp;amp;quot;kendoDropDownList&amp;amp;quot;).list.width(listWidth);
$dropDown.closest(&amp;amp;quot;.k-widget&amp;amp;quot;).width(containerWidth);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;p&gt;// Default implementation with Kendo CSS sizing
$(&amp;quot;#defaultSize&amp;quot;).kendoDropDownList();&lt;/p&gt;
&lt;p dataBound:="" resizeDropDown=""&gt;// Resized on data bound to the width of the data in the drop down
$(&amp;quot;#resized&amp;quot;).kendoDropDownList();
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
</description>
      <pubDate>Sat, 02 Feb 2013 13:19:00 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/trim-unused-css-selectors-with-purifycss-and-webpack</guid>
      <link>https://volaresoftware.com/en/technical-posts/trim-unused-css-selectors-with-purifycss-and-webpack</link>
      <title>Trim unused CSS selectors with PurifyCSS and webpack</title>
      <description>&lt;p&gt;Most web sites use a CSS library like &lt;a href="https://getbootstrap.com/"&gt;Bootstrap&lt;/a&gt;. It's great for getting started quickly and works well as an all-purpose style sheet.&lt;/p&gt;
&lt;p&gt;But what about all the selectors in Bootstrap you aren't using in your app? What if you also add a Bootstrap theme and your own web app style overrides on top of that? All the used and unused styles go down to your users' browsers with every response.&lt;/p&gt;
&lt;p&gt;If you can trim that down to only the styles your web app actually &lt;em&gt;uses&lt;/em&gt;, you'll send down a much smaller style sheet, your site will run faster, and you'll save on bandwidth costs.&lt;/p&gt;
&lt;p&gt;Here's how I did just that with &lt;a href="https://github.com/webpack-contrib/purifycss-webpack"&gt;PurifyCSS&lt;/a&gt; and &lt;a href="https://webpack.js.org/"&gt;webpack&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="install-webpack-and-purifycss"&gt;Install webpack and PurifyCSS&lt;/h3&gt;
&lt;p&gt;Once you've got Node and NPM up and running, install webpack 4.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;npm install webpack webpack-cli --save-dev
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then install &lt;a href="https://github.com/purifycss/purifycss"&gt;PurifyCSS&lt;/a&gt; and the &lt;a href="https://github.com/webpack-contrib/mini-css-extract-plugin"&gt;MiniCssExtractPlugin&lt;/a&gt;, if you don't already have it set up.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;npm install purify-css purifycss-webpack glob-all mini-css-extract-plugin --save-dev
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id="set-up-purifycss-in-webpack.config.js"&gt;Set up PurifyCSS in webpack.config.js&lt;/h3&gt;
&lt;p&gt;In your &lt;code&gt;webpack.config.js&lt;/code&gt; file, add a reference to the MiniCssExtractPlugin, the PurifyCSS plugin, and a way to glob files.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;const glob = require(&amp;quot;glob-all&amp;quot;);
const MiniCssExtractPlugin = require(&amp;quot;mini-css-extract-plugin&amp;quot;);
const PurifyCSSPlugin = require(&amp;quot;purifycss-webpack&amp;quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then set up your &lt;code&gt;paths&lt;/code&gt; in PurifyCSS. These are the locations of the files that will contain your styles. PurifyCSS will statically scan these files for styles and reference them in the style sheet. Styles found in the markup or scripts are left in the final style sheet. Styles not found are removed. The &lt;a href="https://github.com/purifycss/purifycss#how-it-works"&gt;algorithm for finding used styles&lt;/a&gt; is pretty sophisticated.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;plugins: [
    new MiniCssExtractPlugin({
        filename: &amp;quot;[name].css&amp;quot;
    }),
    new PurifyCSSPlugin({
        paths: glob.sync([
            path.join(__dirname, &amp;quot;Views/**/*.cshtml&amp;quot;),
            path.join(__dirname, &amp;quot;Scripts/**/*.html&amp;quot;),
            path.join(__dirname, &amp;quot;Scripts/**/*.js&amp;quot;)
        ])
    })
],
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, I'm referencing my ASP.NET MVC Razor pages in &lt;code&gt;Views/**/*.cshtml&lt;/code&gt;, my component templates in &lt;code&gt;Scripts/**/*.html&lt;/code&gt;, and my project &lt;code&gt;*.js&lt;/code&gt; files. Also note this plugin entry goes &lt;em&gt;after&lt;/em&gt; the &lt;code&gt;MiniCssExtractPlugin&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="add-any-whitelist-exceptions"&gt;Add any whitelist exceptions&lt;/h3&gt;
&lt;p&gt;Even with it's fancy algorithm, PurifyCSS can still miss styles it should leave alone. To prevent PurifyCSS from removing them from the final CSS, use the &lt;code&gt;whitelist&lt;/code&gt; option.&lt;/p&gt;
&lt;p&gt;Here, I've got a project style sheet with two styles – one that should be removed because it is not referenced, and one that should be left in even though it isn't referenced.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-css"&gt;.some-unused-class {
    color: red;
}
&lt;p&gt;.some-dynamic-class {
color: red;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;To do this, I've added &lt;code&gt;&amp;quot;*some-dynamic-class*&amp;quot;&lt;/code&gt; to the &lt;code&gt;whitelist&lt;/code&gt; array so PurifyCSS won't remove it.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;plugins: [
    new MiniCssExtractPlugin({
        filename: &amp;quot;[name].css&amp;quot;
    }),
    new PurifyCSSPlugin({
        paths: glob.sync([
            path.join(__dirname, &amp;quot;Views/**/*.cshtml&amp;quot;),
            path.join(__dirname, &amp;quot;Scripts/**/*.html&amp;quot;),
            path.join(__dirname, &amp;quot;Scripts/**/*.js&amp;quot;)
        ]),
        purifyOptions: {
            whitelist: [&amp;quot;*some-dynamic-class*&amp;quot;]
        }
    })
],
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id="results"&gt;Results&lt;/h3&gt;
&lt;p&gt;In the sample project, I'm using Bootstrap and a very small app style sheet. Here are the result before PurifyCSS.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2018/4/before_purifycss_thumb.png" alt="https://cdn.volaresoftware.com/images/posts/2018/4/before_purifycss_thumb.png" /&gt;&lt;/p&gt;
&lt;p&gt;And here are the result after PurifyCSS.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2018/4/after_purifycss_thumb.png" alt="https://cdn.volaresoftware.com/images/posts/2018/4/after_purifycss_thumb.png" /&gt;&lt;/p&gt;
&lt;p&gt;The sample site is a one-page site with a carousel component that references Bootstrap CSS, and as you would expect, the KB trimmed from removing unused CSS selectors is significant.&lt;/p&gt;
&lt;p&gt;Here is what happened with that class &lt;code&gt;.some-dynamic-class&lt;/code&gt; I put in the PurifyCSS &lt;code&gt;whitelist&lt;/code&gt;.  The &lt;code&gt;.some-unused-class&lt;/code&gt; selector is removed as we'd expect, and the &lt;code&gt;.some-dynamic-class&lt;/code&gt; is still in the final CSS file at the bottom.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2018/4/whitelist_style_left_in_thumb.png" alt="https://cdn.volaresoftware.com/images/posts/2018/4/whitelist_style_left_in_thumb.png" /&gt;&lt;/p&gt;
&lt;p&gt;All this code is on &lt;a href="https://github.com/VolareSoftware/TrimUnusedCSS"&gt;GitHub&lt;/a&gt; if you want to see the &lt;code&gt;package.json&lt;/code&gt; or full &lt;code&gt;webpack.config.js&lt;/code&gt; or mess around with this yourself.&lt;/p&gt;
</description>
      <pubDate>Mon, 16 Apr 2018 21:49:00 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/tree-shaking-with-bootstrap-4-and-webpack</guid>
      <link>https://volaresoftware.com/en/technical-posts/tree-shaking-with-bootstrap-4-and-webpack</link>
      <title>Tree shaking with Bootstrap 4 and webpack</title>
      <description>&lt;p&gt;The simplest way to use &lt;a href="https://getbootstrap.com/"&gt;Bootstrap 4&lt;/a&gt; is to add the whole thing from the CDNs.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;!doctype html&amp;gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;quot;utf-8&amp;quot;&amp;gt;
    &amp;lt;meta name=&amp;quot;viewport&amp;quot; content=&amp;quot;width=device-width, initial-scale=1, shrink-to-fit=no&amp;quot;&amp;gt;
    &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css&amp;quot;&amp;gt;
    &amp;lt;title&amp;gt;Bootstrap Size Test&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;
        &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;
            &amp;lt;div class=&amp;quot;col-sm&amp;quot;&amp;gt;
                page
            &amp;lt;/div&amp;gt;
            &amp;lt;div class=&amp;quot;col-sm&amp;quot;&amp;gt;
                content
            &amp;lt;/div&amp;gt;
            &amp;lt;div class=&amp;quot;col-sm&amp;quot;&amp;gt;
                goes
            &amp;lt;/div&amp;gt;
            &amp;lt;div class=&amp;quot;col-sm&amp;quot;&amp;gt;
                here
            &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;script src=&amp;quot;//code.jquery.com/jquery-3.2.1.slim.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src=&amp;quot;//cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src=&amp;quot;//maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The problem is, you might not need everything Bootstrap has to offer. Adding the JavaScript like this adds 134.5 KB (ignoring gzipping for comparison below) to your page.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2018/2/full_bootstrap_fom_cdns_thumb.png" alt="https://cdn.volaresoftware.com/images/posts/2018/2/full_bootstrap_fom_cdns_thumb.png" /&gt;&lt;/p&gt;
&lt;p&gt;If you are using ES2015+ and the npm distribution, and you don't need the whole Bootstrap package, you can &lt;code&gt;import&lt;/code&gt; just the code you need. Here's how.&lt;/p&gt;
&lt;h2 id="set-up-bootstrap-babel-and-webpack"&gt;Set up Bootstrap, Babel, and webpack&lt;/h2&gt;
&lt;p&gt;First, install Bootstrap, along with jQuery and Popper, which Bootstrap relies on. Then install webpack, along with tools to use ES2015+ syntax and minify JavaScript for distribution.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;npm install bootstrap jquery popper.js
npm install --save-dev webpack babel-core babel-loader babel-preset-env clean-webpack-plugin exports-loader path uglifyjs-webpack-plugin
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, update your &lt;code&gt;webpack.config.js&lt;/code&gt; to resolve the &lt;code&gt;/node_modules&lt;/code&gt; folder. You're setting this up so your &lt;code&gt;import&lt;/code&gt; statements know where to look when you reference Bootstrap modules.&lt;/p&gt;
&lt;p&gt;You'll also need to use &lt;code&gt;exports-loader&lt;/code&gt; with the webpack &lt;code&gt;ProvidePlugin&lt;/code&gt; to export the expected values from the Bootstrap modules and their dependencies. This helps with globals some of the Bootstrap modules depend on, like $ for jQuery.&lt;/p&gt;
&lt;p&gt;Finally, I've added an &lt;code&gt;alias&lt;/code&gt; for jQuery to point to &lt;code&gt;jquery.slim.min.js&lt;/code&gt; since that's enough jQuery functionality for Bootstrap to work. If you are already using the full jQuery in your project, skip this &lt;code&gt;alias&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;const webpack = require(&amp;quot;webpack&amp;quot;);
const path = require(&amp;quot;path&amp;quot;);
const CleanWebpackPlugin = require(&amp;quot;clean-webpack-plugin&amp;quot;);
const UglifyJsPlugin = require(&amp;quot;uglifyjs-webpack-plugin&amp;quot;);
&lt;p dead_code:="" true=""&gt;module.exports = () =&amp;gt; {
return {
entry: {
index: &amp;quot;index.js&amp;quot;
},
output: {
filename: &amp;quot;[name].js&amp;quot;,
path: path.resolve(__dirname, &amp;quot;dist&amp;quot;),
publicPath: &amp;quot;/dist&amp;quot;
},
devtool: &amp;quot;source-map&amp;quot;,
plugins: [
new CleanWebpackPlugin([&amp;quot;dist&amp;quot;]),
new webpack.ProvidePlugin({
$: &amp;quot;jquery&amp;quot;,
Popper: [&amp;quot;popper.js&amp;quot;, &amp;quot;default&amp;quot;],
Alert: &amp;quot;exports-loader?Alert!bootstrap/js/dist/alert&amp;quot;,
Button: &amp;quot;exports-loader?Button!bootstrap/js/dist/button&amp;quot;,
Carousel: &amp;quot;exports-loader?Carousel!bootstrap/js/dist/carousel&amp;quot;,
Collapse: &amp;quot;exports-loader?Collapse!bootstrap/js/dist/collapse&amp;quot;,
Dropdown: &amp;quot;exports-loader?Dropdown!bootstrap/js/dist/dropdown&amp;quot;,
Modal: &amp;quot;exports-loader?Modal!bootstrap/js/dist/modal&amp;quot;,
Popover: &amp;quot;exports-loader?Popover!bootstrap/js/dist/popover&amp;quot;,
Scrollspy: &amp;quot;exports-loader?Scrollspy!bootstrap/js/dist/scrollspy&amp;quot;,
Tab: &amp;quot;exports-loader?Tab!bootstrap/js/dist/tab&amp;quot;,
Tooltip: &amp;quot;exports-loader?Tooltip!bootstrap/js/dist/tooltip&amp;quot;,
Util: &amp;quot;exports-loader?Util!bootstrap/js/dist/util&amp;quot;
}),
new webpack.optimize.CommonsChunkPlugin({
name: &amp;quot;common&amp;quot;
}),
new UglifyJsPlugin({
sourceMap: true,
uglifyOptions: })
],
resolve: {
extensions: [
&amp;quot;.js&amp;quot;
],
modules: [
path.resolve(__dirname, &amp;quot;scripts&amp;quot;),
&amp;quot;node_modules&amp;quot;
],
alias: {
jquery: &amp;quot;jquery/dist/jquery.slim.min.js&amp;quot;
}
},
module: {
rules: [
{
test: /.js$/,
exclude: /node_modules/,
use: {
loader: &amp;quot;babel-loader&amp;quot;,
options: {
presets: [&amp;quot;env&amp;quot;]
}
}
}
]
}
};
};
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="import-just-the-needed-modules"&gt;Import just the needed modules&lt;/h2&gt;
&lt;p&gt;Now you can import the Bootstrap style sheet from &lt;code&gt;/node_modules&lt;/code&gt;, assuming you want the same styling on every page.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;https://volaresoftware.com/blog/node_modules/bootstrap/dist/css/bootstrap.min.css&amp;quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can also &lt;code&gt;import&lt;/code&gt; Bootstrap styles from inside your webpack modules, but for most web apps, you'll want the same styling on all pages, and putting a link to the style sheet in the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; is an easy way to do that.&lt;/p&gt;
&lt;p&gt;Now you can write code that &lt;code&gt;imports&lt;/code&gt; only the needed Bootstrap modules like this.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;import &amp;quot;bootstrap/js/dist/carousel&amp;quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let's say have a page that uses the Bootstrap carousel. Here's the HTML, including a reference to a webpack-built &lt;code&gt;index.js&lt;/code&gt; from my &lt;code&gt;/dist&lt;/code&gt; folder that only includes the carousel reference above.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;!doctype html&amp;gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;quot;utf-8&amp;quot;&amp;gt;
    &amp;lt;meta name=&amp;quot;viewport&amp;quot; content=&amp;quot;width=device-width, initial-scale=1, shrink-to-fit=no&amp;quot;&amp;gt;
    &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;https://volaresoftware.com/blog/node_modules/bootstrap/dist/css/bootstrap.min.css&amp;quot; /&amp;gt;
    &amp;lt;title&amp;gt;Bootstrap Size Test&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;
        &amp;lt;div id=&amp;quot;carouselExampleIndicators&amp;quot; class=&amp;quot;carousel slide&amp;quot; data-ride=&amp;quot;carousel&amp;quot;&amp;gt;
            &amp;lt;ol class=&amp;quot;carousel-indicators&amp;quot;&amp;gt;
                &amp;lt;li data-target=&amp;quot;#carouselExampleIndicators&amp;quot; data-slide-to=&amp;quot;0&amp;quot; class=&amp;quot;active&amp;quot;&amp;gt;&amp;lt;/li&amp;gt;
                &amp;lt;li data-target=&amp;quot;#carouselExampleIndicators&amp;quot; data-slide-to=&amp;quot;1&amp;quot;&amp;gt;&amp;lt;/li&amp;gt;
                &amp;lt;li data-target=&amp;quot;#carouselExampleIndicators&amp;quot; data-slide-to=&amp;quot;2&amp;quot;&amp;gt;&amp;lt;/li&amp;gt;
            &amp;lt;/ol&amp;gt;
            &amp;lt;div class=&amp;quot;carousel-inner&amp;quot;&amp;gt;
                &amp;lt;div class=&amp;quot;carousel-item active&amp;quot;&amp;gt;
                    &amp;lt;img class=&amp;quot;d-block w-100&amp;quot; data-src=&amp;quot;holder.js/800x400?auto=yes&amp;amp;amp;amp;bg=777&amp;amp;amp;amp;fg=555&amp;amp;amp;amp;text=First slide&amp;quot; alt=&amp;quot;First slide [800x400]&amp;quot; src=&amp;quot;data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22800%22%20height%3D%22400%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20800%20400%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_161c9dd15ef%20text%20%7B%20fill%3A%23555%3Bfont-weight%3Anormal%3Bfont-family%3AHelvetica%2C%20monospace%3Bfont-size%3A40pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_161c9dd15ef%22%3E%3Crect%20width%3D%22800%22%20height%3D%22400%22%20fill%3D%22%23777%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%22285.921875%22%20y%3D%22217.7%22%3EFirst%20slide%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E&amp;quot; data-holder-rendered=&amp;quot;true&amp;quot;&amp;gt;
                &amp;lt;/div&amp;gt;
                &amp;lt;div class=&amp;quot;carousel-item&amp;quot;&amp;gt;
                    &amp;lt;img class=&amp;quot;d-block w-100&amp;quot; data-src=&amp;quot;holder.js/800x400?auto=yes&amp;amp;amp;amp;bg=666&amp;amp;amp;amp;fg=444&amp;amp;amp;amp;text=Second slide&amp;quot; alt=&amp;quot;Second slide [800x400]&amp;quot; src=&amp;quot;data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22800%22%20height%3D%22400%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20800%20400%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_161c9dd15f3%20text%20%7B%20fill%3A%23444%3Bfont-weight%3Anormal%3Bfont-family%3AHelvetica%2C%20monospace%3Bfont-size%3A40pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_161c9dd15f3%22%3E%3Crect%20width%3D%22800%22%20height%3D%22400%22%20fill%3D%22%23666%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%22247.3203125%22%20y%3D%22217.7%22%3ESecond%20slide%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E&amp;quot; data-holder-rendered=&amp;quot;true&amp;quot;&amp;gt;
                &amp;lt;/div&amp;gt;
                &amp;lt;div class=&amp;quot;carousel-item&amp;quot;&amp;gt;
                    &amp;lt;img class=&amp;quot;d-block w-100&amp;quot; data-src=&amp;quot;holder.js/800x400?auto=yes&amp;amp;amp;amp;bg=555&amp;amp;amp;amp;fg=333&amp;amp;amp;amp;text=Third slide&amp;quot; alt=&amp;quot;Third slide [800x400]&amp;quot; src=&amp;quot;data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22800%22%20height%3D%22400%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20800%20400%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_161c9dd15f8%20text%20%7B%20fill%3A%23333%3Bfont-weight%3Anormal%3Bfont-family%3AHelvetica%2C%20monospace%3Bfont-size%3A40pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_161c9dd15f8%22%3E%3Crect%20width%3D%22800%22%20height%3D%22400%22%20fill%3D%22%23555%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%22277%22%20y%3D%22217.7%22%3EThird%20slide%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E&amp;quot; data-holder-rendered=&amp;quot;true&amp;quot;&amp;gt;
                &amp;lt;/div&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;a class=&amp;quot;carousel-control-prev&amp;quot; href=&amp;quot;#carouselExampleIndicators&amp;quot; role=&amp;quot;button&amp;quot; data-slide=&amp;quot;prev&amp;quot;&amp;gt;
                &amp;lt;span class=&amp;quot;carousel-control-prev-icon&amp;quot; aria-hidden=&amp;quot;true&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;
                &amp;lt;span class=&amp;quot;sr-only&amp;quot;&amp;gt;Previous&amp;lt;/span&amp;gt;
            &amp;lt;/a&amp;gt;
            &amp;lt;a class=&amp;quot;carousel-control-next&amp;quot; href=&amp;quot;#carouselExampleIndicators&amp;quot; role=&amp;quot;button&amp;quot; data-slide=&amp;quot;next&amp;quot;&amp;gt;
                &amp;lt;span class=&amp;quot;carousel-control-next-icon&amp;quot; aria-hidden=&amp;quot;true&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;
                &amp;lt;span class=&amp;quot;sr-only&amp;quot;&amp;gt;Next&amp;lt;/span&amp;gt;
            &amp;lt;/a&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;script src=&amp;quot;/dist/common.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src=&amp;quot;/dist/index.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The page now uses the same full Bootstrap CSS, which accounts for most of the Bootstrap weight at 141 KB. But the size of the JavaScript is just over 76 KB, saving us about 58 KB from the original approach.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2018/2/tree_shaken_bootstrap_thumb.png" alt="https://cdn.volaresoftware.com/images/posts/2018/2/tree_shaken_bootstrap_thumb.png" /&gt;&lt;/p&gt;
&lt;p&gt;It is much simpler to pull in the full Bootstrap library, but if you need to squeeze out a little more performance or shrink your page weight a little more, pulling in only the Bootstrap libraries you need can help.&lt;/p&gt;
&lt;p&gt;The sample code for this post is &lt;a href="https://github.com/VolareSoftware/TreeShakingWithBootstrap"&gt;available on GitHub&lt;/a&gt;.&lt;/p&gt;
</description>
      <pubDate>Sat, 24 Feb 2018 19:48:00 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/setting-default-values-for-multiple-value-parameters-in-reporting-services</guid>
      <link>https://volaresoftware.com/en/technical-posts/setting-default-values-for-multiple-value-parameters-in-reporting-services</link>
      <title>Setting Default Values for Multiple Value Parameters in Reporting Services</title>
      <description>&lt;p&gt;Today I was working on a Reporting Services report that needed to have all the values checked for a multi-value parameter when the report opened up.  It was a little tricky to figure out, but it turned out to be very simple in the end.&lt;/p&gt;
&lt;h2 id="multiple-value-parameters"&gt;Multiple Value Parameters&lt;/h2&gt;
&lt;p&gt;I've got some multiple value parameters on a report.  These are easy to create in SQL Server Reporting Services.  Just check the box for your parameter and the user gets a check box drop down letting them pick more than one value from the drop down.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2010/10/image_4.png" alt="image_4.png" /&gt;&lt;/p&gt;
&lt;h2 id="available-values"&gt;Available Values&lt;/h2&gt;
&lt;p&gt;You can set the available values for the drop down to a dataset in your report or a shared dataset in the Reporting Services project.  Next, pick the value and name fields (which can be the same column in the dataset if that's what works in your situation).&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2010/10/image_5.png" alt="image_5.png" /&gt;&lt;/p&gt;
&lt;h2 id="default-values"&gt;Default Values&lt;/h2&gt;
&lt;p&gt;This is the part where we want to check each of those multiple values on report startup.  The hard part is, I don't know the values at design time, so I can't hard code them.  I want to simulate a &amp;quot;select all&amp;quot; of the check boxes.  My mind started wandering to VBA code I could put in the report as a startup function.&lt;/p&gt;
&lt;p&gt;But on a whim, I tried selecting all the values from the same query, and I was pleased to see it work!&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2010/10/image_6.png" alt="image_6.png" /&gt;&lt;/p&gt;
&lt;p&gt;And I get the results I want on the report when it opens:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2010/10/image_7.png" alt="image_7.png" /&gt;&lt;/p&gt;
</description>
      <pubDate>Sat, 02 Oct 2010 00:40:40 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/fixing-screen-saver-wait-time-of-999-minutes-on-a-dell-laptop</guid>
      <link>https://volaresoftware.com/en/technical-posts/fixing-screen-saver-wait-time-of-999-minutes-on-a-dell-laptop</link>
      <title>Fixing screen saver wait time of 999 minutes on a Dell laptop</title>
      <description>&lt;p&gt;I have a Dell Precision M4500 with Windows 7 and ran into a problem with the screen saver not coming on.  Rebooting didn't fix it and calling Dell technical support didn't help (&amp;quot;You could reformat, I guess.&amp;quot;).&lt;/p&gt;
&lt;p&gt;My screen saver dialog looked like this with 999 minutes in the wait time:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2011/3/snaghtml1e594b9_1.png" alt="snaghtml1e594b9_1.png" /&gt;&lt;/p&gt;
&lt;p&gt;If I clicked Preview, the screen would go blank like it was supposed to, so it wasn't a video card thing.  When I set the wait time to 10 minutes and clicked OK, then opened the dialog box again, my value of 10 minutes was saved, but the screen saver never turned on.&lt;/p&gt;
&lt;p&gt;Finally, I found this dialog in the Dell System and Manager under Display Settings:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2011/3/snaghtml1e9726b_1.png" alt="snaghtml1e9726b_1.png" /&gt;&lt;/p&gt;
&lt;p&gt;See the &amp;quot;Disable alarms and timers for Presentations&amp;quot; check box?  I had that checked, so I unchecked it and the screen saver started working normally again.  I wasn't in Presentation mode, but this Dell app didn't seem to know that.&lt;/p&gt;
&lt;p&gt;I hope this is helpful to someone stuck on the same issue.&lt;/p&gt;
</description>
      <pubDate>Thu, 10 Mar 2011 01:40:18 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/specflow-and-watin-worst-practices-what-not-to-do</guid>
      <link>https://volaresoftware.com/en/technical-posts/specflow-and-watin-worst-practices-what-not-to-do</link>
      <title>SpecFlow and WatiN Worst Practices: What *NOT* to do</title>
      <description>&lt;p&gt;The best way to learn something is to jump right in.  Best practices don't really emerge until you've found out what works and what doesn't.  This is my list of things that didn't work on my four &lt;a href="http://specflow.org/"&gt;SpecFlow&lt;/a&gt; and &lt;a href="http://watin.org/"&gt;WatiN&lt;/a&gt; projects in the last two years.  Of course, I'll also talk about what did work.&lt;/p&gt;
&lt;h2 id="acknowledgements"&gt;Acknowledgements&lt;/h2&gt;
&lt;p&gt;First off, almost everything I know about SpecFlow/Cucumber/Gherkin I learned from &lt;a href="https://twitter.com/thepaulrayner"&gt;Paul Rayner&lt;/a&gt; and pairing with with him on two projects.  I'm grateful for the experience and the knowledge gained.&lt;/p&gt;
&lt;p&gt;I've also tried to glean as much as I can from &lt;a href="https://twitter.com/marcusoftnet"&gt;Marcus Hammarberg&lt;/a&gt;, &lt;a href="https://twitter.com/darrencauthon"&gt;Darren Cauthon&lt;/a&gt;, &lt;a href="https://twitter.com/rslawrence"&gt;Richard Lawrence&lt;/a&gt;, and &lt;a href="https://twitter.com/brandonsatrom"&gt;Brandon Satrom&lt;/a&gt; in their twitter feeds and &lt;a href="http://msdn.microsoft.com/en-us/magazine/gg490346.aspx"&gt;articles&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="what-level-of-your-app-should-you-test"&gt;What level of your app should you test?&lt;/h2&gt;
&lt;p&gt;One big issue that comes up around SpecFlow is what level of your application should you be testing – internal or external.  The answer has a big impact on how you write your feature files, what side benefits you get from the feature files, and the speed of your tests.&lt;/p&gt;
&lt;h3 id="developer-facing"&gt;Developer-facing&lt;/h3&gt;
&lt;p&gt;You can use SpecFlow as a BDD-style tool and do unit or light integration testing with it.  I call these developer-facing feature files, because they are expressed in language internal to the application (&amp;quot;Then I post the form values to the AccountController&amp;quot;).  The nice thing about this is the readability of the test from the dev side and the speed of execution, since you are explicitly testing code internals.&lt;/p&gt;
&lt;h3 id="business-facing"&gt;Business-facing&lt;/h3&gt;
&lt;p&gt;But I think this misses an opportunity to have richer language in the feature files.  If the SpecFlow features are worded the way the product owner sees the app working, you are fostering a &lt;a href="http://en.wikipedia.org/wiki/Domain-driven_design"&gt;ubiquitous language&lt;/a&gt; between the business and the developers.  You have a clearer vision of your app's external behavior expressed through concrete examples.&lt;/p&gt;
&lt;p&gt;You end up with &amp;quot;Then I click the save button&amp;quot; or even better, &amp;quot;Then I save&amp;quot; instead of &amp;quot;Then I post the form values to the AccountController&amp;quot;.  The bad thing about this style of spec wording is you end up testing through UI test automation tools like WatiN.  This testing style is slow and can be buggy and fragile if you aren't careful (see below for tips).&lt;/p&gt;
&lt;p&gt;In my experience, one of the main problems in software development is getting the dev team to understand what the business wants built and why.  SpecFlow is a great tool for getting both sides together to define that behavior through examples.&lt;/p&gt;
&lt;p&gt;Furthermore, UI testing becomes much more important as web applications take on more and more JavaScript and other client-side code.  Since the external behavior of the app is how the business and users will evaluate the app, I think it makes sense to test at this level.&lt;/p&gt;
&lt;h2 id="how-not-to-set-up-your-test-project"&gt;How not to set up your test project&lt;/h2&gt;
&lt;p&gt;Acceptance tests that drive the browser are &lt;strong&gt;not&lt;/strong&gt; unit tests.  They are closer to integration tests, but they are even &lt;strong&gt;slower&lt;/strong&gt;, since your local web server and the browser have to spin up each time and fill out forms, click buttons, etc.&lt;/p&gt;
&lt;p&gt;Because of this, don't add SpecFlow to your current unit test project or even your current integration test project, if you separate those.  Let it live in its own project with a name like MyProject.AcceptanceTests.  For quick test running and CI, &lt;a href="https://volaresoftware.com/en/technical-posts/running-specflow-and-watin-tests-with-teamcity-and-appharbor"&gt;it's much easier to omit an entire assembly of tests&lt;/a&gt;, so keep these guys separate.&lt;/p&gt;
&lt;p&gt;I find that I often want to run the faster unit tests and run the acceptance tests only around the parts of the application we are working on.  I run the full suite maybe 2-5 times a week, especially before a hand-off to a stakeholder or a big demo.&lt;/p&gt;
&lt;h2 id="how-not-to-install-specflow-and-watin"&gt;How not to install SpecFlow and WatiN&lt;/h2&gt;
&lt;p&gt;Don't bother with DLL downloads or manually setting up file references.  Install the &lt;a href="http://nuget.org/packages/SpecFlow"&gt;SpecFlow NuGet package&lt;/a&gt; and the &lt;a href="http://visualstudiogallery.msdn.microsoft.com/9915524d-7fb0-43c3-bb3c-a8a14fbd40ee"&gt;Visual Studio Extension&lt;/a&gt;.  Let NuGet handle the assembly references and setting up the app.config for you.  The VS Extension adds some nice feature file editing and right-click features to run a single test.&lt;/p&gt;
&lt;p&gt;You'll need to decide on &lt;a href="http://en.wikipedia.org/wiki/MSTest"&gt;MSTest&lt;/a&gt; versus &lt;a href="http://www.nunit.org/"&gt;NUnit&lt;/a&gt;.  The first comes with .NET, the later is free open source and &lt;a href="http://nuget.org/packages/nunit"&gt;you can add it with NuGet&lt;/a&gt;.  If you're in a shop that heavily favors one over the other, use that.  All you're using these for in the SpecFlow world is the generated code and the attributes marking your test fixtures and methods.&lt;/p&gt;
&lt;p&gt;If you're using NUnit (the default), you'll need to be sure ApartmentState is set to &amp;quot;STA&amp;quot; in the app.config for your test project like this.  If you use the NuGet download, it should take care of that.&lt;/p&gt;
&lt;p&gt;Finally, you'll need WatiN, which can also be installed with a &lt;a href="http://nuget.org/packages/watin"&gt;NuGet package&lt;/a&gt;.  I've sometimes had to set some of the WatiN assemblies to Copy Local = true in the acceptance test project to get everything working.  Kind of a hassle, but once it's set up right, you're done forever with it.&lt;/p&gt;
&lt;h2 id="how-not-to-set-up-a-webbrowser-class-and-app.config"&gt;How not to set up a WebBrowser class and app.config&lt;/h2&gt;
&lt;p&gt;WatiN can run UI tests with Internet Explorer or FireFox (not Chrome, Safari, Opera, or anything else).  The FireFox API didn't have parity with the IE one last time I checked, so I've gotten used to using the WatiN IE class.&lt;/p&gt;
&lt;p&gt;However, don't reference this class directly, or all your code is IE dependent.  What if the next version of WatiN supports an iPad emulator you want to use?  Do you really trust your find-replace skills that much?&lt;/p&gt;
&lt;p&gt;Instead, wrap the references with a static class, and reference that in your step definitions.  Here's the one I'm using these days that gets an instance of IE in a static constructor:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;namespace Helpers
{
    public static class WebBrowser
    {
        private static IE _browser;
&lt;pre&gt;&lt;code&gt;    static WebBrowser()
    {
        _browser = new IE();
        _browser.ShowWindow(NativeMethods.WindowShowStyle.Maximize);
    }

    public static IE Current
    {
        get { return _browser; }
        set { _browser = value; }
    }

    public static string BaseUrl
    {
        get { return ConfigurationManager.AppSettings[&amp;amp;quot;BaseUrl&amp;amp;quot;]; }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;This is maximizing the IE window after it opens and adding a reference to a BaseUrl property, which is set in the &lt;code&gt;app.config&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-xml"&gt;&amp;lt;appSettings&amp;gt;
    &amp;lt;clear/&amp;gt;
    &amp;lt;add key=&amp;quot;BaseUrl&amp;quot; value=&amp;quot;http://localhost:1234/&amp;quot;/&amp;gt;
    &amp;lt;!--&amp;lt;add key=&amp;quot;BaseUrl&amp;quot; value=&amp;quot;http://myapp.apphb.com&amp;quot;/&amp;gt;--&amp;gt;
&amp;lt;/appSettings&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I use the BaseUrl to switch out the location of the test target in the step definitions (not shown above).  So if I want to test locally, the BaseUrl is &amp;quot;http://localhost:1234/&amp;quot;.  If I want to hit the AppHarbor version, the BaseUrl &amp;quot;http://myapp.apphb.com/&amp;quot;.  Just change the app.config and run the tests.&lt;/p&gt;
&lt;h2 id="how-not-to-set-up-your-specflow-before-and-after-attributes"&gt;How not to set up your SpecFlow Before and After attributes&lt;/h2&gt;
&lt;p&gt;SpecFlow has attributes that can be put over your step definitions for your setup and teardown code.  Here are the hooks you have:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;BeforeTestRun / AfterTestRun&lt;/li&gt;
&lt;li&gt;BeforeFeature / AfterFeature&lt;/li&gt;
&lt;li&gt;BeforeScenario / AfterScenario&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I've struggled with where these go before, but the last couple projects I created a &lt;code&gt;BeforeAndAfter.cs&lt;/code&gt; class (clever, huh?), set the SpecFlow [Binding] attribute to the top of the class, then added all my before/after code.&lt;/p&gt;
&lt;p&gt;This is a great place to put database clean ups, security code if your app has a login, any custom SpecFlow tags you've created, etc.  Here's the code I used on my last project:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;using System.Configuration;
using TechTalk.SpecFlow;
using WatiN.Core;
&lt;p&gt;namespace Helpers
{
[Binding]
public class BeforeAndAfter
{
[BeforeTestRun]
public static void BeforeTestRun()
{
// Ignore all features and scenarios when running on AppHarbor
if (ConfigurationManager.AppSettings[&amp;quot;Environment&amp;quot;] == &amp;quot;Test&amp;quot;)
{
Assert.Ignore();
return;
}&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;        // Always login first
        Security.ILoginAsAdministrator();
    }

    [AfterTestRun]
    public static void AfterTestRun()
    {
        // Logout to be ready for next session
        Security.ILogout();

        // Close the browser and dispose
        WebBrowser.Current.Close();
        WebBrowser.Current.Dispose();

        // Reset the data to be ready for the next session
        TestData.CleanUp();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;I put all my helper methods like the &lt;code&gt;WebBrowser.cs&lt;/code&gt; and &lt;code&gt;BeforeAndAfter.cs&lt;/code&gt; in a &lt;code&gt;/Helpers&lt;/code&gt; folder in the acceptance test project.&lt;/p&gt;
&lt;h2 id="how-not-to-organize-your-feature-files"&gt;How not to organize your feature files&lt;/h2&gt;
&lt;p&gt;Feature files have one or more features in them.  You could put each separate feature in it's on .feature file, but that's overkill.&lt;/p&gt;
&lt;p&gt;I used to create a new feature file for each view in the app.  That probably makes sense in some cases, but this approach often misses the value of those pages.  For instance, if there are 2-3 pages for an e-commerce checkout process, it's probably not that helpful to have a feature file for &lt;code&gt;BillingAndShippingAddress.feature&lt;/code&gt;, &lt;code&gt;CreditCard.feature&lt;/code&gt;, and &lt;code&gt;Confirmation.feature&lt;/code&gt;.  It might be helpful to developers, but it's likely non-developers on the team see the checkout process more holistically, so why not start with a Checkout.feature file?  If this gets too big, split out pieces into their own logical .feature files later.&lt;/p&gt;
&lt;p&gt;I put all my feature files in a /Features folder in the acceptance test project.  It's mostly cosmetic, but it does help a little.&lt;/p&gt;
&lt;h2 id="how-not-to-organize-your-step-definition-files"&gt;How not to organize your step definition files&lt;/h2&gt;
&lt;p&gt;Step definitions are the implementation of the steps in the feature files. Since I was organizing feature files by web app page, I started out doing the same with step definitions. When you try this approach, you quickly see the problem, since step definitions can and should be reused across features.&lt;/p&gt;
&lt;p&gt;If there is a step definition &amp;quot;Then I go to /MyPage&amp;quot;, the step definition might be clicking a menu, a link in the page, or just opening a URL.  As you can imagine, this can be helpful in lots of different feature files, so it makes more sense to group these in a Navigation.cs file or something like that.  Maybe you have a separate Menu.cs with those step definitions, or maybe you lump them in with Navigation.&lt;/p&gt;
&lt;p&gt;How you group these is up to you.  SpecFlow sees all &lt;code&gt;*.cs&lt;/code&gt; files with a &lt;code&gt;[Binding]&lt;/code&gt; on them as places where your step definitions could live, and it uses regex matching to find the right method.  SpecFlow doesn't care if you put your methods in one class or 100 classes, but you will.  So put some thought into how you group these, because it's easier to see opportunities to refactor out similar code you find within the same .cs file versus across .cs files.&lt;/p&gt;
&lt;p&gt;This makes the file names much more generic, but I've had the most success with this style.  On recent projects, my step definition files have included Forms.cs, Menu.cs, Messages.cs, Navigation.cs, Search.cs, Security.cs, and SEO.cs.&lt;/p&gt;
&lt;p&gt;I put all my step definition code in a /Steps folder.  In the end, it looks like this:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2013/1/image_30.png" alt="image_30.png" /&gt;&lt;/p&gt;
&lt;h2 id="how-not-to-code-step-definitions"&gt;How not to code step definitions&lt;/h2&gt;
&lt;p&gt;Step definition code in each method should be brief – like a couple lines.  If you've got large blocks of code, you've probably got too much going on.&lt;/p&gt;
&lt;p&gt;Maybe you have a giant form with tons of fields and a SpecFlow table feeding you the values.  You can probably get away with something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public void IFillOutTheForm(Table table) 
{
    foreach (var row in table.Rows)
    {
        var field = row[&amp;quot;Field&amp;quot;];
        var value = row[&amp;quot;Value&amp;quot;];
        switch (field)
        {
            case &amp;quot;Something Different&amp;quot;:  // Put exceptions here for drop downs, date pickers, radio buttons, etc.
                WebBrowser.Current.SelectList(Find.ByName(&amp;quot;SomethingDifferentId&amp;quot;)).Select(value);
                break;
            default:
                WebBrowser.Current.TextField(Find.ByName(field)).Value = value;
                break;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, the &amp;quot;Something Different&amp;quot; case is where you would put non-textbox filling out code.  But if your forms are like most business apps, there are lots of text boxes, a handful of drop downs, and a smattering of radio, checkbox, date pickers, sliders, etc. that require some different WatiN code.&lt;/p&gt;
&lt;p&gt;Of course, if the exceptions outnumber the convention, make a separate method and see if you can factor out some common code to use somewhere else.  Remember, the key to being productive with SpecFlow is reusing the step definitions, so once you start seeing duplication, look for ways to refactor to a common convention in your feature files and step definitions.  It takes a while to get a critical mass of these built up, but once you do, you really start picking up speed.&lt;/p&gt;
</description>
      <pubDate>Sun, 06 Jan 2013 05:05:00 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/concatenating-and-decoding-strings-from-a-one-to-many-table-in-sql</guid>
      <link>https://volaresoftware.com/en/technical-posts/concatenating-and-decoding-strings-from-a-one-to-many-table-in-sql</link>
      <title>Concatenating and decoding strings from a one-to-many table in SQL</title>
      <description>&lt;p&gt;Let's say you have two tables in SQL Server: Person and PersonNotes. PersonNotes is a one-to-many table of notes about that Person.  Here's the SQL for the tables:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-sql"&gt;create table Person (PersonId int not null)
insert Person (PersonId) values (1)
&lt;p&gt;create table PersonNotes (PersonId int not null, Note varchar(max))
insert PersonNotes (PersonId, Note) values (1, 'note &amp;lt;1&amp;gt;')
insert PersonNotes (PersonId, Note) values (1, '&amp;amp;amp; note #2')
insert PersonNotes (PersonId, Note) values (1, '&amp;amp;amp; finally, note &amp;lt;3&amp;gt;')
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;And let's say you need to grab all those PersonNotes rows and concatenate them into one string per Person row.  You have a couple options: 1) create a custom function, 2) write a cursor, or 3) use T-SQL's FOR XML trick.  I'll focus on the last one n this post.&lt;/p&gt;
&lt;p&gt;Using FOR XML is kind of lame, since it's really meant for something else, but it works pretty well to pull all the strings across rows into one value:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-sql"&gt;select Person.PersonId, (select PersonNotes.Note + ' '
                        from PersonNotes
                        where PersonNotes.PersonId = Person.PersonId
                        for xml path('')) AS Notes
from Person  
where Person.PersonId = 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here's the &lt;a href="http://sqlfiddle.com/#!6/8ec9d/14/0"&gt;SQL Fiddle&lt;/a&gt; for this table setup and query.  Running this will get you these results:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-xml"&gt;note &amp;amp;amp;lt;1&amp;amp;amp;gt; &amp;amp;amp;amp; note #2 &amp;amp;amp;amp; finally, note &amp;amp;amp;lt;3&amp;amp;amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The problem is, putting it in XML means you get lots of &amp;quot;&amp;lt;&amp;quot;, &amp;quot;&amp;gt;&amp;quot;, and &amp;quot;&amp;amp;&amp;quot; where the strings have been encoded.  That's what you want for XML, but it's not usually what you want for a string.&lt;/p&gt;
&lt;p&gt;But if we use a little XPATH to pull the first node from that resulting XML, we do get the decoded values again:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-sql"&gt;select Person.PersonId, (select PersonNotes.Note + ' '
                        from PersonNotes
                        where PersonNotes.PersonId = Person.PersonId
                        for xml path(''), root, type).value('/', 'varchar(max)') AS Notes
from Person  
where Person.PersonId = 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here's the &lt;a href="http://sqlfiddle.com/#!6/8ec9d/12/0"&gt;SQL Fiddle&lt;/a&gt; for the tables setup and query with the extra XPATH casting back to varchar(max).  Running this will get you these results:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-xml"&gt;note &amp;lt;1&amp;gt; &amp;amp;amp; note #2 &amp;amp;amp; finally, note &amp;lt;3&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And we're happy!&lt;/p&gt;
</description>
      <pubDate>Tue, 13 Oct 2015 10:23:43 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/using-visual-studio-2012-test-explorer-with-nunit-and-specflow</guid>
      <link>https://volaresoftware.com/en/technical-posts/using-visual-studio-2012-test-explorer-with-nunit-and-specflow</link>
      <title>Using Visual Studio 2012 Test Explorer with NUnit and SpecFlow</title>
      <description>&lt;p&gt;This one came up today and surprised me.  I usually use the &lt;a href="http://www.jetbrains.com/resharper/"&gt;ReSharper&lt;/a&gt; test runner, but I wanted to try out the new, improved &lt;a href="http://blogs.msdn.com/b/visualstudioalm/archive/2012/03/08/what-s-new-in-visual-studio-11-beta-unit-testing.aspx"&gt;Visual Studio Test Explorer in VS2012&lt;/a&gt;.  I have &lt;a href="http://www.nunit.org"&gt;NUnit&lt;/a&gt;-based unit and integration tests and &lt;a href="http://www.specflow.org/specflownew/"&gt;SpecFlow&lt;/a&gt;/&lt;a href="http://watin.org/"&gt;WatiN&lt;/a&gt; UI automation tests that use NUnit behind the scenes.&lt;/p&gt;
&lt;h2 id="visual-studio-extensions-and-updates"&gt;Visual Studio Extensions and Updates&lt;/h2&gt;
&lt;p&gt;You'll need to install the &lt;a href="http://visualstudiogallery.msdn.microsoft.com/6ab922d0-21c0-4f06-ab5f-4ecd1fe7175d"&gt;NUnit Test Adapter&lt;/a&gt; so the Visual Studio Test Explorer knows what to do.  You don't need to go back and change attributes, references, etc. to use MSTest.  It can work with NUnit natively once you add this extension under Tools &amp;gt; Extensions and Updates.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2012/9/snaghtmldadd84c_2.png" alt="snaghtmldadd84c_2.png" /&gt;&lt;/p&gt;
&lt;h2 id="apartment-state"&gt;Apartment State&lt;/h2&gt;
&lt;p&gt;Using SpecFlow with NUnit means you have to set your app.config ApartmentState to STA.  &lt;a href="http://stackoverflow.com/questions/2463461/nunit-gui-runner-and-apartment-state"&gt;This is well documented&lt;/a&gt;, but it's one of those things you have to do to get everything working.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-xml"&gt;&amp;lt;NUnit&amp;gt;
  &amp;lt;TestRunner&amp;gt;
    &amp;lt;add key=&amp;quot;ApartmentState&amp;quot; value=&amp;quot;STA&amp;quot;/&amp;gt;
  &amp;lt;/TestRunner&amp;gt;
&amp;lt;/NUnit&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Making this a&lt;code&gt;pp.config&lt;/code&gt; change is all the ReSharper test runner needs, but the Visual Studio Test Explorer needs a little more help.  You have to set the NUnit attribute&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;[assembly: RequiresSTA]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;in your &lt;code&gt;AssemblyInfo.cs&lt;/code&gt; for your test project where your SpecFlow tests live.&lt;/p&gt;
&lt;h2 id="done"&gt;Done!&lt;/h2&gt;
&lt;p&gt;Now you should be able to run ALL your solution's tests with the Visual Studio Test Explorer, including the SpecFlow ones!&lt;/p&gt;
&lt;p&gt;Visual Studio Test Explorer still needs a lot of work around grouping tests, and &lt;a href="https://twitter.com/pprovost"&gt;Peter Provost&lt;/a&gt; says as much in his blog post, but it has come a long way.&lt;/p&gt;
</description>
      <pubDate>Wed, 19 Sep 2012 00:39:59 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/integrating-kendo-ui-drop-downs-with-knockout-js</guid>
      <link>https://volaresoftware.com/en/technical-posts/integrating-kendo-ui-drop-downs-with-knockout-js</link>
      <title>Integrating Kendo UI drop downs with Knockout JS</title>
      <description>&lt;p&gt;&lt;a href="http://www.kendoui.com/web.aspx"&gt;Kendo UI&lt;/a&gt; drop downs look great.  Here is a Kendo UI drop down with default styling in closed and open view:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2013/2/image_34.png" alt="image_34.png" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2013/2/image_35.png" alt="image_35.png" /&gt;&lt;/p&gt;
&lt;p&gt;It is built with this HTML:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;input id=&amp;quot;kendoDropDown&amp;quot; type=&amp;quot;text&amp;quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and this JavaScript:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;// Init the drop down
$(&amp;quot;#kendoDropDown&amp;quot;).kendoDropDownList({
    dataValueField: &amp;quot;id&amp;quot;,
    dataTextField: &amp;quot;name&amp;quot;,
    dataSource: [
        { id: &amp;quot;1&amp;quot;, name: &amp;quot;apple&amp;quot; }, 
        { id: &amp;quot;2&amp;quot;, name: &amp;quot;orange&amp;quot; }, 
        { id: &amp;quot;3&amp;quot;, name: &amp;quot;banana&amp;quot; }
    ]
});
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="the-snag"&gt;The snag&lt;/h2&gt;
&lt;p&gt;Unfortunately, this handsome drop down doesn't integrate smoothly with &lt;a href="http://knockoutjs.com/"&gt;Knockout JS&lt;/a&gt; when it comes to data binding.&lt;/p&gt;
&lt;p&gt;We should be able to update our HTML to use a Knockout binding:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;p&amp;gt;
    &amp;lt;label for=&amp;quot;kendoDropDown&amp;quot;&amp;gt;Kendo UI Drop Down&amp;lt;/label&amp;gt;
    &amp;lt;input id=&amp;quot;kendoDropDown&amp;quot; type=&amp;quot;text&amp;quot; data-bind=&amp;quot;value: fruitId&amp;quot;
    /&amp;gt;
&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then add a view model and apply the Knockout binding:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;// Define and init the Knockout view model
var ViewModel = function () {
        var self = this;
        self.fruitId = ko.observable();
    },
    vm = new ViewModel();   
&lt;p&gt;// Set the initial fruit value
vm.fruitId(&amp;quot;2&amp;quot;); // orange&lt;/p&gt;
&lt;p&gt;// Wire up KO binding
ko.applyBindings(vm);
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;We should see a drop down loaded with the view model's initial value of &amp;quot;2&amp;quot; (orange), but the first value in the list (&amp;quot;1&amp;quot; apple) is selected instead.  What's going on?&lt;/p&gt;
&lt;h2 id="more-investigation"&gt;More investigation&lt;/h2&gt;
&lt;p&gt;I thought maybe I had a Knockout bug in my code, so I played around with a plain (non-Kendo) select list and a plain text box by adding the following HTML:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;p&amp;gt;
    &amp;lt;label for=&amp;quot;select&amp;quot;&amp;gt;Plain old select&amp;lt;/label&amp;gt;
    &amp;lt;select id=&amp;quot;select&amp;quot; data-bind=&amp;quot;value: fruitId&amp;quot;&amp;gt;
        &amp;lt;option value=&amp;quot;1&amp;quot;&amp;gt;apple&amp;lt;/option&amp;gt;
        &amp;lt;option value=&amp;quot;2&amp;quot;&amp;gt;orange&amp;lt;/option&amp;gt;
        &amp;lt;option value=&amp;quot;3&amp;quot;&amp;gt;banana&amp;lt;/option&amp;gt;
    &amp;lt;/select&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;
    &amp;lt;label for=&amp;quot;textBox&amp;quot;&amp;gt;Plain old text box&amp;lt;/label&amp;gt;
    &amp;lt;input id=&amp;quot;textBox&amp;quot; type=&amp;quot;text&amp;quot; data-bind=&amp;quot;value: fruitId&amp;quot; /&amp;gt;
&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But these controls were set to the correct initial value (&amp;quot;2&amp;quot; orange).&lt;/p&gt;
&lt;p&gt;It gets weirder when you change the view model's value programmatically.  Here, I've added some HTML buttons to do that:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;p&amp;gt;
    &amp;lt;button id=&amp;quot;changeTo3&amp;quot; class=&amp;quot;k-button&amp;quot;&amp;gt;change fruitId to &amp;quot;3&amp;quot; (banana) programmatically&amp;lt;/button&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;
    &amp;lt;button id=&amp;quot;changeTo2&amp;quot; class=&amp;quot;k-button&amp;quot;&amp;gt;change fruitId to &amp;quot;2&amp;quot; (orange) programmatically&amp;lt;/button&amp;gt;
&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and some JavaScript to change the view model's values:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;// Wire up the buttons
$(&amp;quot;#changeTo3&amp;quot;).click(function () {
    vm.fruitId(&amp;quot;3&amp;quot;); // banana
});
$(&amp;quot;#changeTo2&amp;quot;).click(function () {
    vm.fruitId(&amp;quot;2&amp;quot;); // orange
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Clicking the buttons should change the view model's value, which should change the controls' values.  It works for the plain HTML controls, but not for the Kendo UI drop down.&lt;/p&gt;
&lt;p&gt;Here's the &lt;a href="https://jsfiddle.net/joewilson0/dCb5L/38/"&gt;JSFiddle&lt;/a&gt; to see all this in action.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;p&amp;gt;The fruitId should be &amp;quot;2&amp;quot; (orange) initially, then &amp;quot;3&amp;quot; (banana) after
    the button click. The text box and the drop down are bound to the same
    value in the Knockout view model (fruitId).&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;As the drop down is changed manually, the Knockout view model is updated,
    and the drop down and text box show the new value. But as the button is
    clicked and the view model is updated in code, the text box shows the correct
    value, but the drop down does not.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;How can the drop down be set in code with Knockout?&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;
    &amp;lt;label for=&amp;quot;kendoDropDown&amp;quot;&amp;gt;Kendo UI Drop Down&amp;lt;/label&amp;gt;
    &amp;lt;input id=&amp;quot;kendoDropDown&amp;quot; type=&amp;quot;text&amp;quot; data-bind=&amp;quot;value: fruitId&amp;quot;
    /&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;
    &amp;lt;label for=&amp;quot;select&amp;quot;&amp;gt;Plain old select&amp;lt;/label&amp;gt;
    &amp;lt;select id=&amp;quot;select&amp;quot; data-bind=&amp;quot;value: fruitId&amp;quot;&amp;gt;
        &amp;lt;option value=&amp;quot;1&amp;quot;&amp;gt;apple&amp;lt;/option&amp;gt;
        &amp;lt;option value=&amp;quot;2&amp;quot;&amp;gt;orange&amp;lt;/option&amp;gt;
        &amp;lt;option value=&amp;quot;3&amp;quot;&amp;gt;banana&amp;lt;/option&amp;gt;
    &amp;lt;/select&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;
    &amp;lt;label for=&amp;quot;textBox&amp;quot;&amp;gt;Plain old text box&amp;lt;/label&amp;gt;
    &amp;lt;input id=&amp;quot;textBox&amp;quot; type=&amp;quot;text&amp;quot; data-bind=&amp;quot;value: fruitId&amp;quot; /&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;
    &amp;lt;button id=&amp;quot;changeTo3&amp;quot; class=&amp;quot;k-button&amp;quot;&amp;gt;change fruitId to &amp;quot;3&amp;quot; (banana) programmatically&amp;lt;/button&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;
    &amp;lt;button id=&amp;quot;changeTo2&amp;quot; class=&amp;quot;k-button&amp;quot;&amp;gt;change fruitId to &amp;quot;2&amp;quot; (orange) programmatically&amp;lt;/button&amp;gt;
&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;// Init the drop down
$(&amp;quot;#kendoDropDown&amp;quot;).kendoDropDownList({
    dataValueField: &amp;quot;id&amp;quot;,
    dataTextField: &amp;quot;name&amp;quot;,
    dataSource: [
        { id: &amp;quot;1&amp;quot;, name: &amp;quot;apple&amp;quot; }, 
        { id: &amp;quot;2&amp;quot;, name: &amp;quot;orange&amp;quot; }, 
        { id: &amp;quot;3&amp;quot;, name: &amp;quot;banana&amp;quot; }
    ]
});
&lt;p var="" self="this;" self.fruitId="ko.observable();"&gt;// Define and init the Knockout view model
var ViewModel = function () ,
vm = new ViewModel();&lt;/p&gt;
&lt;p&gt;// Set the initial fruit value
vm.fruitId(&amp;quot;2&amp;quot;); // orange&lt;/p&gt;
&lt;p&gt;// Wire up KO bindidng
ko.applyBindings(vm);&lt;/p&gt;
&lt;p&gt;// Wire up the buttons
$(&amp;quot;#changeTo3&amp;quot;).click(function () {
vm.fruitId(&amp;quot;3&amp;quot;); // banana
});
$(&amp;quot;#changeTo2&amp;quot;).click(function () {
vm.fruitId(&amp;quot;2&amp;quot;); // orange
});
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="the-work-around"&gt;The work around&lt;/h2&gt;
&lt;p&gt;A &lt;a href="http://www.kendoui.com/blogs/teamblog/posts/12-02-16/kendo_ui_mvvm_and_knockoutjs.aspx"&gt;Kendo UI team blog post&lt;/a&gt; describes a work around for this issue, but it didn't work for me.&lt;/p&gt;
&lt;p&gt;The trick here is that the Kendo UI drop down is really a hidden input and a bunch of spans.  Knockout changes the value of the hidden input when the view model changes, but you have to hook into that jQuery DOM change event and call the code to select a new value in the Kendo drop down.  Kind of lame, but it's supposed to work.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;$(&amp;quot;#kendoDropDown&amp;quot;).bind(&amp;quot;change&amp;quot;, function() {
    $(this).data(&amp;quot;kendoDropDownList&amp;quot;).select(this.selectedIndex);
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can even unhide the hidden text box inside the Kendo UI drop down list and watch its value change as the view model changes, but the drop down just sits there.  Arg!&lt;/p&gt;
&lt;h2 id="the-real-work-around"&gt;The real work around&lt;/h2&gt;
&lt;p&gt;I was pulling my hair out by now, and &lt;a href="http://stackoverflow.com/questions/14639232/kendo-ui-drop-down-not-updated-when-knockout-view-model-updates"&gt;asked for help on Stack Overflow&lt;/a&gt;.  Unfortunately, the answer I got was use another library that does the integration in a different way, the &lt;a href="https://github.com/kendo-labs/knockout-kendo"&gt;Knockout-Kendo.js library&lt;/a&gt;.  That's probably a good answer, but I was hoping to avoid adding another library just to use Knockout and Kendo UI together.&lt;/p&gt;
&lt;p&gt;Instead, I found I could get everything working as expected with a &lt;a href="http://knockoutjs.com/documentation/observables.html"&gt;Knockout subscription&lt;/a&gt;.  It's like a view model data change listener.  My thinking was that I could use the same concept as the Kendo UI team blog post (listen for a change and then manually set the drop down).  Not ideal, but oh well.&lt;/p&gt;
&lt;p&gt;Here's what I changed in the view model:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-javascript"&gt;self.fruitId.subscribe(function (newValue) {
    $(&amp;quot;#kendoDropDown&amp;quot;).data(&amp;quot;kendoDropDownList&amp;quot;).value(newValue);
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the final, working &lt;a href="https://jsfiddle.net/joewilson0/dCb5L/45"&gt;JSFiddle&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;// Init the drop down
$(&amp;quot;#kendoDropDown&amp;quot;).kendoDropDownList({
    dataValueField: &amp;quot;id&amp;quot;,
    dataTextField: &amp;quot;name&amp;quot;,
    dataSource: [
        { id: &amp;quot;1&amp;quot;, name: &amp;quot;apple&amp;quot; }, 
        { id: &amp;quot;2&amp;quot;, name: &amp;quot;orange&amp;quot; }, 
        { id: &amp;quot;3&amp;quot;, name: &amp;quot;banana&amp;quot; }
    ]
});
&lt;p&gt;// Kendo UI team work recommended around
//$(&amp;quot;#kendoDropDown&amp;quot;).bind(&amp;quot;change&amp;quot;, function() {
//    $(this).data(&amp;quot;kendoDropDownList&amp;quot;).select(this.selectedIndex);
//});&lt;/p&gt;
&lt;p&gt;// Define and init the Knockout view model
var ViewModel = function () {
var self = this;
self.fruitId = ko.observable();
// Real work around
self.fruitId.subscribe(function (newValue) {
$(&amp;quot;#kendoDropDown&amp;quot;).data(&amp;quot;kendoDropDownList&amp;quot;).value(newValue);
});
};
vm = new ViewModel();&lt;/p&gt;
&lt;p&gt;// Set the initial fruit value
vm.fruitId(&amp;quot;2&amp;quot;); // orange&lt;/p&gt;
&lt;p&gt;// Wire up KO binding
ko.applyBindings(vm);&lt;/p&gt;
&lt;p&gt;// Wire up the buttons
$(&amp;quot;#changeTo3&amp;quot;).click(function () {
vm.fruitId(&amp;quot;3&amp;quot;); // banana
});
$(&amp;quot;#changeTo2&amp;quot;).click(function () {
vm.fruitId(&amp;quot;2&amp;quot;); // orange
});
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
</description>
      <pubDate>Sun, 17 Feb 2013 22:07:00 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/increasing-testability</guid>
      <link>https://volaresoftware.com/en/technical-posts/increasing-testability</link>
      <title>Increasing Testability</title>
      <description>&lt;h2 id="testa-what"&gt;Testa-what?&lt;/h2&gt;
&lt;p&gt;I don't know if &amp;quot;testability&amp;quot; is a word, but if Bud Light can make up &amp;quot;drinkability&amp;quot;, maybe it should be.  I'm talking about how pliant your code is to testing.  If you're doing &lt;a href="http://en.wikipedia.org/wiki/Test-driven_development"&gt;TDD&lt;/a&gt; or &lt;a href="http://en.wikipedia.org/wiki/Behavior_Driven_Development"&gt;BDD&lt;/a&gt;, the code you write is testable by definition.&lt;/p&gt;
&lt;p&gt;But if you're going the other way, and coding first or testing &lt;a href="http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1267943524&amp;amp;sr=8-1"&gt;legacy code (any code not already under test)&lt;/a&gt;, you've probably run into code that was hard to test and felt like giving up.  Some of the most common hurdles for testability are not coding to abstractions and not decoupling dependencies.  Here's how to get around that.&lt;/p&gt;
&lt;h2 id="the-problem"&gt;The problem&lt;/h2&gt;
&lt;p&gt;Here's a garden variety Order class with a &lt;code&gt;ProcessOrder&lt;/code&gt; method:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public class Order
{
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public string Email { get; set; }
  public decimal Total { get; set; }
&lt;p&gt;public bool ProcessOrder()
{
var result = false;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Validate order
if (!string.IsNullOrEmpty(this.Email) &amp;amp;amp;amp;&amp;amp;amp;amp; this.Total &amp;amp;gt; 0)
{
  // Send order confirmation email
  var emailService = new EmailService();
  var emailSendResult = emailService.SendOrderConfirmationEmail(this);

  if (emailSendResult == true)
  {
    // Do more order processing...

    result = true;
  }
}

return result;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;And here's the test:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;[Test]
public void Should_return_true_when_using_good_order_values()
{
  // Arrange
  var order = new Order();
  order.FirstName = &amp;quot;Joe&amp;quot;;
  order.LastName = &amp;quot;Wilson&amp;quot;;
  order.Email = &amp;quot;real_email_address@volaresystems.com&amp;quot;;
  order.Total = 123.00m;
&lt;p&gt;// Act
// Watch out!  Don't run this or it will send real emails!
var result = order.ProcessOrder();&lt;/p&gt;
&lt;p&gt;// Assert
Assert.That(result, Is.True);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;We need to call the &lt;code&gt;SendOrderConfirmationEmail&lt;/code&gt; method in the &lt;code&gt;EmailService&lt;/code&gt; class.  But if our test calls &lt;code&gt;ProcessOrder&lt;/code&gt;, there is no way to avoid calling the live emailing method as it's coded now.&lt;/p&gt;
&lt;p&gt;How can we test the logic in the &lt;code&gt;ProcessOrder&lt;/code&gt; method &lt;strong&gt;without&lt;/strong&gt; sending out a real email?&lt;/p&gt;
&lt;h2 id="code-to-abstractions"&gt;Code to Abstractions&lt;/h2&gt;
&lt;p&gt;First, we need to code to an abstraction of &lt;code&gt;EmailService&lt;/code&gt;, not to the concrete class itself.  So let's create an interface around &lt;code&gt;EmailService&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public interface IEmailService
{
    bool SendOrderConfirmationEmail(Order order);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then change the &lt;code&gt;EmailService&lt;/code&gt; class to implement this new interface.  Visual Studio 2008 and &lt;a href="http://www.jetbrains.com/resharper/"&gt;ReSharper&lt;/a&gt; make this easy.&lt;/p&gt;
&lt;p&gt;This will let us change our test later to use a &lt;strong&gt;fake&lt;/strong&gt; version of &lt;code&gt;IEmailService&lt;/code&gt; instead of the real one.&lt;/p&gt;
&lt;h2 id="decouple-and-invert-your-dependencies"&gt;Decouple and Invert your Dependencies&lt;/h2&gt;
&lt;p&gt;The next problem is we're creating an instance of the &lt;code&gt;EmailService&lt;/code&gt; class in the &lt;code&gt;ProcessOrder&lt;/code&gt; method.  Anytime you use &amp;quot;new&amp;quot; in your code, you're probably introducing a dependency and reducing testability.&lt;/p&gt;
&lt;p&gt;The fix is to let the &lt;strong&gt;caller&lt;/strong&gt; create the instance and tell the class or method being called which instance to use.  I am using a private field with constructor injection to set the field instance.  Note we're also now coding to the interface &lt;code&gt;IEmailService&lt;/code&gt; instead of the instance &lt;code&gt;EmailService&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Here's the full Order method using the private field to call the &lt;code&gt;SendOrderConfirmationEmail&lt;/code&gt; method on &lt;code&gt;IEmailService&lt;/code&gt; inside the &lt;code&gt;ProcessOrder&lt;/code&gt; method.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public class Order
{
  private readonly IEmailService _emailService;
&lt;p&gt;public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public decimal Total { get; set; }&lt;/p&gt;
&lt;p&gt;public Order(IEmailService emailService)&lt;/p&gt;
&lt;p&gt;public bool ProcessOrder()
{
var result = false;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Validate order
if (!string.IsNullOrEmpty(this.Email) &amp;amp;amp;amp;&amp;amp;amp;amp; this.Total &amp;amp;gt; 0)
{
  // Send order confirmation email
  //var emailService = new EmailService(); // Created outside this class now
  var emailSendResult = _emailService.SendOrderConfirmationEmail(this);

  if (emailSendResult == true)
  {
    // Do more order processing...

    result = true;
  }
}

return result;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Dependencies can be very hard to spot, but it's critical to tease them out of your code to increase testability.  They can even come from things as innocuous as &lt;a href="http://msdn.microsoft.com/en-us/library/system.datetime.aspx"&gt;DateTime&lt;/a&gt;.  If you're code relies on &lt;code&gt;DateTime.Now&lt;/code&gt;, how will you write unit tests for your logic without changing your system clock when you run the test?  It's simpler to have the caller pass in the &lt;code&gt;DateTime&lt;/code&gt; value and have the method do the calculations based on whatever value it is given.&lt;/p&gt;
&lt;h2 id="make-a-fake"&gt;Make a Fake&lt;/h2&gt;
&lt;p&gt;Now that we've got testable code, we can make a fake &lt;code&gt;EmailService&lt;/code&gt; and update our test.&lt;/p&gt;
&lt;p&gt;First, create the &lt;code&gt;FakeEmailService class&lt;/code&gt; implementing the &lt;code&gt;IEmailService&lt;/code&gt; we created earlier.  We need the &lt;code&gt;SendOrderConfirmationEmail&lt;/code&gt; method to return true to simulate an email being successfully sent.&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public class FakeEmailService : IEmailService
{
  public bool SendOrderConfirmationEmail(Order order)
  {
    return true;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You could also use a mocking framework like &lt;a href="http://code.google.com/p/moq/"&gt;Moq&lt;/a&gt; or &lt;a href="http://www.ayende.com/projects/rhino-mocks.aspx"&gt;Rhino Mocks&lt;/a&gt; for this, but a homemade fake is easy, too.&lt;/p&gt;
&lt;p&gt;Now we're ready to update our test to use the fake and inject it into the &lt;code&gt;Order&lt;/code&gt; constructor:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;[Test]
public void Should_return_true_when_using_good_order_values()
{
    // Arrange
    var emailService = new FakeEmailService();
    order = new Order(emailService);
    order.FirstName = &amp;quot;Joe&amp;quot;;
    order.LastName = &amp;quot;Wilson&amp;quot;;
    order.Email = &amp;quot;real_email_address@volaresoftware.com&amp;quot;;
    order.Total = 123.00m;
&lt;pre&gt;&lt;code&gt;// Act
var result = order.ProcessOrder();

// Assert
Assert.That(result, Is.True);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;h2 id="last-step"&gt;Last step&lt;/h2&gt;
&lt;p&gt;We've refactored the Order class so the caller sends the &lt;code&gt;IEmailService&lt;/code&gt; instance to it.  That makes sense for the test, but what about the real code?&lt;/p&gt;
&lt;p&gt;I typically use an &lt;a href="http://en.wikipedia.org/wiki/Inversion_of_control"&gt;IOC container&lt;/a&gt; like &lt;a href="https://structuremap.github.io/"&gt;Structure Map&lt;/a&gt; or &lt;a href="http://www.castleproject.org/"&gt;Castle Windsor&lt;/a&gt; to hold and resolve an in-memory dictionary of interfaces and class instances.  You wire it up at application startup and when you call something that needs &lt;code&gt;IEmailService&lt;/code&gt;, it creates an instance of &lt;code&gt;EmailService&lt;/code&gt; for you.&lt;/p&gt;
&lt;p&gt;If you're working with legacy code and can't use and IOC container, you also can add a no arg constructor like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-csharp"&gt;public Order() : this(new EmailService())
{
}
&lt;p&gt;public Order(IEmailService emailService)
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Your legacy code keeps calling the no arg constructor like it used to, and any new code and your test code use the constructor with &lt;code&gt;IEmailService&lt;/code&gt; dependency passed in.&lt;/p&gt;
&lt;h2 id="wrap-up"&gt;Wrap up&lt;/h2&gt;
&lt;p&gt;If you code isn't testable, you won't test it.  If you're working with legacy code or writing tests after coding, you can use these techniques to pull out external dependencies so they can be faked for testing.&lt;/p&gt;
&lt;p&gt;You can have it all: testable code, unit tests around that code, and no broken legacy code. Mmmm.Testability. Drink it in!&lt;/p&gt;
</description>
      <pubDate>Sun, 07 Mar 2010 06:30:20 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/articles/ten-mistakes-to-avoid-when-choosing-a-custom-software-development-company</guid>
      <link>https://volaresoftware.com/en/articles/ten-mistakes-to-avoid-when-choosing-a-custom-software-development-company</link>
      <title>Ten mistakes to avoid when choosing a custom software development company</title>
      <description>&lt;p&gt;Custom software development can be a game-changer for businesses, providing tailor-made solutions that meet specific needs. Choosing the right software development company is crucial, but it can be a daunting task. Many companies offer these services, and it's easy to make mistakes that can cost time, money, and even the success of the project.&lt;/p&gt;
&lt;p&gt;Here are ten mistakes to avoid when choosing a custom software development company.&lt;/p&gt;
&lt;h3 id="mistake-1-choosing-a-software-company-that-cant-deliver-what-you-need"&gt;Mistake #1: Choosing a software company that can't deliver what you need&lt;/h3&gt;
&lt;p&gt;The first mistake is selecting a software company that cannot deliver what you need. Custom software development requires a deep understanding of the client's business needs and goals. Choose a software development partner that takes the time to listen, understands your requirements, and has a history of successfully delivering for clients.&lt;/p&gt;
&lt;h3 id="mistake-2-choosing-a-software-company-that-cant-support-you-going-forward"&gt;Mistake #2: Choosing a software company that can't support you going forward&lt;/h3&gt;
&lt;p&gt;Custom software often needs updates to maintain optimal functionality. Choose a software development company that can offer ongoing support, maintenance, and updates to ensure your software stays in tip-top shape. A company that disappears after the project's completion can leave you with a system that quickly becomes outdated or breaks down.&lt;/p&gt;
&lt;h3 id="mistake-3-choosing-an-untrustworthy-software-company"&gt;Mistake #3: Choosing an untrustworthy software company&lt;/h3&gt;
&lt;p&gt;Your software development company will have access to sensitive data and information. Choose a software company with a proven track record and a reputation for trustworthiness. Look for references, testimonials, and reviews to ensure you choose a reliable partner.&lt;/p&gt;
&lt;h3 id="mistake-4-choosing-a-software-company-with-unreasonable-pricing-and-time-ranges"&gt;Mistake #4: Choosing a software company with unreasonable pricing and time ranges&lt;/h3&gt;
&lt;p&gt;Ensure that the pricing and time ranges for your project are reasonable and within your budget. If the software company's prices or timelines seem too good to be true, they probably are. Be wary of software companies that offer fixed prices and unrealistic timelines, as these often result in cost overruns, delays, and tons of stress.&lt;/p&gt;
&lt;h3 id="mistake-5-not-checking-the-software-companys-technology-stack"&gt;Mistake #5: Not checking the software company's technology stack&lt;/h3&gt;
&lt;p&gt;Ensure that the software company's technology stack aligns with your organization's preferred stack. Ask about the technologies they use and how they plan to integrate them into your project.&lt;/p&gt;
&lt;h3 id="mistake-6-not-considering-the-software-companys-communication-skills"&gt;Mistake #6: Not considering the software company's communication skills&lt;/h3&gt;
&lt;p&gt;Effective communication is crucial in custom software development. You need your software development partner to be on the same page throughout the development process. Choose a software company that is responsive and easy to communicate with. Ensure they have a clear communication plan and a project manager who will keep you updated on progress, challenges, and milestones.&lt;/p&gt;
&lt;h3 id="mistake-7-not-considering-the-software-companys-culture-and-values"&gt;Mistake #7: Not considering the software company's culture and values&lt;/h3&gt;
&lt;p&gt;It's important to choose a company whose culture and values align with your own. This can help ensure a successful and positive working relationship.&lt;/p&gt;
&lt;h3 id="mistake-8-not-clarifying-ownership-and-ip-rights"&gt;Mistake #8: Not clarifying ownership and IP rights&lt;/h3&gt;
&lt;p&gt;Ensure that ownership and intellectual property rights are clearly defined in your contracts. This agreement should include who owns the software and its components, who has the right to modify and distribute it, and what happens in case of disputes or termination of the contract.&lt;/p&gt;
&lt;h3 id="mistake-9-not-considering-the-software-companys-development-methodology"&gt;Mistake #9: Not considering the software company's development methodology&lt;/h3&gt;
&lt;p&gt;Different software development methodologies exist, such as Agile and Waterfall. Ensure that the software company's methodology aligns with your project's needs, timeline, and budget. The development methodology should also include regular reviews or demos, invite your feedback, and should change to meet your changing priorities.&lt;/p&gt;
&lt;h3 id="mistake-10-not-signing-a-clear-contract"&gt;Mistake #10: Not signing a clear contract&lt;/h3&gt;
&lt;p&gt;A detailed contract is essential to ensure that both parties understand the scope, timeline, cost, and expectations of the project. The contract should also include provisions for changes, delays, and dispute resolution.&lt;/p&gt;
&lt;p&gt;Choosing the right custom software development company is crucial for the success of your project. Avoid these 10 mistakes and you'll be well on your way to finding the right partner for your business.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://volaresoftware.com/en/contact"&gt;Contact Volare Software today&lt;/a&gt; for more information about &lt;a href="https://volaresoftware.com/en/services/custom-software-development"&gt;custom software development&lt;/a&gt;.&lt;/p&gt;
</description>
      <pubDate>Sun, 02 Apr 2023 18:24:49 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/articles/the-importance-of-listening-to-users-during-the-design-process</guid>
      <link>https://volaresoftware.com/en/articles/the-importance-of-listening-to-users-during-the-design-process</link>
      <title>The importance of listening to users during the design process</title>
      <description>&lt;p&gt;As a custom software development company, creating a web or mobile app that meets the needs of your target audience is essential. One of the best ways to ensure that your app is a success is by listening to user feedback during the design process.&lt;/p&gt;
&lt;p&gt;Here's why:&lt;/p&gt;
&lt;h3 id="users-can-have-insights-you-might-not-think-of"&gt;Users can have insights you might not think of.&lt;/h3&gt;
&lt;p&gt;As product owners or developers, it's easy to get caught up in our own ideas and lose sight of what users really want. By listening to real user feedback from real users, you can gain valuable insights that you might not have thought of on your own. This can help you create an app that is more intuitive, user-friendly, and effective.&lt;/p&gt;
&lt;h3 id="users-can-focus-your-thinking-on-the-essential-parts-of-the-app-they-care-about"&gt;Users can focus your thinking on the essential parts of the app they care about.&lt;/h3&gt;
&lt;p&gt;When developing a web or mobile app, it's easy to get bogged down with features and functionality that users may not even care about. By listening to user feedback, you can get a better sense of what users are looking for in your app and focus your development efforts on those key areas. This can help you create an app that is more streamlined and efficient.&lt;/p&gt;
&lt;h3 id="not-all-user-feedback-is-helpful-but-it-is-important-to-use-it-as-guidance"&gt;Not all user feedback is helpful, but it is important to use it as guidance.&lt;/h3&gt;
&lt;p&gt;Of course, not all user feedback is going to be useful or actionable. However, it's still important to listen to all feedback and use it as guidance. Even negative feedback can provide valuable insight into what users don't like about your app, which can help you make improvements and refine your design.&lt;/p&gt;
&lt;p&gt;At Volare Software, we understand the importance of listening to users during the custom software design process. Our team of experienced app developers has a proven track record of creating custom apps that meet the specific needs of our clients. Whether you're looking to develop a web or mobile app from scratch or need assistance with enterprise app development, we've got you covered.&lt;/p&gt;
&lt;p&gt;So if you're ready to create an app that truly resonates with your target audience, &lt;a href="https://volaresoftware.com/en/contact"&gt;contact us today&lt;/a&gt; to learn more about our &lt;a href="https://volaresoftware.com/en/services/web-and-mobile-app-development"&gt;web and mobile app development services&lt;/a&gt;. With our help, you can create an app that users will love and use time and time again.&lt;/p&gt;
</description>
      <pubDate>Sun, 02 Apr 2023 18:46:50 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/articles/what-is-custom-software</guid>
      <link>https://volaresoftware.com/en/articles/what-is-custom-software</link>
      <title>What is custom software?</title>
      <description>&lt;p&gt;Sure, we sell custom software, but we’ll often be the first to recommend off-the-shelf software if it’s a better fit for your budget, scope, or timeline. Off-the-shelf software is convenient and cost-effective, but sometimes it doesn't quite meet your business's unique needs. In those cases, custom software development may be the better choice.&lt;/p&gt;
&lt;p&gt;You might be wondering: what exactly IS custom software? And how does it differ from the social media apps on your phone or the word processor you use at work?&lt;/p&gt;
&lt;p&gt;Simply put, custom software is a tailored solution designed specifically for your business's needs. Unlike off-the-shelf software, which is designed to be used by a wide range of individuals and organizations, custom software is built with your specific business processes, requirements, and goals in mind.&lt;/p&gt;
&lt;p&gt;Custom software development is similar to building a custom house in many ways. Just as a custom house is designed to meet the specific needs and requirements of its owner, custom software is developed to meet the unique needs and requirements of a business. In both cases, the end result is a solution that is tailored to the owner's exact specifications and reflects their individual style and preferences. Just as a custom house requires a team of architects, builders, and designers to bring the owner's vision to life, custom software development requires a team of developers, designers, and project managers to create a solution that meets the client's specific needs. And just as a custom house can make its owner’s life both more efficient and more beautiful, custom software can add tremendous value to a business, helping to improve productivity, streamline processes, and drive growth.&lt;/p&gt;
&lt;p&gt;Think about it this way: the social media apps you use on your phone are designed to be used by a massive audience, with features and functionality that cater to a broad range of users. Your word processor software may have more specialized features, but it's still designed to be used by a wide range of industries and professions.&lt;/p&gt;
&lt;p&gt;On the other hand, the inventory management system or fleet management software your company uses is likely more specialized and tailored to your business's specific needs. It may have features and functionality that you can't find in off-the-shelf software, and it's designed to help your business operate more efficiently and effectively.&lt;/p&gt;
&lt;p&gt;Custom software can take many forms, from desktop applications to mobile apps to web-based systems. But no matter the form it takes, the goal of custom software development is to create a solution that fits your business like a glove.&lt;/p&gt;
&lt;p&gt;So why choose custom software over off-the-shelf solutions? The answer is simple: because it's designed with your business's unique needs in mind, custom software can provide a level of functionality, efficiency, and productivity that off-the-shelf solutions simply can't match. Plus, because it's built specifically for your business, custom software can be more easily integrated with your existing systems and processes, reducing the time and effort required to train your staff on new software.&lt;/p&gt;
&lt;p&gt;At Volare Software, we specialize in custom software development, helping businesses of all sizes and industries find solutions that meet their unique needs. If you're tired of using off-the-shelf software that just doesn't quite fit, &lt;a href="https://volaresoftware.com/en/contact"&gt;contact us today&lt;/a&gt; to learn more about how &lt;a href="https://volaresoftware.com/en/services/custom-software-development"&gt;custom software&lt;/a&gt; can help take your business to the next level.&lt;/p&gt;
</description>
      <pubDate>Tue, 18 Apr 2023 14:20:03 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/articles/what-does-custom-software-development-cost</guid>
      <link>https://volaresoftware.com/en/articles/what-does-custom-software-development-cost</link>
      <title>What does custom software development cost?</title>
      <description>&lt;h3 id="do-you-need-custom-software"&gt;Do you need custom software?&lt;/h3&gt;
&lt;p&gt;Are you considering custom software development?&lt;/p&gt;
&lt;p&gt;While there are already plenty of software options available for common business tasks, such as accounting or HR, there are situations where commodity software won't do. For example, if you have a unique business problem or product, or the software on the market today doesn't match your business needs, custom software development may be the solution.&lt;/p&gt;
&lt;p&gt;But what does custom software development cost?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Small projects, like MVPs, can be as little as $25,000/€23,000 for one, full-time developer for 1-2 months.&lt;/li&gt;
&lt;li&gt;Medium projects are $50,000/€45,000 - $250,000/€225,000 and take 3-6 months for one or two full-time developer(s).&lt;/li&gt;
&lt;li&gt;Very large projects for enterprise customers and government entities are more complex and take more people and more time. They can be 6 months to several years to complete, so they can cost well over $250,000/€225,000 - $1,100,000/€1,00,000 for three to five full-time developers for 6-12 months.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="how-we-estimate-custom-software-costs"&gt;How we estimate custom software costs&lt;/h3&gt;
&lt;p&gt;Unlike building a basement or a house, custom software pricing is not straightforward.&lt;/p&gt;
&lt;p&gt;At Volare Software, a custom software development company, we don't provide fixed bid contracts. Instead, we estimate the monthly running cost for a development team, and the duration and total cost are given as ranges based on the minimum and maximum estimates for the modules in the system.&lt;/p&gt;
&lt;p&gt;We are transparent with potential customers that the total cost and durations are estimates constructed by adding up lots of smaller guesses, so the margin of error is very high. However, we can commit to the cost of the development team for each month, and we can resize the team and monthly budget up or down as needed.&lt;/p&gt;
&lt;p&gt;What takes one developer six months does not take two developers three months. There is communication and code integration overhead to account for.&lt;/p&gt;
&lt;p&gt;Having more developers usually means you get the software delivered more quickly, but there is a point of diminishing returns. We've found that three to five developers can be as productive as ten.&lt;/p&gt;
&lt;h3 id="avoid-fixed-bid-pricing"&gt;Avoid fixed bid pricing&lt;/h3&gt;
&lt;p&gt;Fixed bid contracts require all project details to be known and documented up front. However, we've never been on a project where those initial plans didn't change, and they usually change significantly.&lt;/p&gt;
&lt;p&gt;Fixed bid contracts put the consulting company in the position of arguing with their client that the new thing or the change or the different interpretation they have was not in the original specifications and was not included in the price they were given. This model of constant contract negotiating with your customer is not a positive experience for either party, and it adds to the overhead of the project.&lt;/p&gt;
&lt;p&gt;Instead, we prefer to say &amp;quot;yes&amp;quot; to customer ideas and changes, telling the customer the impact of the change. Ultimately, the customer decides if it's worth the extra time and cost.&lt;/p&gt;
&lt;h3 id="deliver-the-most-important-software-early"&gt;Deliver the most important software early&lt;/h3&gt;
&lt;p&gt;At Volare Software, we use an agile software development process where the most important features of the system are built first. These are usually the highest value modules in the system.&lt;/p&gt;
&lt;p&gt;By building the key modules early, we bring the value and the risk forward in the software project, ensuring the software meets your goals and can be a successful product.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://volaresoftware.com/en/contact"&gt;Contact us today&lt;/a&gt; to learn more about our &lt;a href="https://volaresoftware.com/en/services/custom-software-development"&gt;custom software development services&lt;/a&gt;.&lt;/p&gt;
</description>
      <pubDate>Mon, 06 Aug 2018 06:00:00 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/articles/five-essential-steps-to-ensure-your-web-app-is-secure</guid>
      <link>https://volaresoftware.com/en/articles/five-essential-steps-to-ensure-your-web-app-is-secure</link>
      <title>Five Essential Steps to Ensure Your Web App is Secure</title>
      <description>&lt;p&gt;It seems like every time we read the news, we see another headline about a data breach. With cyber attacks on the rise, it’s important to ensure your web app is secure. So, how can you be sure your web app is secure? In this blog post, we’ll share five essential steps to ensure your web app is secure.&lt;/p&gt;
&lt;h3 id="encrypt-all-traffic"&gt;Encrypt all traffic&lt;/h3&gt;
&lt;p&gt;Encrypting all traffic between your website and its users is essential for securing your web app. This means using HTTPS instead of HTTP. HTTPS encrypts data in transit, so even if someone intercepts the traffic, they won’t be able to read it. To implement HTTPS, you need to obtain an SSL/TLS certificate from a trusted certificate authority and install it on your server. Many hosting providers offer free SSL/TLS certificates, so there’s no excuse not to use HTTPS.&lt;/p&gt;
&lt;h3 id="encrypt-sensitive-data-in-the-database-and-dont-store-it-if-thats-an-option"&gt;Encrypt sensitive data in the database and don't store it if that's an option&lt;/h3&gt;
&lt;p&gt;Encrypting sensitive data in your database is another important step to securing your web app. This includes user passwords, credit card numbers, and any other personally identifiable information. Encryption makes it much harder for hackers to access this information if they manage to breach your defenses. However, if possible, it’s best not to store sensitive data at all. If you don't need to store sensitive data, don't store it. It’s that simple.&lt;/p&gt;
&lt;h3 id="run-security-scans"&gt;Run security scans&lt;/h3&gt;
&lt;p&gt;Security scans are a great way to find vulnerabilities in your web app. There are many tools available that can help you scan your website for common security issues. Some of these tools are free, while others require a paid subscription. It’s worth investing in a good security scanner to ensure you’re not leaving any vulnerabilities exposed.&lt;/p&gt;
&lt;h3 id="run-static-code-evaluations"&gt;Run static code evaluations&lt;/h3&gt;
&lt;p&gt;Static code evaluations are another way to identify potential security issues in your web app. These evaluations analyze your code for common vulnerabilities such as SQL injection, cross-site scripting, and buffer overflows. By identifying these issues early, you can fix them before they become a problem.&lt;/p&gt;
&lt;h3 id="check-security-headers"&gt;Check security headers&lt;/h3&gt;
&lt;p&gt;Security headers are a powerful tool for securing your web app. They tell browsers and other applications how to behave when interacting with your website. For example, the Content-Security-Policy header can be used to prevent cross-site scripting attacks by telling the browser to only load resources from trusted sources. Checking that your web app has the appropriate security headers is an important step in securing your web app.&lt;/p&gt;
&lt;p&gt;In conclusion, securing your web app is essential to protecting your business from cyber attacks. By encrypting all traffic, encrypting sensitive data in your database, running security scans and static code evaluations, and checking security headers, you can help ensure that your web app is secure. Remember, security should be a top priority for any website owner or developer.&lt;/p&gt;
&lt;p&gt;At Volare Software, we specialize in &lt;a href="https://volaresoftware.com/en/services/custom-software-development"&gt;custom software development&lt;/a&gt;, helping businesses of all sizes and industries find solutions that meet their unique needs. If you’re looking for custom software and security is a top concern, &lt;a href="https://volaresoftware.com/en/contact"&gt;contact us today&lt;/a&gt; to learn more about how Volare Software can help take your business to the next level.&lt;/p&gt;
</description>
      <pubDate>Tue, 18 Apr 2023 14:27:52 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/articles/buy-build-or-both</guid>
      <link>https://volaresoftware.com/en/articles/buy-build-or-both</link>
      <title>Buy, Build, or Both?</title>
      <description>&lt;p&gt;You need to open up a new market, cut costs, or automate a process. New software can help solve this problem, but which software meets your needs?&lt;/p&gt;
&lt;p&gt;There are three main categories of software: 1) packaged software, 2) software as a service (SaaS), and 3) custom software. This article covers the pros and cons of each type of software and can help you make the right purchase decision for your business.&lt;/p&gt;
&lt;h3 id="when-is-packaged-software-or-saas-the-right-choice"&gt;When is packaged software or SaaS the right choice?&lt;/h3&gt;
&lt;p&gt;If you want a word processor, email client, or accounting package, it's been done. The products are numerous, mature, and range from free to very reasonably-priced.&lt;/p&gt;
&lt;p&gt;More and more business software is falling into this commodity space, such as enterprise content management solutions, document management programs, and customer relationship management (CRM) software. These tools have a single purpose and usually very good at what they do.&lt;/p&gt;
&lt;p&gt;Cost wise, buying software is usually cheaper than building custom software. As we'll see later on, there are some caveats to this, but this conventional wisdom is often correct.&lt;/p&gt;
&lt;p&gt;This is where most software evaluations end. It meets your requirements and it's cheaper. Make the purchase and move on, right? Well hold on a sec.&lt;/p&gt;
&lt;p&gt;There are some risks to packaged software and SaaS that are often overlooked:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;They often include modules you don't want and may not be an exact fit for your business. Adding the modules you do want is extra. So is implementing the software and customizing it to fit your business.&lt;/li&gt;
&lt;li&gt;They work in functional silos and are usually from multiple vendors. You've got to be sure it will integrate with your other systems.&lt;/li&gt;
&lt;li&gt;They may not let you get the data out the way you want it.&lt;/li&gt;
&lt;li&gt;Your users may not be as excited about your choice as you are.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let's take a closer look at these problems and when they may ultimately push your decision to the custom software side.&lt;/p&gt;
&lt;h3 id="get-just-what-you-want-no-more-no-less"&gt;Get just what you want, no more, no less&lt;/h3&gt;
&lt;p&gt;Buying software &amp;quot;off the rack&amp;quot; is the way to go if the package meets all your business requirements. But most of the time, you're buying functionality you don't need and missing functionality you do need. You shouldn't have to change your business to match the software you've just purchased.&lt;/p&gt;
&lt;p&gt;The common answer is to have consultants implement a solution and customize it to your business. If the packaged software is a good fit with your requirements, this can be a good choice, too. You just want the consultants to come in and round out the corners, though. They shouldn't need to rewrite anything; just configure it for your organization and maybe integrate your new software with some of your existing systems.&lt;/p&gt;
&lt;p&gt;But at some point (and it should be pretty soon after the install), the consultants should finish and go home. If they need to stick around for lots of customizations or integrations, you may have lost the justification for buying instead of building it. And don't forget that all those customizations can't just be thrown out when the vendor rolls out the next version of the product you've bought. Too many companies make this mistake and fall into a cycle of perpetually customizing packaged software.&lt;/p&gt;
&lt;p&gt;With custom software, the program meets all the requirements of the business and doesn't include any modules you don't want. It usually costs more initially, but because you buy only what you need, nothing more, you won't need to perpetually customize.&lt;/p&gt;
&lt;h3 id="get-deep-integration-with-your-existing-systems"&gt;Get deep integration with your existing systems&lt;/h3&gt;
&lt;p&gt;With packaged software, integration with your other systems ranges from simple to a painful implementation project. For example, if you purchase CRM software and want to load all your existing customers into it, the tool should provide this. Most consultants can do this work quickly. Painful integrations are when you can't get the data out, or you can get it out, but you have to use the vendor's very strange API to pull just one record at a time.&lt;/p&gt;
&lt;p&gt;If the new system is one piece of a larger process, or if it will be the system of record for your enterprise data, you will have many integration points for data coming into and out of the new system.&lt;/p&gt;
&lt;p&gt;With custom software applications, those integration points are built in because they are part of the original requirements. The software integrates deeply with your current enterprise systems.  If done right, the new integration APIs are written in standard ways that are discoverable by any new applications that may come online in the future.&lt;/p&gt;
&lt;h3 id="how-stable-is-that-vendor-what-is-your-exit-plan"&gt;How stable is that vendor? What is your exit plan?&lt;/h3&gt;
&lt;p&gt;The main value proposition of packaged software is the functionality you get for the price you pay. But that value can go out the window if the vendor goes out of business or is purchased and no longer supports your software. And what happens if you get their software deeply embedded in your business and the vendor goes up on price next time you're negotiating their contract. Vendor lock-in is a real business risk.&lt;/p&gt;
&lt;p&gt;In a struggling economy, it's not unusual to see smaller software vendors bought out by larger ones. It's also common to see start-up SaaS companies offering low introductory prices to get customers on board, then gouging them once the cost of leaving that vendor gets high enough. When purchasing software, consider the long term costs and how you would get your data out.&lt;/p&gt;
&lt;p&gt;And don't just make a plan. You need to test that your plan really works and you can get the data out when you need it and in a format that is useful to you. This is like a building evacuation plan. Usually no one reads the plan until the emergency happens, and then it's too late. You have to actually test pulling your data out in a non-emergency situation to see if the plan will really work.&lt;/p&gt;
&lt;p&gt;With custom software, your business owns all the code and all the data from the start. Most systems are turned over to IT departments after the construction phase, so there is no risk of your data being held hostage.&lt;/p&gt;
&lt;p&gt;Although unlikely, it's certainly possible to have your custom software development vendor go out of business or be purchased by a competitor during the development phase. However, if the system is written using your IT department's standards and your application development vendor is releasing working versions of code every few weeks, you minimize vendor lock-in or vendor going-out-of-business risk.&lt;/p&gt;
&lt;h3 id="where-is-the-data-stored"&gt;Where is the data stored?&lt;/h3&gt;
&lt;p&gt;With packaged software, the data is often stored in a proprietary database. Even if it's in a more common database format, many vendors will not support direct queries or reports against the data store.&lt;/p&gt;
&lt;p&gt;If you're using SaaS and the data is in the cloud, you can't be sure where it is. That works great for some organizations that really want the redundancy and availability, but for sensitive data or for businesses that are heavily regulated, data security will be a deciding factor in your purchase.&lt;/p&gt;
&lt;p&gt;Custom software puts the data where the organization wants it because access to and location of the data are part of the requirements. It's as secure, redundant, and available to queries and reports as the requirements dictate.&lt;/p&gt;
&lt;h3 id="get-user-buy-in"&gt;Get user buy in&lt;/h3&gt;
&lt;p&gt;The typical IT buying process is to identify the requirements and find the packaged software that best fits. This evaluation is often handed over to a technical person to be sure the software is a fit for the organization from an IT perspective.&lt;/p&gt;
&lt;p&gt;The problem comes when a package is selected and the users are told that starting next Monday, they will be in training, and starting the Monday after that, they will be using the new system. If the users haven't helped choose the software, they may reject it or sabotage the implementation.&lt;/p&gt;
&lt;p&gt;With custom software and custom integration projects, users are involved in the requirements early on, and the new system should be tailored to their specifications. They are the most critical stake holders and can set the tone for a successful adoption throughout your organization.&lt;/p&gt;
&lt;h3 id="conclusion"&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Software purchase decisions can be as complex as the problems they attempt to solve. Decision makers need to consider short and long term costs and risks of buying packaged or SaaS software as is, buying it and customizing it to integrate into the business, or going with custom application software the whole way. The easy answer is not always the best answer when all the risks are considered.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://volaresoftware.com/en/contact"&gt;Contact Volare Software today&lt;/a&gt; for more information about &lt;a href="https://volaresoftware.com/en/services/custom-software-development"&gt;building custom software&lt;/a&gt; for your business.&lt;/p&gt;
</description>
      <pubDate>Sat, 12 Aug 2023 11:50:33 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/articles/how-we-do-agile-software-development</guid>
      <link>https://volaresoftware.com/en/articles/how-we-do-agile-software-development</link>
      <title>How we do agile software development</title>
      <description>&lt;p&gt;We follow an agile software development process that has been revisited, updated, and tweaked over the 13 years we've been in business. We are happy with the process we have now, but we're always trying to improve it. If you see inefficiencies or blind spots, please let us know in the comments below.&lt;/p&gt;
&lt;h2 id="planning-and-project-management"&gt;Planning and Project Management&lt;/h2&gt;
&lt;h3 id="stories-and-bug-fixes"&gt;Stories and Bug Fixes&lt;/h3&gt;
&lt;p&gt;The business, usually through a single product manager, is primarily responsible for writing up new stories. The content should be enough for the author to remember what he/she was talking about when asked for details in the future. Once the placeholder story comes up in the work cycle, the delivery team gets with the relevant stake holders and asks them questions about the feature, ideally working through and writing up some concrete examples and coming up with a design if needed. These conversations and examples highlight the reason for the feature. and serve as a powerful motivator for the delivery team.&lt;/p&gt;
&lt;p&gt;There is no need to write stories in the language, &amp;quot;As a ____, I want to ____, so I can ____.&amp;quot;. The blanks should have been filled in from the conversations and may or may not be useful to write into the story. That's up to the team if they want to document that for posterity or new people joining the team, but it's faster to tell people the reason this story matters to the business and transfer the knowledge that way.&lt;/p&gt;
&lt;p&gt;There is no need to agree on a definition of a story being &amp;quot;ready&amp;quot; for the team to work on. If it's at the top of the backlog and needs design work or more details, it's your job to chase that down before coding starts. We don't start coding until we have acceptance criteria that is clear enough for the developer. The developer usually writes up the steps for testing for the tester and product owner and business.&lt;/p&gt;
&lt;p&gt;Everyone on the team can write a story. Developers and testers find technical debt, bugs, and UI inconsistencies all the time. The team can prioritize this work, but it is important that it is visible to both the delivery team and the business.&lt;/p&gt;
&lt;p&gt;There is no need to separate feature work from bug work. A bug is when the software does something the business doesn't want it to. A feature is when the software doesn't yet do something the business wants it to. There is no need for a blanket policy of &amp;quot;fix all bugs first&amp;quot;. The business knows if there are low priority bugs that can wait while a high impact feature is being worked on.&lt;/p&gt;
&lt;p&gt;We don't trace user stories to epics and don't usually break them down into tasks. If stories have a common theme, they can be tagged with a label or colored the same color if needed.&lt;/p&gt;
&lt;h3 id="estimating"&gt;Estimating&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://volaresoftware.com/en/articles/avoiding-software-estimates"&gt;We don't estimate story sizes&lt;/a&gt;. We can tell the business how many stories we average per release or per time period. Using this knowledge and seeing how far back the story is in the backlog and the number of stories in progress, the business can roughly calculate when that bug fix or feature will be in production.&lt;/p&gt;
&lt;h3 id="priorities"&gt;Priorities&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2023/8/Kanban.png" alt="Kanban board" /&gt;&lt;/p&gt;
&lt;p&gt;Stories are ranked in the backlog in priority order, with the highest priority stories at the top. If the story or bug fix is important, it can be moved up so it is more likely to be in the next release or the one after that.&lt;/p&gt;
&lt;p&gt;The business can change the delivery team priorities at any time, and the attitude of the delivery team should be that we're glad to do it because we are there to work with the business to make the software as effective as possible.&lt;/p&gt;
&lt;p&gt;Occasionally, there are very high priority bug fixes that need to be made. We can add a swim lane to our &lt;a href="https://en.wikipedia.org/wiki/Kanban_board"&gt;online Kanban board&lt;/a&gt; for these, and they get expedited treatment to get the fix into production as quickly as possible.&lt;/p&gt;
&lt;h3 id="workflow"&gt;Workflow&lt;/h3&gt;
&lt;p&gt;Stories are worked from left to right in the &lt;a href="https://en.wikipedia.org/wiki/Kanban_board"&gt;online Kanban board&lt;/a&gt;. The leftmost column is the Backlog. The rightmost column is stories pushed to production. The columns in between vary based on the project, but usually include Development, Testing, and Ready for Acceptance Testing, which is a queue where stories sit until the next release to the user acceptance testing environment, and User-Acceptance Testing.&lt;/p&gt;
&lt;p&gt;More than one person can be assigned a story. Anyone on the team can move a story, ideally with a comment about why they made the move. We don't both with hard WIP (work in progress) limits, because we socialize that you can truly only work on one thing at a time, and it's OK to have two stories sitting in the Development column if you are waiting for answers on one of them and it may take a few days to get a response.&lt;/p&gt;
&lt;p&gt;When testers review developers' work and find issues, they write up enough details for the developer to reproduce the issue, ideally with screen shots or a walkthrough, and the story is moved back to the Development column for fixing. That now becomes that developer's top priority and the fix is usually not time consuming, and then the story move back to Testing with comments from the developer about the fix.&lt;/p&gt;
&lt;p&gt;The same process happens with user acceptance testing. If the produce owner or business find a bug or think of a change they want made, the story gets updated and moved back to the Development column. Sometimes the change requested is big enough to warrant a new story which also needs to be prioritized.&lt;/p&gt;
&lt;h3 id="reporting-status"&gt;Reporting Status&lt;/h3&gt;
&lt;p&gt;There is no need for daily standups or status reports. We have an &lt;a href="https://en.wikipedia.org/wiki/Kanban_board"&gt;online Kanban board&lt;/a&gt; that shows all stories in progress, their status, and who is working on them. The delivery team and the business have access to this task board. Everything the delivery team is working on is transparent.&lt;/p&gt;
&lt;h3 id="communication-and-meetings"&gt;Communication and Meetings&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2023/8/Online_Meeting.png" alt="Meeting" /&gt;&lt;/p&gt;
&lt;p&gt;If there are no daily standups or status reports, how do we communicate? Since we work remotely, we do it all online. If you've got an internet connection, you're all set. We mostly use instant messaging tools and escalate to phone or video call or screen sharing as needed. Email and phone calls work, too, but those are secondary and usually used when someone we need to talk with doesn't use the same IM tool as the delivery team.&lt;/p&gt;
&lt;p&gt;Stock images make meetings look fun, but synchronous meetings (e.g., 5 of us need to be on a call at 10am today) are expensive and their purpose is often better accomplished in other ways. Instant messaging allows us to have asynchronous meetings, so you can keep working and hop into the discussion when you have time. This avoids context switching and prevents developers and testers from looking at the clock, seeing they have a meeting in 15 minutes, and deciding not to start something new. Software design, development. and testing require uninterrupted thinking for big chunks of time, and async meetings are critical to not disturbing someone's flow.&lt;/p&gt;
&lt;h3 id="blocks-and-team-dynamics"&gt;Blocks and Team Dynamics&lt;/h3&gt;
&lt;p&gt;If people on the delivery team are blocked (e.g., &amp;quot;I can't access the database.&amp;quot;, &amp;quot;How does the business want these buttons to look?&amp;quot;, &amp;quot;I'm stuck on some SignalR syntax.&amp;quot;, etc.), it's up to those team members to report that right away. Because there is no daily standup, there is no waiting until the next day to mention it. Anyone who can helps the blocked team member or gets them with someone who can help them.&lt;/p&gt;
&lt;p&gt;A key assumption here is that the blocked team member will speak up and not quietly flounder for hours or days. We make sure asking for help doesn't come at the price of being teased or humiliated for not knowing something.&lt;/p&gt;
&lt;p&gt;Everyone on the team must help other team members. In fact, how this is approached is crucial. If you ask a developer if they need help with something, 9 times out of 10 they will reflexively say no. They want to figure it out on their own, they think they've almost got it, etc. If you instead ask, &amp;quot;How can I help?&amp;quot; or &amp;quot;Why don't we look at this together - it's tricky.&amp;quot; or &amp;quot;Can you show me how you did that? I want to learn it too.&amp;quot; you'll have more success.&lt;/p&gt;
&lt;p&gt;Be humble. Be considerate. Be sincere. Be helpful. Be cheerful.&lt;/p&gt;
&lt;h2 id="development-practices"&gt;Development Practices&lt;/h2&gt;
&lt;h3 id="testing"&gt;Testing&lt;/h3&gt;
&lt;p&gt;We write LOTS of client and server-side unit tests. These tests help ensure the happy path tests cases are covered and that the corner cases have at least been thought through. They also drive a decoupled design where we can mock things as needed that are not directly under test, like database queries that need to return specific data to hit a code path.&lt;/p&gt;
&lt;p&gt;These tests become more valuable over time. You can change something in one part of the code base and feel confident you didn't break something you wrote 6 months ago after seeing all the tests pass.&lt;/p&gt;
&lt;p&gt;Running the unit tests to check the software is not enough to know we're done, so we also use a combination of integration, end-to-end, and manual testing.&lt;/p&gt;
&lt;p&gt;We write some, but not as many integration and end-to-end tests where we're testing database, API calls, or the entire front and back end. These tests are slower to run and harder to maintain with all the setup needed, so we use these kinds of tests only in the most crucial pieces of the app (e.g., the shopping cart better work).&lt;/p&gt;
&lt;p&gt;Developers are responsible for manually testing their own code. They wrote it, so they should know where the pitfalls could be. They are also responsible for writing detailed test scripts for team members who will be testing after them. These are usually added to the story. A developer can only move a story once they have done their own manual testing and writing detailed acceptance criteria.&lt;/p&gt;
&lt;p&gt;We also have a tester that does manual testing to double-check that the developer didn't forget anything. This manual testing is helpful for limit testing (e.g., try values like –1, 0, or 1), validation testing (e.g., if the field says it's required, it really is), cross-browser testing (e.g., if the developers are using Chrome to code/test, does it also work with Safari on iPads?), and logic testing.&lt;/p&gt;
&lt;p&gt;We don't measure test coverage. We have in the past, but we have never known what to do with the data. 100% test coverage isn't a goal. 50% or 75% coverage doesn't tell me we need more tests, or we have enough. It's trivia and adds overhead, so we don't bother any more.&lt;/p&gt;
&lt;h3 id="code-patterns-and-refactoring"&gt;Code Patterns and Refactoring&lt;/h3&gt;
&lt;p&gt;We develop code patterns for the project by asking all developers for input. Over time, we change our mind about some of those patterns or make updates to tools. If we can, we pull the pattern out as a shared piece of code so it can be changed in one place. If that's not practical, we bring code forward to the new patterns as we work on it.&lt;/p&gt;
&lt;p&gt;We refactor code as needed, usually following our own version of the Boy Scout rule (always leave the campground cleaner than you found it). If you open a piece of code to make a &lt;em&gt;small&lt;/em&gt; change, leave the rest of the code alone. If you need to make &lt;em&gt;major&lt;/em&gt; changes, bring that code up to the latest coding patterns and tools the team is using today.&lt;/p&gt;
&lt;p&gt;Because we have extensive test suites, major code changes are not a scary thing for the team.&lt;/p&gt;
&lt;h3 id="pair-programming-and-code-reviews"&gt;Pair Programming and Code Reviews&lt;/h3&gt;
&lt;p&gt;Pair programming is used, but typically on new or complex code or with new team members. Most developers prefer to work through the problem alone, but sometimes that's a little overwhelming and pairing for an hour or so is hugely helpful.&lt;/p&gt;
&lt;p&gt;We do code reviews of each other's work, but it's not every for every commit. If a developer is feeling a little unsure about their work or coding patterns or working on something that will be shared by the whole team, a code review makes sense.&lt;/p&gt;
&lt;p&gt;Pair programming and code reviews are fantastic ways to socialize coding patterns and check in with developers to make sure they understand and are using the team agreed to development patterns.&lt;/p&gt;
&lt;h3 id="just-in-time-architecture-and-ui-design"&gt;Just-in-time Architecture and UI Design&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2023/8/Just_In_Time.png" alt="Justin Timberlake" /&gt;&lt;/p&gt;
&lt;p&gt;We don't have a big architecture plan before we start the project. We have a rough idea of how it will go, but we try to code in such a way that we have options and can change the architecture just-in-time as needed during development.&lt;/p&gt;
&lt;p&gt;For some stories, the UI design is a key to solving the problem. In those cases, we use mockup tools to quickly draft a UI and get feedback from the business and product owner. We cycle through that feedback until we're happy with the design, and then the mockups become attachments in the story so the developer has a template of what the finished product should look like.&lt;/p&gt;
&lt;p&gt;UI design mockups can be very powerful when done live with the customer, and the tools are simple enough that ideas can become concrete designs very quickly.&lt;/p&gt;
&lt;h3 id="branching"&gt;Branching&lt;/h3&gt;
&lt;p&gt;We don't usually create branches for feature or bug fixes. Everyone works on master. We have branches for releases, like a user-acceptance testing branch and a production branch, so we can hop onto a branch and make a fix and merge it back to the lower branches as needed. We create labels/tags for each release candidate.&lt;/p&gt;
&lt;h3 id="continuous-deployment-and-feedback"&gt;Continuous Deployment and Feedback&lt;/h3&gt;
&lt;p&gt;Every code commit pushes a new release to a development web server. This tests our code integrations and builds, but more importantly, it gives the team's tester, product owner, and any other stake holders a live look at the latest working code.&lt;/p&gt;
&lt;p&gt;The delivery team is constantly asking for feedback from the product owner and the business about how the software is working or not working so we can adjust. With custom software, they key to getting what you want is giving the delivery team lots of feedback on the in-progress software. Continuously deployment is the place to take the latest code for a test drive.&lt;/p&gt;
&lt;h2 id="release-management"&gt;Release Management&lt;/h2&gt;
&lt;h3 id="time-boxed-vs.feature-driven"&gt;Time-boxed vs. Feature-driven&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://cdn.volaresoftware.com/images/posts/2023/8/Stopwatch.png" alt="Stopwatch" /&gt;&lt;/p&gt;
&lt;p&gt;Releases can be either time-boxed, where we release everything that's done every 2 weeks, or they can be feature-driven, where we release when a feature is complete. We sometimes compromise and release every 2 weeks unless there is something important that is &lt;em&gt;almost&lt;/em&gt;done, and then we'll wait another couple of days before releasing with that feature. We don't do this every release, and the product owner, business, and delivery team should reach consensus on whether to hold up a release.&lt;/p&gt;
&lt;p&gt;Time-boxed releases are nice and steady and give the business an expectation of when they can have working code in production. We use feature toggles to turn off parts of the app that are not ready for production so we can still deploy code with partial features.&lt;/p&gt;
&lt;p&gt;We don't build up sprints with points for time-boxed releases because I have seen negative side effects of that approach. Team members finish early and don't want to start a new story because it's for next week's sprint, or team members are working like crazy to finish before the sprint cutoff so their feature makes it into this release. Both go against the idea of having a steady, sustainable pace of work. If we're doing a release and code isn't ready and won't be ready tomorrow, that's OK.&lt;/p&gt;
&lt;h3 id="definition-of-done"&gt;Definition of Done&lt;/h3&gt;
&lt;p&gt;We agree on a story being done when the acceptance criteria has been met, the code is checked in, there are passing automated tests for the code, detailed steps for testing the story have been written, the manual testing found no remaining issues, and the business accepted the story as done. At any point, a story moved to the right that doesn't meet one of these can be sent back to the left for rework.&lt;/p&gt;
&lt;h3 id="acceptance-testing-the-release-candidate-and-deploying-to-production"&gt;Acceptance Testing the Release Candidate and Deploying to Production&lt;/h3&gt;
&lt;p&gt;We set up a development integration environment, a staging or user-acceptance testing environment, and production. Once a release candidate has been deployed, the product owner and business test those features. Ideally, this is not the first time they have seen these features or bug fixes, and they are confirming they still work as expected in this release candidate and environment.&lt;/p&gt;
&lt;p&gt;After the business and product owner give the go ahead that the release candidate looks OK, it's deployed to production.&lt;/p&gt;
&lt;h2 id="process-review-and-improvement"&gt;Process Review and Improvement&lt;/h2&gt;
&lt;h3 id="retrospectives"&gt;Retrospectives&lt;/h3&gt;
&lt;p&gt;We don't have sprint retrospectives. Any time is a good time for improvement. We have a culture where suggestions are always carefully considered and incorporated where possible, even if they are a little experimental.&lt;/p&gt;
&lt;h3 id="calculations"&gt;Calculations&lt;/h3&gt;
&lt;p&gt;After a release, we can recalculate our cycle time (how long it takes a story from work starting to installed in production). This, combined with counting the number of stories per release can give the business a simple tool for predicting when a story they have their eye on will land in production.&lt;/p&gt;
&lt;p&gt;For example, if we complete an average of 10 stories per release, and the story in question is number 3 in the backlog and there are 6 stories on the board in progress right now, there is a small chance that story will make it into the current release (it would be the 9th story, and we average 10), but there is very good chance that story will be in the next release after the current one.&lt;/p&gt;
</description>
      <pubDate>Sat, 12 Aug 2023 11:43:25 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/articles/ten-disasters-to-avoid-in-your-next-custom-software-development-contract</guid>
      <link>https://volaresoftware.com/en/articles/ten-disasters-to-avoid-in-your-next-custom-software-development-contract</link>
      <title>Ten disasters to avoid in your next custom software development contract</title>
      <description>&lt;p&gt;Custom software development is not just about coding. It's about effective communication, mutual understanding, and well-drafted contracts.&lt;/p&gt;
&lt;p&gt;Contracts define terms, conditions, and expectations that may arise during the project. But when the contract itself fails to protect your interests, it can lead to disastrous results for your business.&lt;/p&gt;
&lt;p&gt;Here we'll discuss ten potential disasters to avoid when writing a contract for custom software development services.&lt;/p&gt;
&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;
&lt;p&gt;Custom software development is a complex process that involves multiple stakeholders, including clients, vendors, project managers, and developers. A well-drafted contract can help all parties achieve their goals and mitigate potential risks.&lt;/p&gt;
&lt;p&gt;As the client, you need to ensure that the vendor delivers what they promised and meets your expectations. Vendors need to ensure that they are paid in a timely manner.&lt;/p&gt;
&lt;p&gt;Here are ten disastrous consequences that can stem from a poorly-written contract:&lt;/p&gt;
&lt;h3 id="disaster-1-no-termination-clause"&gt;Disaster #1: No termination clause&lt;/h3&gt;
&lt;p&gt;Can you fire the vendor if they fail they deliver substandard work? Without a clear termination clause, you may not have the legal authority to terminate the contract, which can result in delays and financial losses. be sure you have a termination clause that lets you end the contract immediately if you are not happy with the software company's performance.&lt;/p&gt;
&lt;h3 id="disaster-2-ambiguous-scope-of-work-and-unclear-process-software-development-process"&gt;Disaster #2: Ambiguous scope of work and unclear process software development process&lt;/h3&gt;
&lt;p&gt;What if the software development company interprets the scope of work differently from what you intended? Do they have a process that can help surface that difference so you can address it? If not, this can lead to disputes and project delays. A clearly-defined scope of work can avoid misunderstandings, but for all but the simplest projects, the scope of work is not enough. You must define the process the development company will use to build the software so you have opportunities to see the work in progress, give feedback, and have the software company change course if needed.&lt;/p&gt;
&lt;h3 id="disaster-3-vague-payment-terms"&gt;Disaster #3: Vague payment terms&lt;/h3&gt;
&lt;p&gt;What if you are late on payments, or the vendor demands payment for unfinished work? Clear payment terms help both clients and vendors avoid disputes and financial losses.&lt;/p&gt;
&lt;h3 id="disaster-4-no-intellectual-property-rights"&gt;Disaster #4: No intellectual property rights&lt;/h3&gt;
&lt;p&gt;What if the vendor holds the code ransom and refuses to give you access to it? What if they use the code for other client projects without your permission? A well-written contract will define intellectual property rights so everything is clear. Most software development contracts in the United States and western Europe are work-for-hire type contracts where the company paying for the work owns all the intellectual property.&lt;/p&gt;
&lt;h3 id="disaster-5-no-liability-clause"&gt;Disaster #5: No liability clause&lt;/h3&gt;
&lt;p&gt;What if the vendor delivers faulty code that causes harm to your business or customers? Without a liability clause, the vendor may not be legally responsible for the damages. The software company will want to limit that liability, but often the limits are based on what an insurance company would pay out. Be sure any liability limits are sufficient to cover your business loss risk.&lt;/p&gt;
&lt;h3 id="disaster-6-no-confidentiality-agreement"&gt;Disaster #6: No confidentiality agreement&lt;/h3&gt;
&lt;p&gt;What if the vendor leaks your confidential information to competitors or third parties? A confidentiality agreement can protect your trade secrets and sensitive information. Look for confidentiality agreements that extend beyond the completion of the project and the termination of the contract, usually a year or more.&lt;/p&gt;
&lt;h3 id="disaster-7-no-dispute-resolution-mechanism"&gt;Disaster #7: No dispute resolution mechanism&lt;/h3&gt;
&lt;p&gt;What if a dispute arises between you and the vendor during the project? Dispute resolution mechanisms help the parties resolve the dispute without going to court. You may want to use binding arbitration or some other, less expensive options to sort out disputes.&lt;/p&gt;
&lt;h3 id="disaster-8-no-non-compete-clause"&gt;Disaster #8: No non-compete clause&lt;/h3&gt;
&lt;p&gt;What if the software company hires your developers? What happens if one of your managers casually mentions that one of the software developers should join your company as an employee? A non-compete clause can define what happens in either of these scenarios and can reduce the risk of this happening for everyone.&lt;/p&gt;
&lt;h3 id="disaster-9-no-conflict-of-interest-clause"&gt;Disaster #9: No conflict of interest clause&lt;/h3&gt;
&lt;p&gt;What if the software company starts working a similar project for your competitors? A conflict of interest clause can assure you that the software company isn't currently working on the same problem with another client or with a close competitor in your industry.&lt;/p&gt;
&lt;h3 id="disaster-10-no-support-agreement"&gt;Disaster #10: No support agreement&lt;/h3&gt;
&lt;p&gt;Finally, your software is in production, but you just found a bug. Do you have a support agreement that defines the role of the software development company for something like this? Will production support be needed, or will your company's IT department take that role? Be sure to think through the maintenance phase of your software and how you want to handle that.&lt;/p&gt;
&lt;h3 id="conclusion"&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;A well-drafted software development contract can help both parties achieve their goals and mitigate potential risks. By avoiding the disasters mentioned above, you can ensure that your project is completed smoothly.&lt;/p&gt;
&lt;p&gt;At Volare Software, we have been successfully completing custom software projects since 2009, and we understand the importance of a well-drafted contract. &lt;a href="https://volaresoftware.com/en/contact"&gt;Contact us today&lt;/a&gt; to learn more about our &lt;a href="https://volaresoftware.com/en/services/custom-software-development"&gt;custom software development services&lt;/a&gt;.&lt;/p&gt;
</description>
      <pubDate>Sun, 02 Apr 2023 20:39:06 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/press-releases/volare-software-ranked-one-of-the-top-50-software-development-companies-in-the-united-states</guid>
      <link>https://volaresoftware.com/en/press-releases/volare-software-ranked-one-of-the-top-50-software-development-companies-in-the-united-states</link>
      <title>Volare Software Ranked One of the Top 50 Software Development Companies in the United States</title>
      <description>&lt;p&gt;In November 2019, TechReviewer published its list of the &lt;a href="https://techreviewer.co/top-50-software-development-companies-in-usa/"&gt;top 50 software development companies in the United States&lt;/a&gt; and ranked Volare Software #39. TechReviewer analyzed over 500 software companies in the U.S. to come up with their list of the top 50+.&lt;/p&gt;
&lt;p&gt;Joe Wilson of Volare Software said, &amp;quot;It's nice to have some recognition for our work. We are committed to developing high quality software applications that delight our customers.&amp;quot;&lt;/p&gt;
&lt;h2 id="about-volare-software"&gt;About Volare Software&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://volaresoftware.com/en"&gt;Volare Software&lt;/a&gt; is a custom software development company with its U.S. location in Denver, Colorado and its E.U. location in Hilversum, Netherlands. They build high quality web and mobile apps that run fast and look great on every device. Since 2009, Volare Software has been building solutions for clients like the U.S. Air Force, AT&amp;amp;T, Kaiser Permanente, and Jeffco Public Schools, to name a few. The company specializes in enterprise application development using agile software development processes that speed up delivery, increase quality, promote transparency and accountability, reduce risk, and ensure high customer satisfaction.&lt;/p&gt;
&lt;h2 id="about-techreviewer"&gt;About TechReviewer&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://techreviewer.co/"&gt;TechReviewer&lt;/a&gt; is a trusted analytical hub that carries out studies and compiles lists of top development, design, and marketing companies. Specializing in B2B tech companies, TechReviewer's mission is to help businesses make informed decisions to select vendors who provide high quality services.&lt;/p&gt;
</description>
      <pubDate>Thu, 05 Dec 2019 01:43:56 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/press-releases/volare-software-sponsors-colorado-give-camp</guid>
      <link>https://volaresoftware.com/en/press-releases/volare-software-sponsors-colorado-give-camp</link>
      <title>Volare Software Sponsors Colorado Give Camp</title>
      <description>&lt;h2 id="custom-software-company-supports-coding-for-charity"&gt;Custom software company supports coding for charity.&lt;/h2&gt;
&lt;p&gt;Volare Software is pleased to sponsor Colorado Give Camp in Colorado Springs this weekend, October 26-28, 2012. This is the third time Volare has sponsored the Give Camp.&lt;/p&gt;
&lt;p&gt;GiveCamp is a weekend-long event where technology professionals from designers, developers and database administrators to marketers and web strategists donate their time to provide solutions for non-profit organizations. Since its inception in 2007, the GiveCamp program has provided benefits to over 150 charities, with a value of developer and designer time exceeding $1,000,000 in services.&lt;/p&gt;
&lt;p&gt;&amp;quot;GiveCamp is a free, non-profit event that could not be possible without sponsors,&amp;quot; says Gabriel Villa, Colorado Give Camp Co-Organizer. &amp;quot;When we called for sponsors, Volare Software stepped up to the cause. Not only have they provided food for a group of volunteers developing for non-profits, but also volunteered their President to develop for the weekend as well. Volare is a real leader in development and a leader in their community.&amp;quot;&lt;/p&gt;
&lt;h2 id="about-volare-software"&gt;About Volare Software&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://volaresoftware.com/en"&gt;Volare Software&lt;/a&gt; is a custom software development company with its U.S. location in Denver, Colorado and its E.U. location in Hilversum, Netherlands. They build high quality web and mobile apps that run fast and look great on every device. Since 2009, Volare Software has been building solutions for clients like the U.S. Air Force, AT&amp;amp;T, Kaiser Permanente, and Jeffco Public Schools, to name a few. The company specializes in enterprise application development using agile software development processes that speed up delivery, increase quality, promote transparency and accountability, reduce risk, and ensure high customer satisfaction.&lt;/p&gt;
</description>
      <pubDate>Wed, 24 Oct 2012 04:00:00 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/press-releases/volare-software-celebrates-10-year-anniversary</guid>
      <link>https://volaresoftware.com/en/press-releases/volare-software-celebrates-10-year-anniversary</link>
      <title>Volare Software celebrates 10-year anniversary</title>
      <description>&lt;p&gt;Volare Software, a custom software development company based in Denver, Colorado, celebrated its 10-year anniversary in June.&lt;/p&gt;
&lt;p&gt;Owner and founder Joe Wilson said, &amp;quot;We're grateful to the clients and employees we've worked with over these first 10 years. We've built large, complex solutions for Fortune 50 companies and built minimum viable products for startups. I'm proud of high-quality software we've delivered. We consistently get glowing reviews and high ratings from both our customers and employees, so we must be doing something right. Here's to the next 10 years.&amp;quot;&lt;/p&gt;
&lt;h2 id="about-volare-software"&gt;About Volare Software&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://volaresoftware.com/en"&gt;Volare Software&lt;/a&gt; is a custom software development company with its U.S. location in Denver, Colorado and its E.U. location in Hilversum, Netherlands. They build high quality web and mobile apps that run fast and look great on every device. Since 2009, Volare Software has been building solutions for clients like the U.S. Air Force, AT&amp;amp;T, Kaiser Permanente, and Jeffco Public Schools, to name a few. The company specializes in enterprise application development using agile software development processes that speed up delivery, increase quality, promote transparency and accountability, reduce risk, and ensure high customer satisfaction.&lt;/p&gt;
</description>
      <pubDate>Tue, 02 Jul 2019 01:45:00 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/press-releases/volare-software-among-best-mobile-app-development-companies-in-2019</guid>
      <link>https://volaresoftware.com/en/press-releases/volare-software-among-best-mobile-app-development-companies-in-2019</link>
      <title>Volare Software among best mobile app development companies in 2019</title>
      <description>&lt;p&gt;Volare Software was named one of the &lt;a href="https://www.businessofapps.com/guide/app-development-companies/"&gt;best mobile app development companies&lt;/a&gt; in 2019 by Business of Apps in their just-released guide. The roundup features app development companies from all over the world.&lt;/p&gt;
&lt;p&gt;Volare Software specializes in &lt;a href="https://volaresoftware.com/en/services/web-application-development"&gt;custom web and mobile app development&lt;/a&gt;, using progressive web apps (PWAs) for mobile app development. PWAs are a special type of web application that can be installed on a mobile phone like an app and can interact with that device, like by sending push notifications to the user.&lt;/p&gt;
&lt;p&gt;Joe Wilson, owner of Volare Software, said, &amp;quot;It's nice to be recognized for the work we've been doing for the last 10 years building high quality custom web apps for our clients.&amp;quot;&lt;/p&gt;
&lt;h2 id="about-volare-software"&gt;About Volare Software&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://volaresoftware.com/en"&gt;Volare Software&lt;/a&gt; is a custom software development company with its U.S. location in Denver, Colorado and its E.U. location in Hilversum, Netherlands. They build high quality web and mobile apps that run fast and look great on every device. Since 2009, Volare Software has been building solutions for clients like the U.S. Air Force, AT&amp;amp;T, Kaiser Permanente, and Jeffco Public Schools, to name a few. The company specializes in enterprise application development using agile software development processes that speed up delivery, increase quality, promote transparency and accountability, reduce risk, and ensure high customer satisfaction.&lt;/p&gt;
&lt;h2 id="about-business-of-apps"&gt;About Business of Apps&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.businessofapps.com/"&gt;Business of Apps&lt;/a&gt; provides world class news, analysis, data &amp;amp; marketplaces for app businesses. Founded in 2014, we have become the essential resource for people building, marketing and monetizing apps. Our site reaches a global audience of over 200k app industry professionals a month. We host comprehensive B2B directories and marketplaces covering app ad platforms,  app development, app marketing, influencers and other specialist areas.&lt;/p&gt;
</description>
      <pubDate>Mon, 30 Sep 2019 00:43:53 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/press-releases/volare-software-working-with-u-s-air-force</guid>
      <link>https://volaresoftware.com/en/press-releases/volare-software-working-with-u-s-air-force</link>
      <title>Volare Software working with U.S Air Force</title>
      <description>&lt;p&gt;Volare Software, a custom software development company specializing in web and mobile applications, has been awarded a U.S. Air Force Small Business Innovation Research (SBIR) contract through AFWERX and the Air Force Research Lab (AFRL).&lt;/p&gt;
&lt;p&gt;The project will advance the development of the Human Resources Smart Weapon, a mobile and tablet-optimized custom web app for onboarding airmen with one click. Common fields will be pre-filled for airmen, fields will be validated as they are entered, multiple PDFs will be created from one form submission, and workflows will route submitted PDF forms for approvals and signatures.&lt;/p&gt;
&lt;h2 id="about-volare-software"&gt;About Volare Software&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://volaresoftware.com/en"&gt;Volare Software&lt;/a&gt; is a custom software development company with its U.S. location in Denver, Colorado and its E.U. location in Hilversum, Netherlands. They build high quality web and mobile apps that run fast and look great on every device. Since 2009, Volare Software has been building solutions for clients like the U.S. Air Force, AT&amp;amp;T, Kaiser Permanente, and Jeffco Public Schools, to name a few. The company specializes in enterprise application development using agile software development processes that speed up delivery, increase quality, promote transparency and accountability, reduce risk, and ensure high customer satisfaction.&lt;/p&gt;
&lt;h2 id="about-afwerx"&gt;About AFWERX&lt;/h2&gt;
&lt;p&gt;Established in 2017 by the Secretary of the Air Force, AFWERX is a catalyst for agile Air Force engagement across industry, academia, and non-traditional contributors to create transformative opportunities. The core mission of AFWERX is to improve Air Force capabilities by connecting innovators, simplifying technology transfer and accelerating results. AFWERX has partnered with the AFRL, a scientific research organization operated by the U.S. Air Force Materiel Command, to streamline the SBIR process to speed up the experience, broaden the pool of potential applicants, and decrease bureaucratic overhead.&lt;/p&gt;
</description>
      <pubDate>Mon, 16 Mar 2020 07:56:20 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/press-releases/volare-software-named-best-custom-software-developer-in-denver-by-digital-com</guid>
      <link>https://volaresoftware.com/en/press-releases/volare-software-named-best-custom-software-developer-in-denver-by-digital-com</link>
      <title>Volare Software Named Best Custom Software Developer in Denver by Digital.com</title>
      <description>&lt;p&gt;Digital.com, a leading independent review website for small business online tools, products, and services, has named Volare Software to its list of the best custom software development firms in Denver. The top companies were selected based on core service offerings and customer feedback.&lt;/p&gt;
&lt;p&gt;Volare Software and other service providers were expected to work with businesses across various industries, including e-commerce, legal, or media. Each firm was also required to offer multiple service lines, such as UX/UI design and web and mobile app development. The guide features both large and small companies to meet the diverse needs of businesses that seek faster project turnaround or budget-friendly services.&lt;/p&gt;
&lt;p&gt;Researchers at Digital.com conducted a 40-hour assessment of over 63 companies across the city. To access the complete list of the top 15 custom software developers in Denver, please visit &lt;a href="https://digital.com/custom-software-development-companies/denver/"&gt;https://digital.com/custom-software-development-companies/denver/&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="about-volare-software"&gt;About Volare Software&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://volaresoftware.com/en"&gt;Volare Software&lt;/a&gt; is a custom software development company with its U.S. location in Denver, Colorado and its E.U. location in Hilversum, Netherlands. They build high quality web and mobile apps that run fast and look great on every device. Since 2009, Volare Software has been building solutions for clients like the U.S. Air Force, AT&amp;amp;T, Kaiser Permanente, and Jeffco Public Schools, to name a few. The company specializes in enterprise application development using agile software development processes that speed up delivery, increase quality, promote transparency and accountability, reduce risk, and ensure high customer satisfaction.&lt;/p&gt;
&lt;h2 id="about-digital.com"&gt;About Digital.com&lt;/h2&gt;
&lt;p&gt;Digital.com reviews and compares the best products, services, and software for running or growing a small business website or online shop. The platform collects twitter comments and uses sentiment analysis to score companies and their products. Digital.com was founded in 2015 and formerly known as Review Squirrel. To learn more, visit &lt;a href="https://digital.com/"&gt;https://digital.com/&lt;/a&gt;.&lt;/p&gt;
</description>
      <pubDate>Fri, 22 Jan 2021 05:22:55 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/articles/how-do-you-choose-a-workflow-management-tool</guid>
      <link>https://volaresoftware.com/en/articles/how-do-you-choose-a-workflow-management-tool</link>
      <title>How do you choose a workflow management tool?</title>
      <description>&lt;p&gt;Attention business owners and managers!&lt;/p&gt;
&lt;p&gt;Are you tired of managing multiple spreadsheets, emails, and applications to keep your workflows running smoothly? It's time to streamline your business processes with a workflow management tool.&lt;/p&gt;
&lt;p&gt;But with so many options available, how do you choose the right one for your organization? Here are some factors to consider when making your decision.&lt;/p&gt;
&lt;h3 id="vendor-reputation-and-longevity"&gt;Vendor Reputation and Longevity&lt;/h3&gt;
&lt;p&gt;First and foremost, consider the software company's reputation and longevity in the market. You want to choose a vendor that has a proven track record of providing reliable software solutions. Look for customer reviews, testimonials, and case studies to assess their level of customer satisfaction. Additionally, check the vendor's history in the industry to ensure they have the staying power to support your business in the long run.&lt;/p&gt;
&lt;h3 id="technology-and-scalability"&gt;Technology and Scalability&lt;/h3&gt;
&lt;p&gt;Next, evaluate the technology and scalability of the workflow management tool. You want a tool that can handle your current workflow demands but can also grow with your business. Consider factors such as the platform's architecture, security features, and performance capabilities. A tool that utilizes REST API development and microservices  will offer the flexibility and scalability required to support your evolving business needs.&lt;/p&gt;
&lt;h3 id="how-the-platform-handles-errors-and-hang-ups"&gt;How the Platform Handles Errors and Hang-Ups&lt;/h3&gt;
&lt;p&gt;Even the most robust workflow management tools can encounter errors and hang-ups. When selecting a tool, it's crucial to evaluate how the platform handles these issues. Does the vendor offer reliable customer support? What are their response times? Do they have a documented process for resolving issues? These are all questions to consider when assessing the tool's reliability.&lt;/p&gt;
&lt;h3 id="business-process-automation-and-system-integration"&gt;Business Process Automation and System Integration&lt;/h3&gt;
&lt;p&gt;In addition to workflow management, many organizations also require business process automation and system integration capabilities. Look for a tool that supports these functionalities to streamline your business operations. Workflow development and management can be made more efficient when they are integrated with other key systems such as CRM, ERP, and HRM.&lt;/p&gt;
&lt;p&gt;Selecting the right workflow management tool can significantly improve your team's productivity and streamline your business operations. By considering vendor reputation and longevity, technology and scalability, and how the platform handles errors and hang-ups, you can make an informed decision. With the right tool in hand, you'll be well on your way to achieving your workflow management goals.&lt;/p&gt;
&lt;p&gt;At Volare Software, we specialize in &lt;a href="https://volaresoftware.com/en/services/api-development-and-workflow-management"&gt;API development, business process automation, system integration, workflow development, and workflow management&lt;/a&gt;. &lt;a href="https://volaresoftware.com/en/contact"&gt;Contact us today&lt;/a&gt; to learn more about how we can help you streamline your business processes to help you achieve your goals.&lt;/p&gt;
</description>
      <pubDate>Sun, 02 Apr 2023 18:37:07 Z</pubDate>
    </item>
    <item>
      <guid
        isPermaLink="true">https://volaresoftware.com/en/technical-posts/reusing-kendo-ui-settings-to-make-your-app-s-ui-patterns-consistent</guid>
      <link>https://volaresoftware.com/en/technical-posts/reusing-kendo-ui-settings-to-make-your-app-s-ui-patterns-consistent</link>
      <title>Reusing Kendo UI settings to make your app's UI patterns consistent</title>
      <description>&lt;p&gt;Kendo UI components have LOTS of settings and options. For most web apps, you'll pick a set of options and stick with common UI patterns throughout the app.&lt;/p&gt;
&lt;p&gt;Will your app's grids use paging or infinite scrolling of grid data? If paging, how many records should you show on each page? Which UI style should your app's date pickers use? What format should your app's numeric text boxes use by default - whole number or decimal?&lt;/p&gt;
&lt;p&gt;One technique for sharing common settings across all Kendo UI components within your app is to set up your defaults and wrap with the jQuery extend function.&lt;/p&gt;
&lt;p&gt;Here is a date picker:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;import $ from &amp;quot;jquery&amp;quot;;
import &amp;quot;@progress/kendo-ui/js/kendo.datepicker&amp;quot;;
&lt;p&gt;export function extend(settings) {
const commonSettings = {
componentType: &amp;quot;modern&amp;quot;
};&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;return $.extend(true, {}, commonSettings, settings);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Here is a drop down list where the server returns a &lt;code&gt;text&lt;/code&gt; and a &lt;code&gt;value&lt;/code&gt; field to populate the drop down:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;import $ from &amp;quot;jquery&amp;quot;;
import &amp;quot;@progress/kendo-ui/js/kendo.dropdownlist&amp;quot;;
&lt;p&gt;export function extend(settings) {
const commonSettings = {
dataSource: {
sort: [{ field: &amp;quot;text&amp;quot; }] // Sort by the field called &amp;quot;text&amp;quot; every time
},
dataTextField: &amp;quot;text&amp;quot;, // Assume the text field is always called &amp;quot;text&amp;quot;
dataValueField: &amp;quot;value&amp;quot;,  // Assume the value field is always called &amp;quot;value&amp;quot;
optionLabel: &amp;quot;- Please Select -&amp;quot;,
autoBind: false, // Don't bind the drop down on initialization
valuePrimitive: true // Use primitives for values, like 123, not objects, like { value: 123, text: &amp;quot;Active&amp;quot; }
};&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;return $.extend(true, {}, commonSettings, settings);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Here is a numeric text box for positive whole numbers:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;import $ from &amp;quot;jquery&amp;quot;;
import &amp;quot;@progress/kendo-ui/js/kendo.numerictextbox&amp;quot;;
&lt;p&gt;export function extend(settings) {
const commonSettings = {
min: 0,
step: 1,
decimals: 0,
round: true,
format: &amp;quot;{0:0}&amp;quot;
};&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;return $.extend(true, {}, commonSettings, settings);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Use these default app settings by importing the module, referencing the &lt;code&gt;extend&lt;/code&gt; method exported by that module, then using, adding to, or overriding the UI defaults needed for that date picker, drop down list, or numeric text box:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-js"&gt;import * as datePicker from 'common/datePicker';
import * as dropDownList from 'common/dropDownList';
import * as numericTextBox from 'common/numericTextBox';
&lt;p&gt;$(&amp;quot;#myDatePicker&amp;quot;).kendoDatePicker(datePicker.extend()); // No change to default values
$(&amp;quot;#myDropDown&amp;quot;).kendoDropDownList(dropDownList.extend({
dataSource: &amp;quot;/api/myDropDown&amp;quot; // Add to, rather than change, default values
}));
$(&amp;quot;#myNumericTextBox&amp;quot;).kendoNumericTextBox(numericTextBox.extend({
min: -100 // Override default values
}));
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;This is a good way to have a consistent UI without always copy-pasting key-value pairs across files.&lt;/p&gt;
&lt;p&gt;It also allows you to quickly change how your app looks and works across pages and components with a change to the common Kendo UI defaults.&lt;/p&gt;
</description>
      <pubDate>Sun, 14 Feb 2021 07:44:17 Z</pubDate>
    </item>
  </channel>
</rss>