Nested If and For loops in views woes

I want to start this off by saying that I generally don't like using C# code in my views, I feel it is bad practice.  I would much rather the models be simple enough to be displayed without the use of code on the front end.  I also feel that display views for complex nested types should be used as partial views, this is the correct way to do it in my opinion.  However, situations arise where you can't refactor all your models to work, or it isn't worth it.  For these cases, it is often better to simply break down and put the if and for blocks in the view.  This does have some syntax challenges I will talk through.  
The first is the @ symbol.  You are probably familiar with using it before all calls to the Html Helper and such.  Now if we have an if block, that if block must be started with an @ and then it will have { curleys } around stuff that occurs on that condition.  This works well enough if you just have html in there.  But lets say you have 2 nested if blocks, well you have to be careful now.  
Basically, after you have an @, it is code until it sees what it thinks is static text, usually an html tag.  Sometimes it isn't so easy for the parser to figure this out.  So say you have 2 if blocks in a row, well it is going to be upset.  This is where the @: syntax and the <text></text> syntax come into play.  Basically, in complex scenarios like this (nested) we need to specify everything that is text so it can know the rest is code and parse correctly.  Here is what my double if looks like in a for loop for reference using the above syntax.
<div class="fieldgrid" style="float:left;">
            <table class=" table-bordered" style="max-width:200px;word-wrap: break-word;">
                @{int i = 20; }
                @foreach (var prop in Model.GetType().GetProperties().Where(c => !c.PropertyType.ToString().Contains("Collections.Generic")).OrderBy(c => c.Name))
                {
                    if (i == 0)
                    {
                        i = 20;
                        @:</table></div>
                    @:<div class="fieldgrid" style="float:left;"><table class=" table-bordered" style="max-width:200px;word-wrap: break-word;">
                }
                    <text>
                        <tr>
                            <td class="display-label">
                                @prop.Name
                            </td>
                            <td>
                                @prop.GetValue(Model, null)
                            </td>
                        </tr>
                    </text>
                    i--;
                }
            </table>
        </div>
So this code I will talk about in another post, but for the scope of this post, it creates many tables from a set of data.  It does a simple for loop of the data to do so, but breaks the table into 20 record chunks.  So a counter is created and an if block put in place to see if the counter hits 0, it resets the counter and ends and starts a new table.  The static text is all identified either with a @: before it, or surrounded in <text></text> tags.  I would have only used <text> tags, however, wrapping just closing tags with it doesn't go well as precompiler xml is hard to differentiate from post xml I guess.  But this works and is how to do such things.  
Remember, just because you can, doesn't mean you should.

Downloading a CSV file from MVC Controller

So I had a request from a user on an app to download a CSV file from my MVC web site.  I had previously showed how to upload a csv to MVC, so this shouldn't be hard.  The first thing you need to do is create a function on your controller to put the file together and return it.  Here is a really simple example.  
    public FileContentResult DownloadCSV()
    {
        string csv = "Charlie, Chaplin, Chuckles";
        return File(new System.Text.UTF8Encoding().GetBytes(csv), "text/csv", "Report123.csv");
    }
Since CSV is just a text file, I put together a really simple one there to get the idea across.  All that is special about this function is that it returns a FileContentResult vs ActionResult (though that probably would be fine) and return a File.  That was reason.  Now the link http://site/App/controller/DownloadCSV should return a file.  You just need to create a link in your front end and done.  
If you want to do all of this from a JQuery call, it would look something like this.

$.ajax({
    type: 'POST',
    url: '/Controller/DownloadCSV', 
    data: '{  }',
    contentType: 'application/json; charset=utf-8',
    dataType: 'json',
    success: function (returnValue) {
        window.location = '/Reports/Download?file=' + returnValue;
    }
});

MVC IP restricting at controller level.

I have recently exposed a REST API service for URL shorteneing on the public web, but wanted to restrict functions of it to only myself.  To do this, using google, I was able to create a solution by creating a custom ActionFilterAttribute class implementation that I can dress my controllers I want to restrict access on.  So the first thing I do when designing is determining what I want my usage to look like.  I wanted my class decoration to look like this.
<add value="127.0.0.1,192.168.*.*,108.22.33.*" key="AllowedIPAddresses" />
Then I want my config file to look like this.
[AuthorizeIPAddress]
        public ActionResult Index()
        {
            var ctx = new ShortenerDBDataContext();
            return View(from a in ctx.SomeFuncs select a);
        }
