Intro
I've been a desktop dev for a long time now, and have never really had to monkey with web development until very recently. I have a need to do some custom integration with Survey Monkey's Api and as a "Hello World" I came up with this simple ASP.Net MVC app that queries Survey Monkey for a list of my surveys and displays some real basic info about them. (Nothing I couldn't get from just going to their site, but hey!, I'm learning here.)
I have no idea what I'm doing, so any and all feedback would be greatly appreciated. I'd be particularly interested in some way to cache the results from the API request so that I don't have to fetch it each time the page loads.
The Tech
- C# 6.0
- MVC 5.0
- Ninject MVC for dependency injection.
- Survey Monkey API wrapper for C#.
The Code
The API wrapper library needs an API Key & Token to connect to Survey Monkey. In order to keep them out of the GitHub repo, I created some environment variables and a factory class that knows how to access them and return an instance of SurveyMonkeyApi
.
./SurveyMonkeyApiFactory.cs
namespace SurveyMonkeyPlayground
{
public interface ISurveyMonkeyApiFactory
{
SurveyMonkeyApi Create();
}
public class SurveyMonkeyApiFactory : ISurveyMonkeyApiFactory
{
public SurveyMonkeyApi Create()
{
string apiKey = Environment.GetEnvironmentVariable("SM_APIKEY");
string token = Environment.GetEnvironmentVariable("SM_TOKEN");
return new SurveyMonkeyApi(apiKey, token);
}
}
}
Next I created a model that is a subset of the full Survey
object from the 3rd party library.
./Models/SurveyModel.cs
namespace SurveyMonkeyPlayground.Models
{
public class SurveyModel
{
public string Name { get; set; }
public int ResponseCount { get; set; }
public string Url { get; set; }
}
}
And then a controller to handle requests for a list of all surveys, and details about any given survey.
./Controllers/SurveysController.cs
namespace SurveyMonkeyPlayground.Controllers
{
public class SurveysController : Controller
{
private ISurveyMonkeyApiFactory _apiFactory;
public SurveysController(ISurveyMonkeyApiFactory factory)
{
_apiFactory = factory;
}
// GET: Surveys
public ActionResult Index()
{
var surveyMonkey = _apiFactory.Create();
var surveys = surveyMonkey.GetSurveyList()
.Select(s => new SurveyModel() { Name = s.Nickname, ResponseCount = s.NumResponses, Url = s.AnalysisUrl });
return View(surveys);
}
// GET: Surveys/Details?name=SomeSurveyName
public ActionResult Details(string name)
{
var surveyMonkey = _apiFactory.Create();
var survey = surveyMonkey.GetSurveyList()
.Where(s => s.Nickname == name)
.Select(s => new SurveyModel() { Name = s.Nickname, ResponseCount = s.NumResponses, Url = s.AnalysisUrl })
.First();
return View(survey);
}
}
}
And finally, some views to display this all.
./Views/Surveys/Index.cshtml
@model IEnumerable<SurveyMonkeyPlayground.Models.SurveyModel>
@{
ViewBag.Title = "Surveys";
}
<h2>Surveys</h2>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.Name)
</th>
<th>
@Html.DisplayNameFor(model => model.ResponseCount)
</th>
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
<a href="@item.Url">@item.Name</a>
</td>
<td>
@Html.DisplayFor(modelItem => item.ResponseCount)
</td>
<td>
@Html.ActionLink("Details", "Details", new { Name = item.Name})
</td>
</tr>
}
</table>
./Views/Surveys/Details.cshtml
@model SurveyMonkeyPlayground.Models.SurveyModel
@{
ViewBag.Title = "Surveys";
}
<h2>@Model.Name Details</h2>
<div>
<hr />
<dl class="dl-horizontal">
<dt>
@Html.DisplayNameFor(model => model.Name)
</dt>
<dd>
@Html.DisplayFor(model => model.Name)
</dd>
<dt>
@Html.DisplayNameFor(model => model.ResponseCount)
</dt>
<dd>
@Html.DisplayFor(model => model.ResponseCount)
</dd>
<dt>
Result Analysis Url
</dt>
<dd>
<a href="@Html.DisplayFor(model => model.Url)">@Html.DisplayFor(model => model.Url)</a>
</dd>
</dl>
</div>
<p>
@Html.ActionLink("Back to List", "Index")
</p>