Adding support for ViewData

This commit is contained in:
Pranav K 2014-01-20 16:06:31 -08:00
parent 0699e7aa40
commit 5f4807dc9e
17 changed files with 172 additions and 87 deletions

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
@ -32,18 +33,18 @@ namespace Microsoft.AspNet.CoreServices
}
args.AppendFormat("\"{0}\"", fileInfo.PhysicalPath);
var outputStream = new MemoryStream();
var errorStream = new MemoryStream();
// common execute
var process = CreateProcess(args.ToString());
int exitCode = await Start(process, outputStream, errorStream);
int exitCode = await Start(process, outputStream);
string output = GetString(outputStream);
string error = GetString(errorStream);
if (exitCode != 0)
{
return CompilationResult.Failed(String.Empty, error.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
.Select(e => new CompilationMessage(e)));
IEnumerable<CompilationMessage> messages = output.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
.Skip(3)
.Select(e => new CompilationMessage(e));
return CompilationResult.Failed(String.Empty, messages);
}
var type = Assembly.LoadFrom(outFile)
@ -63,7 +64,7 @@ namespace Microsoft.AspNet.CoreServices
return String.Empty;
}
private static async Task<int> Start(Process process, Stream output, Stream error)
private static async Task<int> Start(Process process, Stream output)
{
var tcs = new TaskCompletionSource<int>();
process.EnableRaisingEvents = true;
@ -74,18 +75,10 @@ namespace Microsoft.AspNet.CoreServices
process.Start();
var tasks = new[]
{
process.StandardOutput.BaseStream.CopyToAsync(output),
process.StandardError.BaseStream.CopyToAsync(error)
};
var copyTask = process.StandardOutput.BaseStream.CopyToAsync(output);
await Task.WhenAll(tcs.Task, copyTask);
int result = await tcs.Task;
// Process has exited, draining the stdout and stderr
await Task.WhenAll(tasks);
return result;
return process.ExitCode;
}
internal Process CreateProcess(string arguments)

View File

@ -89,13 +89,13 @@ namespace Microsoft.AspNet.Mvc.Razor
}
}
protected virtual string RenderBody()
protected virtual HtmlString RenderBody()
{
if (BodyContent == null)
{
throw new InvalidOperationException("RenderBody cannot be called at this point because you're not executing a layout");
}
return BodyContent;
return new HtmlString(BodyContent);
}
}
}

View File

@ -7,9 +7,12 @@ namespace Microsoft.AspNet.Mvc.Razor
{
public TModel Model { get; set; }
public dynamic ViewData { get; set; }
public override Task RenderAsync(ViewContext context, TextWriter writer)
{
Model = (TModel)context.Model;
ViewData = context.ViewData;
Model = (TModel)ViewData.Model;
return base.RenderAsync(context, writer);
}
}

View File

@ -36,12 +36,12 @@ namespace Microsoft.AspNet.Mvc
throw new NotImplementedException();
}
public IActionResult View(string view, object model)
public IActionResult View(string view, ViewDataDictionary viewData)
{
return new ViewResult(_serviceProvider, _viewEngine)
{
ViewName = view,
Model = model
ViewData = viewData
};
}
}

View File

@ -5,17 +5,17 @@ namespace Microsoft.AspNet.Mvc
{
public static IActionResult View(this IActionResultHelper actionResultHelper)
{
return actionResultHelper.View(view: null, model: null);
return actionResultHelper.View(view: null, viewData: null);
}
public static IActionResult View(this IActionResultHelper actionResultHelper, string view)
{
return actionResultHelper.View(view, model: null);
return actionResultHelper.View(view, viewData: null);
}
public static IActionResult View(this IActionResultHelper actionResultHelper, object model)
public static IActionResult View(this IActionResultHelper actionResultHelper, ViewDataDictionary viewData)
{
return actionResultHelper.View(view: null, model: model);
return actionResultHelper.View(view: null, viewData: viewData);
}
}
}

View File

@ -8,10 +8,13 @@ namespace Microsoft.AspNet.Mvc
public void Initialize(IActionResultHelper actionResultHelper)
{
Result = actionResultHelper;
ViewData = new ViewDataDictionary();
}
public IActionResultHelper Result { get; private set; }
public IOwinContext Context { get; set; }
public ViewDataDictionary ViewData { get; private set; }
}
}

View File

@ -6,6 +6,6 @@ namespace Microsoft.AspNet.Mvc
IActionResult Content(string value);
IActionResult Content(string value, string contentType);
IActionResult Json(object value);
IActionResult View(string view, object model);
IActionResult View(string view, ViewDataDictionary viewData);
}
}

View File

@ -89,6 +89,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Routing\IRouteData.cs" />
<Compile Include="View\ViewContext.cs" />
<Compile Include="View\ViewDataDictionary.cs" />
<Compile Include="View\ViewEngineResult.cs" />
<Compile Include="View\ViewResult.cs" />
</ItemGroup>

View File

@ -6,14 +6,14 @@ namespace Microsoft.AspNet.Mvc
{
public class ViewContext : RequestContext
{
public ViewContext(IOwinContext context, IRouteData routeData, object model) :
public ViewContext(IOwinContext context, IRouteData routeData, ViewDataDictionary viewData) :
base(context, routeData)
{
Model = model;
ViewData = viewData;
}
public IServiceProvider ServiceProvider { get; set; }
public object Model { get; private set; }
public ViewDataDictionary ViewData { get; private set; }
}
}

View File

