Adding support for ViewData
This commit is contained in:
parent
0699e7aa40
commit
5f4807dc9e
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -50,7 +50,8 @@ namespace MvcSample
|
|||
|
||||
public IActionResult MyView()
|
||||
{
|
||||
return Result.View(User());
|
||||
ViewData.Model = User();
|
||||
return Result.View(ViewData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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 »</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 »</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 »</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 »</a></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -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>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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>
|
||||
</div>
|
||||
<div class="container body-content">
|
||||
@RenderBody()
|
||||
<hr />
|
||||
<footer>
|
||||
<p>© @DateTime.Now.Year - My ASP.NET Application</p>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Reference in New Issue