Category Archives: ASP.NET MVC

Using Tincr with ASP.NET MVC in Windows 7

If you’re not aware, tin.cr is an extension to Chrome that allows you to edit your JavaScript and CSS files in Chrome or using your editor of choice and affecting the source and destination. I personally wanted to use it to make modifications to JavaScript files in VS2012 and have Chrome auto load the file and put it into effect on the page. Thus I save myself numerous page refreshes while I work out kinks. Tincr was developed by Ryan Ackley. Here is the official video for Tincr.

Installing Tincr on Windows 7

  1. Visit the tin.cr website.
  2. Click on the Download Tincr button (Do this through chrome and it will take you to the chrome extension install page).image
  3. Once you have added the extension restart the browser and you should see a Tincr tab in the Developer Tools windowimage<

Setup Tincr

  1. We now need to create a tincr.json file. Open up your favorite editor and post the following code into it (remember to change MyApp to your app name):

    {
        “toFile” : [],
        “fromFile” :
        [
            {
                “from”: “\\\\Scripts\\\\([a-zA-Z]+)\\.js”,
                “to”: “/MyApp/Scripts/$1.js”
            }
        ]
    }

    This tincr.json file tells tincr to look for JavaScript files in the Scripts folder and apply that to the ‘to’ URL. Notice it is using regex so if you have funky named files, you will have to change the regex. In my case, the js file is called ‘common.js’. Once you are done, save the tincr.json file to the root directory. This will be the location of the ASP.NET MVC app directory that is hosted in IIS. In my case, it was C:\dev\tfs\MyApp.

  2. Now you need to setup Tincr. You can mimic the options I set here. For Root Directory, you should point to the location of the ASP.NET MVC app directory that is hosted in IIS. In my case, it was c:\dev\tfs\MyApp. You should see the green ‘Project loaded successfully’ before you begin to use this.image

Using Tincr

  1. We are ready to test this out. Open a browser window and navigate to the URL. In my case it is http://localhost/MyApp. Now go into VS2012 and make a change to a JavaScript file. You should see a message in Dev Tools Console saying “Auto-Reloaded http://localhost/MyApp/Scripts/common.js”. In the case below, I had a console.log(‘asdf’) that I changed to ‘its alive’ in a jquery function that did something on hover. So I just saved the file in VS 2012, moved my mouse over the element and saw the new message. AWESOME!image

Issues with Tincr

If you don’t see the Auto-Reloaded message, it means that your tincr.json file is incorrect OR the extension is not able to figure out your file. This is something that I struggled with for a little bit.

  • The Extension has an issue with windows where query string parameters affixed to the JavaScript URL will make it fail.
  • Another possible issue is if you have an AJAX request that downloads a JavaScript file because it’s a link in the content that was returned. Well, your URL for that JavaScript file may have been altered by JQuery. Use Fiddler and make sure that your URL for the file does not contain any query parameters. It will save you a bunch of time.

Happy Coding.

Advertisement
Tagged , , , , , , , ,

ASP.NET MVC 3 Redirect Query String with id

This tip is mostly because I’ve run into this issue a few times and keep forgetting what I did. The tip concerns an ASP.NET MVC 3 Query string property for redirect using the key ‘id’ when you have a route defined that uses ‘id’ as such:

"{controller}/{action}/{id}"

And you want to redirect to: mywebsite.com/controller/action?id=SomeValue

You also want to keep that id query string because it is a string value that can be a GUID or some string or even an integer. Yes I realize this is bad design but I was working on something out of my control.

The way to accomplish this is to use this:

Redirect(Url.Action("Action", "Controller") + "?id=" + id);

Instead of:

return RedirectToAction(“Action”, “Controller”, new { id = idvalue });

When you use RedirectToAction, it will format your url and remove the querystring which you want to keep. By using Redirect and forging the query string yourself, you get to keep the ‘?id’ part in the URL.

Tagged , , ,

Reporting In ASP.NET MVC 3

