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.

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.

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! 

Serialize Object Data to an XML File C#

Saving and loading objects to and from files is one of the first things they teach you when learning to program.  The text file was the original format of choice and it is still used widely today.  Xml was created to be easy to read like text and yet structured to allow relationships to exist in storage.  Occasionally today you still run across the need to store data to something other than a database.  But writing out files from classes means writing functions on your object to read and write it from some sort of file format you must establish. 
While this isn't necessarily hard, it is time consuming and a point of failure and complexity.  I had written a few code generators that could generate a simple reader and writer to xml files given any class, but that was also cumbersome.  What I found out is you can do this inherently with the System.XML library using the XmlSerializer which is very easy to use and saves a lot of time.  You just need to dress your classes.
Here is an example, I have relatively simple set of objects that represent a set of customer statements.
[Serializable]
        public class Statement
        {
            public string AccountNumber { get; set; }
            public int Sort { get; set; }
            public string SubSort { get; set; }
            public decimal SackNumber { get; set; }
            public decimal PackNumber { get; set; }
            public decimal Key { get; set; }
            public string RateLevel { get; set; }
            public string Endorsement { get; set; }
            public string Payload { get; set; }
            public string Stuffer { get; set; }
            public string CustomerNumber { get; set; }
            public string Company { get; set; }
            public string Plan { get; set; }
            public decimal Balance { get; set; }
            public decimal MinimumPayment { get; set; }
            public decimal PastDueAmt { get; set; }
            public string Name { get; set; }
            public string Address1 { get; set; }
            public string Address2 { get; set; }
            public string Address3 { get; set; }
            public string City { get; set; }
            public string State { get; set; }
            public string Carrier { get; set; }
            public string Zip { get; set; }
            public DateTime FinalDate { get; set; }
            public string Prefix { get; set; }
            public string Zip2 { get; set; }
            public bool PastDue { get; set; }
            [XmlArray("MessageList"), XmlArrayItem(typeof(Message), ElementName = "Message")]
            public List<Message> Messages { get; set; }
            [XmlArray("DetailList"), XmlArrayItem(typeof(Detail), ElementName = "Detail")]
            public List<Detail> Details { get; set; }
            public Statement()
            {
                Details = new List<Detail>();
                Messages = new List<Message>();
            }
        }
        [Serializable]
        public class Message
        {
            public Message()
            { }
            public decimal LateCharge { get; set; }
            public decimal MinPayMonths { get; set; }
            public decimal MinPayTotal { get; set; }
            public decimal ThreeYearPayment { get; set; }
            public decimal ThreeYearPayTotal { get; set; }
            public decimal YTDFees { get; set; }
            public decimal TYDInterest { get; set; }
            public string MessageString { get; set; }
            public string Last4 { get; set; }
            public decimal EndRate { get; set; }
            public decimal EndFinCharge { get; set; }
            public decimal EndAmtFinanced { get; set; }
            public decimal EndTotalPayout { get; set; }
        }
        [Serializable]
        public class Detail
        {
            public Detail() { }
            public DateTime TransactionDate { get; set; }
            public string TransNumber { get; set; }
            public string TransDescription { get; set; }
            public decimal TransAmount { get; set; }
            public char TransDisputeFlag{ get; set; }
            public string SubPlan { get; set; }

            public string Filler { get; set; }
        }
As you can see I dressed child objects with a xmlroot and serializable.  I also had to make sure all types used in classes and the classes themselves have default constructors that are public and take in to parameters.  And then simply call the save method and boom, you have saved your object to an xml file and can read it with the load method later.  Enjoy!

Enabling CORS on a MVC 5 Application

I recently created a application using Apache Cordova which uses HTML and Javascript / JQuery to create apps that can be built and deployed to many platforms like Android, IOS, and Windows Phone to name a few.  In doing, this, I adopted the model of selecting data from a REST API I exposed via MVC Web API 2.0 from my webserver.  The problem is, you need CORS exposed on the webserver or the Javascript won't except the response from the request for data to prevent cross site scripting.  I could have set up a proxy, but instead I enabled CORS and it wasn't that hard.  It appears there are several ways to do this including many new libraries like System.Web.Html.Cors and System.Web.Cors that are in the nightly builds from Microsoft but not in the deployed visual studios dev environment yet.  I used nuGet to get a few of them and din't have the best luck as my version of System.Web.Http got confused.  
After some more looking I found you could simply put this in your web.config under system.webserver, and it solved the problem, though less gracefully than in code.

<httpProtocol>
  <customHeaders>
	<add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" />
  </customHeaders>
</httpProtocol>
That was it. On my web host, I had to grant full access in the System.Configuration tag as well.