Skip to content

Instantly share code, notes, and snippets.

@EricCote
Last active February 16, 2017 22:03
Show Gist options
  • Save EricCote/fed5b46d4234cbfd5c49522572f46d0a to your computer and use it in GitHub Desktop.
Save EricCote/fed5b46d4234cbfd5c49522572f46d0a to your computer and use it in GitHub Desktop.
Web Api Lab 5
using GeekQuiz.Models;
...
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
System.Data.Entity.Database.SetInitializer(new TriviaDatabaseInitializer());
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
namespace GeekQuiz.Controllers
{
[Authorize]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
...
}
}
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@ViewBag.Title - Geek Quiz</title>
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
</head>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
@Html.ActionLink("Geek Quiz", "Index", "Home", null, new { @class = "navbar-brand" })
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>@Html.ActionLink("Play", "Index", "Home")</li>
</ul>
@Html.Partial("_LoginPartial")
</div>
</div>
</div>
<div class="container body-content">
@RenderBody()
<hr />
<footer>
<p>&copy; @DateTime.Now.Year - Geek Quiz</p>
</footer>
</div>
using Newtonsoft.Json.Serialization;
...
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Use camel case for JSON data.
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
using System.Data.Entity;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http.Description;
using GeekQuiz.Models;
....
public class TriviaController : ApiController
{
private TriviaContext db = new TriviaContext();
protected override void Dispose(bool disposing)
{
if (disposing)
{
this.db.Dispose();
}
base.Dispose(disposing);
}
}
....
private async Task<TriviaQuestion> NextQuestionAsync(string userId)
{
var lastQuestionId = await this.db.TriviaAnswers
.Where(a => a.UserId == userId)
.GroupBy(a => a.QuestionId)
.Select(g => new { QuestionId = g.Key, Count = g.Count() })
.OrderByDescending(q => new { q.Count, QuestionId = q.QuestionId })
.Select(q => q.QuestionId)
.FirstOrDefaultAsync();
var questionsCount = await this.db.TriviaQuestions.CountAsync();
var nextQuestionId = (lastQuestionId % questionsCount) + 1;
return await this.db.TriviaQuestions.FindAsync(CancellationToken.None, nextQuestionId);
}
...
// GET api/Trivia
[ResponseType(typeof(TriviaQuestion))]
public async Task<IHttpActionResult> Get()
{
var userId = User.Identity.Name;
TriviaQuestion nextQuestion = await this.NextQuestionAsync(userId);
if (nextQuestion == null)
{
return this.NotFound();
}
return this.Ok(nextQuestion);
}
...
private async Task<bool> StoreAsync(TriviaAnswer answer)
{
this.db.TriviaAnswers.Add(answer);
await this.db.SaveChangesAsync();
var selectedOption = await this.db.TriviaOptions.FirstOrDefaultAsync(o => o.Id == answer.OptionId
&& o.QuestionId == answer.QuestionId);
return selectedOption.IsCorrect;
}
...
// POST api/Trivia
[ResponseType(typeof(TriviaAnswer))]
public async Task<IHttpActionResult> Post(TriviaAnswer answer)
{
if (!ModelState.IsValid)
{
return this.BadRequest(this.ModelState);
}
answer.UserId = User.Identity.Name;
var isCorrect = await this.StoreAsync(answer);
return this.Ok<bool>(isCorrect);
}
...
angular.module('QuizApp', [])
.controller('QuizCtrl', function ($scope, $http) {
$scope.answered = false;
$scope.title = "loading question...";
$scope.options = [];
$scope.correctAnswer = false;
$scope.working = false;
$scope.answer = function () {
return $scope.correctAnswer ? 'correct' : 'incorrect';
};
});
.controller('QuizCtrl', function ($scope, $http) {
...
$scope.nextQuestion = function () {
$scope.working = true;
$scope.answered = false;
$scope.title = "loading question...";
$scope.options = [];
$http.get("/api/trivia").then(function (response) {
$scope.options = response.data.options;
$scope.title = response.data.title;
$scope.answered = false;
$scope.working = false;
},function (response) {
$scope.title = "Oops... something went wrong";
$scope.working = false;
});
};
};
.controller('QuizCtrl', function ($scope, $http) {
...
$scope.sendAnswer = function (option) {
$scope.working = true;
$scope.answered = true;
$http.post('/api/trivia', { 'questionId': option.questionId, 'optionId': option.id }).then(function (response) {
$scope.correctAnswer = (response.data === true);
$scope.working = false;
}, function (response) {
$scope.title = "Oops... something went wrong";
$scope.working = false;
});
};
};
@{
ViewBag.Title = "Play";
}
<div id="bodyContainer" ng-app="QuizApp">
<section id="content">
<div class="container" >
<div class="row">
<div class="flip-container text-center col-md-12" ng-controller="QuizCtrl" ng-init="nextQuestion()">
<div class="back" ng-class="{flip: answered, correct: correctAnswer, incorrect:!correctAnswer}">
<p class="lead">{{answer()}}</p>
<p>
<button class="btn btn-info btn-lg next option" ng-click="nextQuestion()" ng-disabled="working">Next Question</button>
</p>
</div>
<div class="front" ng-class="{flip: answered}">
<p class="lead">{{title}}</p>
<div class="row text-center">
<button class="btn btn-info btn-lg option" ng-repeat="option in options" ng-click="sendAnswer(option)" ng-disabled="working">{{option.title}}</button>
</div>
</div>
</div>
</div>
</div>
</section>
</div>
@section scripts {
@Scripts.Render("~/Scripts/angular.js")
@Scripts.Render("~/Scripts/app/quiz-controller.js")
}
.validation-summary-valid {
display: none;
}
/* Geek Quiz styles */
.flip-container .back,
.flip-container .front {
border: 5px solid #00bcf2;
padding-bottom: 30px;
padding-top: 30px;
}
#content {
position:relative;
background:#fff;
padding:50px 0 0 0;
}
.option {
width:140px;
margin: 5px;
}
div.correct p {
color: green;
}
div.incorrect p {
color: red;
}
.btn {
border-radius: 0;
}
.flip-container div.front, .flip-container div.back.flip {
display: block;
}
.flip-container div.front.flip, .flip-container div.back {
display
/* flip transformation */
.flip-container div.front {
-moz-transform: perspective(2000px) rotateY(0deg);
-webkit-transform: perspective(2000px) rotateY(0deg);
-o-transform: perspective(2000px) rotateY(0deg);
transform: perspective(2000px) rotateY(0deg);
}
.flip-container div.front.flip {
-moz-transform: perspective(2000px) rotateY(179.9deg);
-webkit-transform: perspective(2000px) rotateY(179.9deg);
-o-transform: perspective(2000px) rotateY(179.9deg);
transform: perspective(2000px) rotateY(179.9deg);
}
.flip-container div.back {
-moz-transform: perspective(2000px) rotateY(-180deg);
-webkit-transform: perspective(2000px) rotateY(-180deg);
-o-transform: perspective(2000px) rotateY(-180deg);
transform: perspective(2000px) rotateY(-180deg);
}
.flip-container div.back.flip {
-moz-transform: perspective(2000px) rotateY(0deg);
-webkit-transform: perspective(2000px) rotateY(0deg);
-ms-transform: perspective(2000px) rotateY(0);
-o-transform: perspective(2000px) rotateY(0);
transform: perspective(2000px) rotateY(0);
}
/* hide back of pane during flip */
.front, .back {
-moz-backface-visibility: hidden;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
bundles.Add(new StyleBundle("~/Content/css").Include(
"~/Content/bootstrap.css",
"~/Content/site.css",
"~/Content/Flip.css"));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment