ITmeze - IT world server like cyprus meze

System.Linq.Dynamic and Spatial Searches

Itmeze

On my current project i am doing a LOT of dynamic searches. 

Lot's of them go through System.Linq.Dynamic library - it is really just one .cs file. As library has lost somewhere on internet, the only place i have managed to find it is on one of github's repository :

I had to run some spatial searches over exposed DbGeography type - those are directly on database - via Entity Framework

public class Town { public string Name { get; set; } 
public DbGeography Location { get; set; } } 

The problem is, dynamic queries (based on string) simply won't work on that.

_db.Towns.Where("Location.Distance(@0) < 20000", someLocation).ToList() 

Such query will bruttaly fail with "Methods on type 'DbGeography' are not accessible". Going through the code shows us:

if (!IsPredefinedType(method.DeclaringType))

is throwing exception. Solution for that is simple and requires to add DbGeography to 'predefinedTypes' variable. Now, following test will pass:

[Fact]
public void DistanceSearchShouldWork()
{
	var warsaw = new Town() { Name = "Warsaw", Location = DbGeography.FromText("POINT(52.229718 21.012214)") };
	var lodz = new Town() { Name = "Lodz", Location = DbGeography.FromText("POINT(51.759304 19.455969)") };
	var berlin = new Town() { Name = "Berlin", Location = DbGeography.FromText("POINT(52.523206 13.410836)") };
	var towns = new List
			    {
				    warsaw,
				    lodz,
				    berlin
			    }.AsQueryable();

	var distance = warsaw.Location.Distance(lodz.Location);

	Assert.Equal(1, towns.Where("Location.Distance(@0) < 20000", warsaw.Location).Count());
	Assert.Equal(2, towns.Where("Location.Distance(@0) < 200000", warsaw.Location).Count());
	Assert.Equal(3, towns.Where("Location.Distance(@0) < 2000000", warsaw.Location).Count());
}

In case you would like to grap solution directly - you can do that on fork here.

 

Tags: [linq] [DbGeography] [spatial]

This blog is powered by NancyFX!

Itmeze

This blog is powered by NancyFX MongoDB - source code can be found on github repo.

I have to add that it was a pleasure to work with both although i remain sceptical if i would use mongodb in future. It's lack of transactions and no async c# api really scares me. But anyway, If you are interested how both Nancyfx and MongoDB can work under .net check this one out.

Thats all really!

Tags: [nancyfx] [mongodb]

Redirect to new domain after rebranding with IIS Url Rewrite Module

Itmeze

Client has a bunch of domains and and websites. Because They have decided to change company's name recently I was asked to proceed with chanage of domain names as well. After few weeks of constantly informing visitors about planned changed We decided that it is a good time to abandon old domains and redirect visitors to new ones. In order to "be okay" with google (their page ranks, indexed pages and so on) we make those redirects permanent (301 Moved Permanently as a response status code). As all of the websites are hosted on IIS 7 I have decided to use URL Rewrite Module for the job. First of all - make sure You have Url rewrite module installed on Your server machine. Secondly, You need to update web.config file to something like the one that (assuming old-name):
  <system.webServer>
        ......
        <rewrite>
            <rules>
                <clear />
                <rule name="rebranding" enabled="false" stopProcessing="true">
                    <match url="(.*)" />
                    <conditions logicalGrouping="MatchAll" trackAllCaptures="true">
                        <add input="{HTTP_HOST}" pattern="(.*)old-name(.*)" />
                    </conditions>
                    <action type="Redirect" url="http://{C:1}new-name{C:2}/{ToLower:{R:1}}" appendQueryString="true" />
                </rule>                
            </rules>
        </rewrite>
  </system.webServer>
You can do that in IIS manager as well. Some explanation here:
  • match url="(.*)" - matches all request
  • trackAllCaptures="true" - will enable to use captured grups in our redirect url
  • (.*)old-name(.*) - matches each HTTP_HOST that has 'old-name' within, like: ar.old-name.com or www.old-name.ru
  • http://{C:1}new-name{C:2}/{ToLower:{R:1}} - redirected url, R:1 stands for matches from and C:1 and C:2 matches those from conditions, ToLower changes text to lower case letters
  • appendQueryString="true" - will append query string to newly generated url
Have fun

Tags: [web development]

Javascript Encode on server side - Medium Trust Environment

Itmeze

It happens from time to time I have to get rid of those funky apostrophe in my server/javascript code. To do such kind of things I was using Microsoft Anti-Cross Site Scripting Library. By simply calling:

public static string JavaSriptEncode(this string text) {
  return Microsoft.Security.Application.AntiXss.JavaScriptEncode(text, false);
}

Unfortunately, It doesn't work in Medium trust environment - btw, why the hell i get stingy clients. After some time digging all over internet and trying to write it by myself I accidentally found a thing that I never believed to be there. Well, ladies and gentleman, since .NET 4.0 HttpUtility has a new static function called... JavaScriptStringEncode

public static string JavaSriptEncode(this string text) {
  return HttpUtility.JavaScriptStringEncode(text);
}

Uff!...

Tags: [encoding] [javascript] [web development]

Deploying BlackBerry OTA App (.jad, .cod files) or Android(.apk) on IIS

Itmeze

