Using FullCalendar in an MVC ASP.Net Web Application

Recently I was creating a site that needed an interactive calendar for events.  A quick google search turned up a nice Javascript based (Jquery) calendar I could use for free.  The product is Full Calendar .  I wanted to write a quick article about what is required to get it up and running in a site.  

The first thing to do is download the latest version from their site.  I downloaded 2.6.1 at the time.  Once downloaded, extract it to a folder on your machine.  Now I am using visual studios to make an MVC app.  So what I did was create a directory in my solution called calendar and copied the following elements into the directory.  
  • fullcalendar.min.css
  • fullcalendar.min.js
  • fullcalendar.print.css (if you want print rendering)
  • jquery-ui.custom.min.js (if you don't have it included in project elsewhere)
  • moment.min.js (not sure if needed)
I already was using Jquery in my project, so this was sufficient to get me rolling.

Now I included links in my header on my page.

    @Styles.Render("~/calendar/fullcalendar.min.css")
    @Scripts.Render("~/calendar/moment.min.js")
    @Scripts.Render("~/calendar/fullcalendar.min.js")

The next thing I did was add a div tag that will be the calendar, and a short script to get it rolling.
<div id="calendar" style="width:95%"></div>
                    <script type="text/javascript">
                        $(document).ready(function() {
                            $('#calendar').fullCalendar({
                                header: {
                                    left: 'prev,next today',
                                    center: 'title',
                                    right: 'month,agendaWeek,agendaDay'
                                },
                                editable: false,
                                eventLimit: true, // allow "more" link when too many events
                                events: @(Html.Raw(Model.Body))
                            });
	                    });
                    </script>
Now that I have that in place, the calendar should render.

You will now note that it didn't quite work because in the javascript function, I referenced Model.Body which you probably didn't have.  So this is how I add events to the calendar.  How my app works, is I store the events in a json file on my server to be rendered out.  When the Model for the page loads, it has that JSON stored in a string on the Model called Body, so the HTML.Raw renders it out to the javascript and it works slick.

The JSON is simple, it only has 3 attributes per Event in an array, so looks like the following.

[
  {
    "title": "All Day Event",
    "start": "2016-01-01"
  },
  {
    "title": "Long Event",
    "start": "2016-01-07",
    "end": "2016-01-10"
  }
]
What I did was create a class that represents this.

[Serializable]
    public class Event
    {
        public string title { get; set; }
        public DateTime start { get; set; }
        public DateTime end { get; set; }
    }
Then I leverage the Newtonsoft Serializer to convert between a List<Event> and the json quickly for saving and for editing using models.  Perhaps I will have an article on the add event function another day.  For now, a quick example of that read to and from JSON to end the day.

var list = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Models.Event>>(content.Body);
            if (list == null)
                list = new List<Models.Event>();
            list.Add(new Models.Event() { title=Title, end = Convert.ToDateTime(EndDate), start = Convert.ToDateTime(StartDate) });
            content.Body = Newtonsoft.Json.JsonConvert.SerializeObject(list);

C# MVC Windows Authentication And API Without

So I routinely use windows authentication on internal applications at my current job.  Lately we have been using the WebAPI framework with MVC to expose more REST services from these apps as well.  We always want to lock down screens to users that should have access, however web API's we are less restrictive with, though mixing the two practices is a bit strange in the same application.

After some head scratching, this is how its done.  So first, to limit the app to only authenticated users, we use this in the web.config under system.web

<authentication mode="Windows" />
    <authorization>
      <deny users="?" />
    </authorization>

Its rather simple, it just requires all users be authenticated through windows.  We implemented a version of the entity framework to tie these to a custom role database for users on applications to lock down individual controller functions, but that's code for a different post.  This post will look at how to expose the API as unauthenticated.  How we do this is to add this to the web.config (as well as the above), this time under the configuration tag.

  <location path="api">
    <system.web>
      <customErrors mode="RemoteOnly"/>
      <authorization>
        <!-- All anonymous users access to the virtual path api -->
        <allow users="?" />
      </authorization>
    </system.web>
    <!-- Need to include the security overrides else it will inherit from the root of the application -->
    <system.webServer>
      <validation validateIntegratedModeConfiguration="false" />
      <handlers>
        <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
        <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
        <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
        <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
        <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
        <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
      </handlers>
    </system.webServer>
  </location>

So in short, this adds a second set of configs for things under the path API (which you need to make sure your api functions are under that url) to allow users ?.  I also needed to add system.webserver info that I copied from the existing one so all the plugins I have would work as well.  That should do it, you should have anonymous access to API now.


C# MVC Post back Child Elements In View

More times than not, you will have objects with child objects in your view.  Weather this is an order with lines or a Product with sources, this is the reality.  Most online tutorials of MVC don't cover these well, but I wanted to touch on the two ways to cover these.  

The first way is in my opinion the cleanest and most reusable.  You simple create a view for the child object itself.  Many times you create a Display version and an Edit version then put int he Shared/DisplayTemplates or Shared/EditTemplates directory respectively.  After that, in your parent object's view, you put something like @Html.DisplayFor(model=>Model.ChildObjs) which will render each with the new view in display templates repeating, design your view html accordingly.

The second way is the inline way.  This isn't as pretty, but works.  You simply put a for loop in place to loop through the children elements and use Html.EditorFor(model=>Model.Childs[i].Field to edit fields.  Make sure to put a hidden in for other fields for each child that need to be posted back to make your safe happen.  Also, foreach isn't going to cut it, you need a For loop with an iterator or it won't be able to reflect the fields back.

Hope this helps!

Generating Invoices Online

I do some commission work on the side and have found the best way for me to send out invoices is to use https://invoice-generator.com/ .   It is straight forward, easy to use, and free with good looking invoices.  Check it out if you need to bill someone, it looks rather professional. 

MVC View that will display attributes of any Model

So I spend a lot of time creating simple internal apps that aren't pretty, but are great for giving people (me) access to data without query analyzer, very simple apps in short.  I hate it when I have to update these simple apps though, and if you create enough of them, objects in the system are always changing and you end up wasting a lot of time updating views to show the new data.  
To help this, I devised a bit of code to put in your view that will render a model for ever, updating even if the object changes.  Lets check it out.
<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 whats going on isn't pretty, but basically I am reflecting my model, and the looping through its properties and displaying them in alphabetical order.  I also try to weed out the complex types in the where clause as you can see.  This did get a bit more complex because I wanted to split them into smaller tables so they don't get too huge, that's where the if block comes in.  But really, a rather simple, and powerful way to display a model dynamically.