This past week I had a need to create a report for an ASP.NET MVC 3 app I was working on. The requirement for the report was to show charts of the data and to provide the original data using databars and indicators and output it to PDF. Not a very complex report at all. But somehow, there were some Goldilocks moments which I present to you now.

Telerik.Reporting – Too Cold

The first thing I tried was the Telerik Reporting solution. It was easy to do but the charting gave me some headaches. The main pain point for me was that it did not support Radius charts and there were no plans to add it. The other problem was with the way the reporting control (server side control) had to be used. Its as if they created it for regular ASP.NET and then hacked it for MVC. See example code here.

image

Aspose.Cells – Too Hot

Then I tried Aspose.Cells to generate an excel sheet and perform the necessary conversion to PDF. This tool was simple to implement but very tedious to get looking just right. I didn’t have a lot of time to spend on the reporting aspect and It felt like I was writing VBA. To be clear, Excel is inherently tedious to work on and Aspose.Cells is the best implementation of Excel I have ever seen. Not even Microsoft has a good implementation that just works (especially in a server environment). The main issues I ran into with Aspose.Cells was that indicators were buggy and would not work properly. The other issue was saving as PDF. It would save fine but the indicators and databars would not print in the PDF report. We use Aspose.Cells in other projects where we need to generate reports that are mostly excel files to allow for data manipulation. It works there and its awesome. However, for this project, it was just not right. 

At this point we started looking at using HTML 5 to generate the charts and just spit the data out on the page. But then we had the issue of taking an HTML page and converting it to a PDF. There are some tools out there that will do it but its not something I wanted to do.

Product Diagram of Aspose.Cells for .NET

Report Builder 3.0 – Just Right

I finally tried Report Builder 3.0. The UI is not the easiest to work with when trying to do styling etc. but it got the job done in record time and the report exported to PDF nicely. It worked. Pleased with this result I was ready to use the LocalReport ability (‘Represents a report that is processed and rendered locally without connecting to a report server’) to render the report in the MVC Controller and stream the PDF file as a result of the Controller method.

The problem is that Microsoft in its infinite wisdom has not enabled that functionality for reports created in Report Builder 3.0.

imageimage

Why in the world would such a useful functionality be crippled on purpose? There must be a workaround!

Stackoveflow was checked but did not help. Changing the report type by modifying the xml does not render it useable. Then I came across this link which stated:

The reports that are created with ReportBuilder 3.0 use the RDL 2010 schema but the ReportViewer in local mode can only process/render reports that use the 2005 or 2008 schema. If you publish the 2010 report to a report server and use the ReportViewer in remote mode you can render the 2010 RDL Report.

So I had to find another way around this issue. I had to use a Report Server to host the report.

Then I could use the WebClient class to request the report via http. The URL I used was:

http://<SERVER_NAME>/ReportServer_SQLEXPRESS?%2fGAP%2f<REPORT_NAME>&rs:Command=Render&rs:Format=PDF&rc:Toolbar=false&rc:Parameters=false&<PARAM_1>=<VALUE&gt;

Notice that there are some things you have to replace in the URL above. Also note that ‘ReportServer_SQLEXPRESS’ is being used. This is because the instance is running off SQL Express and not the full blown SQL 2008 R2 which you should used in production. And that ‘Format=PDF’ will render the report as a PDF.

 

So, to conclude, Report Builder 3.0 was the easiest to use to build the report and generating the PDF from the report was also simple to accomplish. Report Builder supports many different styles of charts and data displays much like Excel. I’m now going to push Report Builder for all our reports considering the ease with which they can be modified and just how easy they are to use. I could put the data on the report and give it to the designer to prettify.