Hope some other people will find this post helpful. We had an issue today at work with providing BlackBerry application over the web site that was hosted on IIS 7.5. Although Screen shots that You 'll find below were made for this specific server procedure might look pretty much the same when it comes to older versions of IIS. By default (for IIS) .jad and .cod files are not delivered over IIS. The problem and it's solution lies within MIME types registered on the server. To fix that someone has to add MIME types with valid extension and type:
  1. Go to Internet Information Services Manager  (I usually do that by right clicking on Computer, choosing Manage and expanding Roles/WebServer/IIS, or simply search for IIS in Start -> Search for Programs box
  2. Click on Your server name, Switch to Features View if You are in Content View
  3. You will find MIME Types icon. Double click it.
  4. On the Action Pane - usually on the right side, select Add..
  5. Fill window with provided information (This registers .jad extension).
  6. Do the same for .cod files - You may have to delete or edit existing .cod settings as I found those already existing with some image type.
  7. Restart IIS. (iisreset in command prompt)
  You can follow above steps to set up Android Package File (APK). To do that add MIME type like one below:   Hope this will help someone.

Tags: [blackberry] [iis] [mobile] [web development]

Handler "Elmah" has a bad module "ManagedPipelineHandler" in its module list

Itmeze

Elmah - awesome library for asp.net that enable to log exceptions (as well as those that end up with Yellow screen of death). It comes with a great module and a handler used to view error logs. It really helps a lot. I used that in literally every web project I have made. Yesterday, I was installing new project on fresh Windows Server 2008 R2. I ended up with an error: Handler "Elmah" has a bad module "ManagedPipelineHandler" in its module list. After hour of goggling I couldn't find a solution that would solve my problem (reinstalling asp.net, changing ISAPI restrictions). Nothing helped. Then I have found out that problem lies in IIS7 configuration part in my web.config.
<system.webServer>
  <modules>
    <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah"/>
  </modules>
  <handlers>
    <add name="Elmah" path="elmah.axd" verb="POST,GET,HEAD" type="Elmah.ErrorLogPageFactory, Elmah" preCondition="integratedMode"   />
  </handlers>
</system.webServer>
My set up was done based on dotnetslackers article, and I simply copied their pre IIS7 configuration to system.webserver part. The part that I was missing was preCondition="integratedMode" attribute for a handler. Hope that helps someone

Tags: [web development]

Validate max file size during upload in asp.net mvc

Itmeze

Just a quick sketch. Validation is done as an Attribute (DataAnotations way).
 public class FileAttribute : ValidationAttribute {

        public int MaxContentLength = int.MaxValue;
        public string[] AllowedFileExtensions;
        public string[] AllowedContentTypes;

        public override bool IsValid(object value) {

            var file = value as HttpPostedFileBase;

            //this should be handled by [Required]
            if (file == null)
                return true;

            if (file.ContentLength > MaxContentLength) {
                ErrorMessage = "File is too large, maximum allowed is: {0} KB".FormatWith(MaxContentLength / 1024);
                return false;
            }

            if (AllowedFileExtensions != null) {
                if (!AllowedFileExtensions.Contains(file.FileName.Substring(file.FileName.LastIndexOf('.')))) {
                    ErrorMessage = "Please upload file of type: " + string.Join(", ", AllowedFileExtensions);
                    return false;
                }
            }

            if (AllowedContentTypes != null) {
                if (!AllowedContentTypes.Contains(file.ContentType)) {
                    ErrorMessage = "Please upload file of type: " + string.Join(", ", AllowedContentTypes);
                    return false;
                }
            }

            return true;
        }
    }
And now decorators (within viewmodel).
[Display(Name = "Upload Proof of Address")]
[File(AllowedFileExtensions = new string[] { ".jpg", ".gif", ".tiff", ".png", ".pdf" }, MaxContentLength = 1024 * 1024 * 8, ErrorMessage = "Invalid File")]
public HttpPostedFileBase AddressProof { get; set; }
Hope that helps someone.

Tags: [asp.net-mvc] [data-annotations] [validation] [web development]

Noscript information with a link to google search

Itmeze

Some web apps just do not work without JavaScript. Just doesn't. Stop. We are usually asked to provide users with nice looking information that this site is best viewable with JavaScript turned on. Plus there is a need to explain them how to turn JS in their browsers. Smart and yet incredibly simple would be to direct them to google search result for a phrase like 'How do I enable JavaScript in my browser?'
<noscript>
  <a class="enable-js" href="http://www.google.com/search?q=How+do+I+enable+JavaScript+in+my+browser">
    XXX application requires JavaScript to be enabled in browser
  </a>
</noscript>
This one I use for most of web apps I have made so far. Smart, simple and always accurate. In fact that would be event nicer to add browser with version ...

Tags: [javascript] [noscript] [web development]

jQuery style Ui dialog over flash banners

Itmeze

I was doing some extra job for one of the clients, some changes on the web site full of blinking flash banners. Idea was to get users' attention even more by displaying some floating windows... lovely ... Obvious choice would be jQuery modal dialog... So I made it ... Unfortunately it has shown up that some of the flash banners remain 'over' the dialog, and some of them don't. After digging into that I figured out that the reason behind that is one of flash parameters: "wmode" (thanks God this is not another inner flash issue). From Adome Knowledge base:
wmode - Possible values: window, opaque, transparent. Sets the Window Mode property of the Flash movie for transparency, layering, and positioning in the browser.
  • window - movie plays in its own rectangular window on a web page.
  • opaque - the movie hides everything on the page behind it.
  • transparent - the background of the HTML page shows through all transparent portions of the movie. This option can slow animation performance.
So, to fix that You need to set this parameter to 'transparent'. Fortunately all flash objects were placed with swfobject scripts. Sample code to fix that issue may look like may look like (video from YouTube):
    $(document).ready(function () {
        // The video to load.
        var videoID = "xxx";
        // Lets Flash from another domain call JavaScript
        var params = { allowScriptAccess: "always", wmode: "transparent" };
        // The element id of the Flash embed
        var atts = { id: "ytPlayer" };
        // All of the magic handled by SWFObject 
        swfobject.embedSWF("http://www.youtube.com/v/" + videoID + "&#038;enablejsapi=1&#038;playerapiid=player1",
                       "videoDiv", "420", "258", "8", null, null, params, atts);
    });

Hope this saves some of Your precious time...

Tags: [dialog] [flash] [jquery] [web development]

Next -->

Copyright 2013 © ITmeze