Skip to content
This repository has been archived by the owner on Dec 14, 2018. It is now read-only.

Commit

Permalink
Removing ModelMetadata.Model
Browse files Browse the repository at this point in the history
  • Loading branch information
rynowak committed Feb 24, 2015
1 parent ed8e571 commit 9d5364c
Show file tree
Hide file tree
Showing 110 changed files with 2,313 additions and 1,527 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
@functions {
private object FormattedValue {
get {
if (ViewData.TemplateInfo.FormattedModelValue == ViewData.ModelMetadata.Model) {
return String.Format(CultureInfo.CurrentCulture, "{0:0.00}", ViewData.ModelMetadata.Model);
if (ViewData.TemplateInfo.FormattedModelValue == ViewData.ModelExplorer.Model) {
return String.Format(CultureInfo.CurrentCulture, "{0:0.00}", ViewData.ModelExplorer.Model);
}
return ViewData.TemplateInfo.FormattedModelValue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
@functions {
private object FormattedValue {
get {
if (ViewData.TemplateInfo.FormattedModelValue == ViewData.ModelMetadata.Model) {
return string.Format(CultureInfo.CurrentCulture, "{0:0.00}", ViewData.ModelMetadata.Model);
if (ViewData.TemplateInfo.FormattedModelValue == ViewData.ModelExplorer.Model) {
return string.Format(CultureInfo.CurrentCulture, "{0:0.00}", ViewData.ModelExplorer.Model);
}
return ViewData.TemplateInfo.FormattedModelValue;
}
Expand Down
7 changes: 2 additions & 5 deletions src/Microsoft.AspNet.Mvc.Core/Controller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1209,17 +1209,14 @@ public virtual bool TryValidateModel([NotNull] object model, string prefix)
throw new InvalidOperationException(message);
}

var modelMetadata = MetadataProvider.GetMetadataForType(
modelAccessor: () => model,
modelType: model.GetType());
var modelExplorer = MetadataProvider.GetModelExplorerForType(model.GetType(), model);

var modelName = prefix ?? string.Empty;
var validationContext = new ModelValidationContext(
modelName,
BindingContext.ValidatorProvider,
ModelState,
modelMetadata,
containerMetadata: null);
modelExplorer);

ObjectValidator.Validate(validationContext);
return ModelState.IsValid;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ public class DefaultControllerActionArgumentBinder : IControllerActionArgumentBi
foreach (var parameter in actionDescriptor.Parameters)
{
var metadata = _modelMetadataProvider.GetMetadataForParameter(
modelAccessor: null,
methodInfo: actionDescriptor.MethodInfo,
parameterName: parameter.Name);

Expand Down Expand Up @@ -97,17 +96,19 @@ private void UpdateParameterMetadata(ModelMetadata metadata, IBinderMetadata bin
foreach (var parameter in parameterMetadata)
{
var parameterType = parameter.ModelType;

var modelBindingContext = GetModelBindingContext(parameter, modelState, operationBindingContext);
var modelBindingResult = await bindingContext.ModelBinder.BindModelAsync(modelBindingContext);
if (modelBindingResult != null && modelBindingResult.IsModelSet)
{
var modelExplorer = new ModelExplorer(_modelMetadataProvider, parameter, modelBindingResult.Model);

arguments[parameter.PropertyName] = modelBindingResult.Model;
var validationContext = new ModelValidationContext(
modelBindingResult.Key,
bindingContext.ValidatorProvider,
actionContext.ModelState,
parameter,
containerMetadata: null);
modelBindingResult.Key,
bindingContext.ValidatorProvider,
actionContext.ModelState,
modelExplorer);
_validator.Validate(validationContext);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,7 @@ public void OnProvidersExecuted([NotNull] ApiDescriptionProviderContext context)
{
apiDescription.ResponseType = runtimeReturnType;

apiDescription.ResponseModelMetadata = _modelMetadataProvider.GetMetadataForType(
modelAccessor: null,
modelType: runtimeReturnType);
apiDescription.ResponseModelMetadata = _modelMetadataProvider.GetMetadataForType(runtimeReturnType);

var formats = GetResponseFormats(
action,
Expand Down Expand Up @@ -436,7 +434,6 @@ public PseudoModelBindingVisitor(ApiParameterContext context, ParameterDescripto
public void WalkParameter()
{
var modelMetadata = Context.MetadataProvider.GetMetadataForParameter(
modelAccessor: null,
methodInfo: Context.ActionDescriptor.MethodInfo,
parameterName: Parameter.Name);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,9 +252,7 @@ public static class ModelBindingHelper
throw new ArgumentException(message, nameof(modelType));
}

var modelMetadata = metadataProvider.GetMetadataForType(
modelAccessor: () => model,
modelType: modelType);
var modelMetadata = metadataProvider.GetMetadataForType(modelType);

var operationBindingContext = new OperationBindingContext
{
Expand All @@ -266,6 +264,7 @@ public static class ModelBindingHelper

var modelBindingContext = new ModelBindingContext
{
Model = model,
ModelMetadata = modelMetadata,
ModelName = prefix,
ModelState = modelState,
Expand All @@ -278,7 +277,8 @@ public static class ModelBindingHelper
var modelBindingResult = await modelBinder.BindModelAsync(modelBindingContext);
if (modelBindingResult != null)
{
var modelValidationContext = new ModelValidationContext(modelBindingContext, modelMetadata);
var modelExplorer = new ModelExplorer(metadataProvider, modelMetadata, modelBindingResult.Model);
var modelValidationContext = new ModelValidationContext(modelBindingContext, modelExplorer);
modelValidationContext.RootPrefix = prefix;
objectModelValidator.Validate(modelValidationContext);
return modelState.IsValid;
Expand Down Expand Up @@ -382,4 +382,4 @@ public static string CreatePropertyModelName(string prefix, string propertyName)
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Globalization;
using System.Linq.Expressions;
using System.Reflection;
using Microsoft.AspNet.Mvc.Core;
Expand All @@ -12,7 +13,7 @@ namespace Microsoft.AspNet.Mvc.Rendering.Expressions
{
public static class ExpressionMetadataProvider
{
public static ModelMetadata FromLambdaExpression<TModel, TResult>(
public static ModelExplorer FromLambdaExpression<TModel, TResult>(
[NotNull] Expression<Func<TModel, TResult>> expression,
[NotNull] ViewDataDictionary<TModel> viewData,
IModelMetadataProvider metadataProvider)
Expand Down Expand Up @@ -55,31 +56,43 @@ public static class ExpressionMetadataProvider
throw new InvalidOperationException(Resources.TemplateHelpers_TemplateLimitations);
}

var container = viewData.Model;
Func<object> modelAccessor = () =>
Func<object, object> modelAccessor = (container) =>
{
try
{
return CachedExpressionCompiler.Process(expression)(container);
return CachedExpressionCompiler.Process(expression)((TModel)container);
}
catch (NullReferenceException)
{
return null;
}
};

return GetMetadataFromProvider(
modelAccessor,
typeof(TResult),
propertyName,
container,
containerType,
metadataProvider);
ModelMetadata metadata;
if (propertyName == null)
{
// Ex:
// m => 5 (arbitrary expression)
// m => foo (arbitrary expression)
// m => m.Widgets[0] (expression ending with non-property-access)
metadata = metadataProvider.GetMetadataForType(typeof(TResult));
}
else
{
// Ex:
// m => m.Color (simple property access)
// m => m.Color.Red (nested property access)
// m => m.Widgets[0].Size (expression ending with property-access)
metadata = metadataProvider.GetMetadataForType(containerType).Properties[propertyName];
}

return viewData.ModelExplorer.GetExplorerForExpression(metadata, modelAccessor);
}

public static ModelMetadata FromStringExpression(string expression,
[NotNull] ViewDataDictionary viewData,
IModelMetadataProvider metadataProvider)
public static ModelExplorer FromStringExpression(
string expression,
[NotNull] ViewDataDictionary viewData,
IModelMetadataProvider metadataProvider)
{
if (string.IsNullOrEmpty(expression))
{
Expand All @@ -88,93 +101,64 @@ public static class ExpressionMetadataProvider
}

var viewDataInfo = ViewDataEvaluator.Eval(viewData, expression);
Type containerType = null;
Type modelType = null;
Func<object> modelAccessor = null;
string propertyName = null;
object container = null;

if (viewDataInfo == null)
{
// Try getting a property from ModelMetadata if we couldn't find an answer in ViewData
var propertyExplorer = viewData.ModelExplorer.GetExplorerForProperty(expression);
if (propertyExplorer != null)
{
return propertyExplorer;
}
}

if (viewDataInfo != null)
{
ModelExplorer containerExplorer = viewData.ModelExplorer;
if (viewDataInfo.Container != null)
{
containerType = viewDataInfo.Container.GetType();
container = viewDataInfo.Container;
containerExplorer = metadataProvider.GetModelExplorerForType(
viewDataInfo.Container.GetType(),
viewDataInfo.Container);
}

modelAccessor = () => viewDataInfo.Value;

if (viewDataInfo.PropertyInfo != null)
{
propertyName = viewDataInfo.PropertyInfo.Name;
modelType = viewDataInfo.PropertyInfo.PropertyType;
// We've identified a property access, which provides us with accurate metadata.
var containerType = viewDataInfo.Container?.GetType() ?? viewDataInfo.PropertyInfo.DeclaringType;
var containerMetadata = metadataProvider.GetMetadataForType(viewDataInfo.Container.GetType());
var propertyMetadata = containerMetadata.Properties[viewDataInfo.PropertyInfo.Name];

Func<object, object> modelAccessor = (ignore) => viewDataInfo.Value;
return containerExplorer.GetExplorerForExpression(propertyMetadata, modelAccessor);
}
else if (viewDataInfo.Value != null)
{
// We only need to delay accessing properties (for LINQ to SQL)
modelType = viewDataInfo.Value.GetType();
}
}
else
{
// Try getting a property from ModelMetadata if we couldn't find an answer in ViewData
var propertyMetadata = viewData.ModelMetadata.Properties[expression];
if (propertyMetadata != null)
{
return propertyMetadata;
// We have a value, even though we may not know where it came from.
var valueMetadata = metadataProvider.GetMetadataForType(viewDataInfo.Value.GetType());
return containerExplorer.GetExplorerForExpression(valueMetadata, viewDataInfo.Value);
}
}

return GetMetadataFromProvider(modelAccessor,
modelType ?? typeof(string),
propertyName,
container,
containerType,
metadataProvider);
// Treat the expression as string if we don't find anything better.
var stringMetadata = metadataProvider.GetMetadataForType(typeof(string));
return viewData.ModelExplorer.GetExplorerForExpression(stringMetadata, modelAccessor: null);
}

private static ModelMetadata FromModel([NotNull] ViewDataDictionary viewData,
IModelMetadataProvider metadataProvider)
private static ModelExplorer FromModel(
[NotNull] ViewDataDictionary viewData,
IModelMetadataProvider metadataProvider)
{
if (viewData.ModelMetadata.ModelType == typeof(object))
{
// Use common simple type rather than object so e.g. Editor() at least generates a TextBox.
return GetMetadataFromProvider(
modelAccessor: null,
modelType: typeof(string),
propertyName: null,
container: null,
containerType: null,
metadataProvider: metadataProvider);
var model = viewData.Model == null ? null : Convert.ToString(viewData.Model, CultureInfo.CurrentCulture);
return metadataProvider.GetModelExplorerForType(typeof(string), model);
}
else
{
return viewData.ModelMetadata;
}
}

// An IModelMetadataProvider is not required unless this method is called. Therefore other methods in this
// class lack [NotNull] attributes for their corresponding parameter.
private static ModelMetadata GetMetadataFromProvider(Func<object> modelAccessor,
Type modelType,
string propertyName,
object container,
Type containerType,
[NotNull] IModelMetadataProvider metadataProvider)
{
if (containerType != null && !string.IsNullOrEmpty(propertyName))
{
var metadata =
metadataProvider.GetMetadataForProperty(modelAccessor, containerType, propertyName);
if (metadata != null)
{
metadata.Container = container;
}

return metadata;
return viewData.ModelExplorer;
}

return metadataProvider.GetMetadataForType(modelAccessor, modelType);
}
}
}
}
Loading

0 comments on commit 9d5364c

Please sign in to comment.