Also, in case you did not know this, Microsoft SQL Server2008 R2 RTM – Express with Advanced Services is a fully functioning SQL SERVER 2008 database with all the trimmings.

  • Same database engine as other versions of SQL Server.
  • Supports 10 GB of storage per database.
  • Backup and restore with ease.
  • Compatible with all editions of SQL Server and SQL Azure.
  • Designed to work with Visual Studio and ASP.NET.
  • Available with a graphical management tool.
  • Offers reporting capabilities, full-text search, and spatial support.
  • Tagged , , , , , , , , , , ,

    ASP.NET MVC Caching Dynamically generated JavaScript

    One of the things you may occasionally have to do while using JavaScript is show dialogs and react to your users inputs. These could be in the form of alert boxes that are built into the language, growls, loading panels or even just a message added to an element. (Side note: The jQuery BlockUI plugin seems very promising).

    The discerning user would realize that a website that targets a global audience has to be able to localize, globalize and internationalize to their language and a good starting place is to look at Scott Hanselman’s post on this very topic.

    Globalization, Internationalization and Localization in ASP.NET MVC 3, JavaScript and jQuery – Part 1

    One hacky way to get localized strings in JavaScript when they are in separate files is to have a localized file with all the localized text in it. Then based on the users language preference, load up the appropriate file and use the strings from there. But what if the strings come from a database and you need to generate this at runtime to be able to handle change without deployment again. Well here is how you can do it.

    Read the article on JavaScriptView by elegantcode for more details. However, to summarize here are their steps:

    1. Create a controller method that return the view as a JavaScriptFileResult preferably in your home controller.
    2. Create a view that contains the localized strings in an array. I used a helper method to get the contents from the database dynamically. You may wish to add this to your home controllers view folder as well.
    3. Add a script block in the shared layout’s header to the URL for the JavaScript file.

    All well and good. The file will now come down with the rest of the content as a JavaScript file and you can use the array of localized strings in your other JavaScript code.

    BUT! The one problem you may notice is that the JavaScript source file is retrieved every time a request is made to the server. Thus you will need to cache it. To do so, we just need to add the OutputCacheAttribute onto the controller method that returns the JavaScript file.

    [OutputCache(Location = System.Web.UI.OutputCacheLocation.ServerAndClient, Duration = 900, VaryByParam = "none")]

    The only problem here is that the VaryByParam is set to none. That’s because we don’t have any parameters being passed into the method. This is a problem because two different requests can come in for varying locales and now the second one may get the cached value of the first one. Therefore, we need to pass in the locale as a parameter and then VaryByParam on that field. This will ensure that every locale has the file cached and changes made can go out without requiring a deployment of files to the server.

    JsConstants

    The script block in the _Layouts.cshtml file.

    <script src="@Url.Content("~/Home/JsConstants?lcid=" + System.Threading.Thread.CurrentThread.CurrentCulture.LCID)" type="text/javascript"></script>

    But of course, who wants to keep sending these Id’s over all the time for all our script files. So, the easiest way to do this would be to create an identifier that can be used to check language automatically. And then we can write, “lang” in the VaryByParam attribute option and remove the lcid parameter from JsConstants.

    [OutputCache(Location = System.Web.UI.OutputCacheLocation.ServerAndClient, Duration = 900, VaryByParam = "lang")]

    The code to make this work is as follows. [Sorry but I’m not quite sure where I found this gem from]

    public override string GetVaryByCustomString(HttpContext context, string value)
    {
    	if (value.Equals("lang"))
    	{
    		return Thread.CurrentThread.CurrentUICulture.Name;
    	}
    	return base.GetVaryByCustomString(context,value);
    }

    fidllerJsConstants

    As you can see from the image above, the first request for the JsConstants file containing the JavaScript returned 918bytes of data. Whereas, the subsequent call returned 0 bytes. The raw message returned reads as follows:

    HTTP/1.1 304 Not Modified
    Cache-Control: private, max-age=863
    Expires: Sat, 03 Sep 2011 22:57:26 GMT
    Last-Modified: Sat, 03 Sep 2011 22:42:26 GMT
    Vary: *
    Server: Microsoft-IIS/7.5
    X-Powered-By: ASP.NET
    Date: Sat, 03 Sep 2011 22:43:03 GMT

    This indicates that we are able to cache the contents of the JavaScript file that was being generated dynamically and it will be refreshed after the Duration we set (900).

    Happy Coding.

    kick it on DotNetKicks.com