To do this, my custom class (found online) ended up looking like this.
using System;
using System.Web;
using System.Web.Mvc;
using System.Configuration;

namespace PPOVR_Shortener.Filters
{
    /// <summary> 
    /// Only allows authorized IP addresses access. 
    /// </summary> 
    public class AuthorizeIPAddressAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            //Get users IP Address 
            string ipAddress = HttpContext.Current.Request.UserHostAddress;

            if (!IsIpAddressValid(ipAddress.Trim()))
            {
                //Send back a HTTP Status code of 403 Forbidden  
                filterContext.Result = new HttpStatusCodeResult(403);
            }

            base.OnActionExecuting(filterContext);
        }

        /// <summary> 
        /// Compares an IP address to list of valid IP addresses attempting to 
        /// find a match 
        /// </summary> 
        /// <param name="ipAddress">String representation of a valid IP Address</param> 
        /// <returns></returns> 
        public static bool IsIpAddressValid(string ipAddress)
        {
            //Split the users IP address into it's 4 octets (Assumes IPv4) 
            string[] incomingOctets = ipAddress.Trim().Split(new char[] { '.' });

            //Get the valid IP addresses from the web.config 
            string addresses =
              Convert.ToString(ConfigurationManager.AppSettings["AllowedIPAddresses"]);

            //Store each valid IP address in a string array 
            string[] validIpAddresses = addresses.Trim().Split(new char[] { ',' });

            //Iterate through each valid IP address 
            foreach (var validIpAddress in validIpAddresses)
            {
                //Return true if valid IP address matches the users 
                if (validIpAddress.Trim() == ipAddress)
                {
                    return true;
                }

                //Split the valid IP address into it's 4 octets 
                string[] validOctets = validIpAddress.Trim().Split(new char[] { '.' });

                bool matches = true;

                //Iterate through each octet 
                for (int index = 0; index < validOctets.Length; index++)
                {
                    //Skip if octet is an asterisk indicating an entire 
                    //subnet range is valid 
                    if (validOctets[index] != "*")
                    {
                        if (validOctets[index] != incomingOctets[index])
                        {
                            matches = false;
                            break; //Break out of loop 
                        }
                    }
                }

                if (matches)
                {
                    return true;
                }
            }

            //Found no matches 
            return false;
        }
    }
}
Works well, even allows ranges, enjoy.

MVC Routing based on id only

So I had a situation where I wanted to route to a controller based on the id only.  What this means is I want a real short url, like http://www.ghij.org/768345 and have it redirect to a controller with the 768345 being the id to pass to that controller.  The way to do this is to add a rout path to my RouteConfig.cs file.  What I did was this.
routes.MapRoute(
                name: "Push",
                url: "{id}",
                defaults: new { controller = "LongURL", action = "Index", id = UrlParameter.Optional }
            );
What it does is creates a new route path (I put mine first in the set) that simply looks for 1 parameter and assigns it to ID, then defaults the other items (controller and action) and sends you on your way.

C# calling REST API's using complext types (objects)

So we have been rolling out Web API's to expose functions to other systems.  This is great, but it isn't like SOAP where you have a WSDL, import it and you can code against it.  You have to do more work than that.  We don't want to be completely blind and just pass xml / json around and let each side figure out what the type looks like, so we should compile our main types to classes and share them between assemblies.  Then when we request or post a product, we can easily just have it as its native type.  Here is how.

If I wanted to post a product to a function, I would do it like this.

var client = new RestClient(Config.GetString("QASpecWebClient", true));
                var request = new RestRequest(Config.GetString("QASpecWebFunction", true), Method.POST);
                request.RequestFormat = DataFormat.Json;
                request.AddBody(product);
                var resp = client.Execute(request);

Notice how we just AddBody the product.  It is a complex type that the service in question uses as well.  Luckily RestSharp takes care of converting it to json to get it there.

If we want to request a product from a function, I would do it like this.

var client = new RestClient("http://localhost:62991/");
var request = new RestRequest("api/productapi/"+id.ToString());
request.RequestFormat = DataFormat.Json;
var resp = client.Execute(request);
var returner = JsonConvert.DeserializeObject<IProduct>(resp.Content);
return returner;

Notice how we just do the same client request setup, don't add a body, and then use the deserialze function template to our type and boom, we have a complex type with no messy parsing.  Enjoy!

 

Oh, don't forget to include Newtonsoft.Json and RestSharp!