@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;
using System.Dynamic;
namespace Microsoft.AspNet.Mvc
{
public class ViewDataDictionary : DynamicObject
{
private Dictionary<object, dynamic> _data;
public ViewDataDictionary()
{
_data = new Dictionary<object, dynamic>();
}
public ViewDataDictionary(ViewDataDictionary source)
{
_data = new Dictionary<object, dynamic>(source._data);
}
public object Model { get; set; }
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = _data[binder.Name];
// We return true here because ViewDataDictionary returns null if the key is not
// in the dictionary, so we simply pass on the returned value.
return true;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
// This cast should always succeed assuming TValue is dynamic.
dynamic v = value;
_data[binder.Name] = v;
return true;
}
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
{
if (indexes == null || indexes.Length != 1)
{
throw new ArgumentException("Invalid number of indexes");
}
object index = indexes[0];
if (_data.TryGetValue(index, out result))
{
result = _data[index];
}
else
{
result = null;
}
return true;
}
public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value)
{
if (indexes == null || indexes.Length != 1)
{
throw new ArgumentException("Invalid number of indexes");
}
object index = indexes[0];
// This cast should always succeed assuming TValue is dynamic.
_data[index] = (dynamic)value;
return true;
}
}
}

View File

@ -20,7 +20,7 @@ namespace Microsoft.AspNet.Mvc
public string ViewName {get; set; }
public object Model { get; set; }
public ViewDataDictionary ViewData { get; set; }
public async Task ExecuteResultAsync(RequestContext context)
{
@ -35,7 +35,7 @@ namespace Microsoft.AspNet.Mvc
context.HttpContext.Response.ContentType = "text/html";
using (var writer = new StreamWriter(context.HttpContext.Response.Body, Encoding.UTF8, 1024, leaveOpen: true))
{
var viewContext = new ViewContext(context.HttpContext, context.RouteData, Model)
var viewContext = new ViewContext(context.HttpContext, context.RouteData, ViewData)
{
ServiceProvider = _serviceProvider
};

View File

@ -50,7 +50,8 @@ namespace MvcSample
public IActionResult MyView()
{
return Result.View(User());
ViewData.Model = User();
return Result.View(ViewData);
}
}
}

View File

@ -74,8 +74,6 @@
<Compile Include="Models\Class1.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Startup.cs" />
<Compile Include="Views\Layout.cs" />
<Compile Include="Views\MyView.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Microsoft.AspNet.CoreServices\Microsoft.AspNet.CoreServices.csproj">

View File

@ -1,2 +1,33 @@
@{ Layout = "~/Views/Shared/_Layout.cshtml"; }
@DateTime.UtcNow
@{
Layout = "~/Views/Shared/_Layout.cshtml";
ViewData.Title = "Home Page";
}
<div class="jumbotron">
<h1>ASP.NET</h1>
<p class="lead">ASP.NET is a free web framework for building great Web sites and Web applications using HTML, CSS and JavaScript.</p>
<p><a href="http://asp.net" class="btn btn-primary btn-large">Learn more &raquo;</a></p>
</div>
<div class="row">
<div class="col-md-4">
<h2>Getting started</h2>
<p>
ASP.NET MVC gives you a powerful, patterns-based way to build dynamic websites that
enables a clean separation of concerns and gives you full control over markup
for enjoyable, agile development.
</p>
<p><a class="btn btn-default" href="http://go.microsoft.com/fwlink/?LinkId=301865">Learn more &raquo;</a></p>
</div>
<div class="col-md-4">
<h2>Get more libraries</h2>
<p>NuGet is a free Visual Studio extension that makes it easy to add, remove, and update libraries and tools in Visual Studio projects.</p>
<p><a class="btn btn-default" href="http://go.microsoft.com/fwlink/?LinkId=301866">Learn more &raquo;</a></p>
</div>
<div class="col-md-4">
<h2>Web Hosting</h2>
<p>You can easily find a web hosting company that offers the right mix of features and price for your applications.</p>
<p><a class="btn btn-default" href="http://go.microsoft.com/fwlink/?LinkId=301867">Learn more &raquo;</a></p>
</div>
</div>

View File

@ -1,20 +0,0 @@
using System;
using Microsoft.AspNet.Mvc.Razor;
namespace MvcSample.Views
{
[VirtualPath("~/Views/Shared/_Layout.cshtml")]
public class Layout : RazorView
{
public override void Execute()
{
WriteLiteral("<html>");
WriteLiteral("<body>");
WriteLiteral("<h1>Hello world</h1>");
WriteLiteral("<div id=\"main\"");
RenderBody();
WriteLiteral("</div>");
WriteLiteral("</body></html>");
}
}
}

View File

@ -1,20 +0,0 @@
using System;
using Microsoft.AspNet.Mvc.Razor;
namespace MvcSample.Views
{
[VirtualPath("~/Views/Home/MyView.cshtml")]
public class MyView : RazorView<User>
{
public override void Execute()
{
Layout = "~/Views/Shared/_Layout.cshtml";
WriteLiteral("<div style=\"border: 1px solid black\">The time is now");
Write(new HtmlString(DateTime.UtcNow.ToString()));
WriteLiteral("<em>");
Write(Model.Name);
Write("</em>");
WriteLiteral("</div>");
}
}
}

View File

@ -1,11 +1,34 @@
<html>
<head>
<title>No title</title>
</head>
<body>
<div style="margin: auto; width: 900px">
<h2>Hello world</h2>
@RenderBody()
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@ViewData.Title - My ASP.NET Application</title>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" />
</head>
<body>
<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>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="/">Home</a></li>
</ul>
</div>
</div>
</body>
</html>
</div>
<div class="container body-content">
@RenderBody()
<hr />
<footer>
<p>&copy; @DateTime.Now.Year - My ASP.NET Application</p>
</footer>
</div>
</body>
</html>