forked from aspnet/AspNetWebStack
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHttpActionContextExtensions.cs
More file actions
176 lines (152 loc) · 7.14 KB
/
Copy pathHttpActionContextExtensions.cs
File metadata and controls
176 lines (152 loc) · 7.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Web.Http.Metadata;
using System.Web.Http.ModelBinding;
using System.Web.Http.Validation;
namespace System.Web.Http.Controllers
{
/// <summary>
/// Extension methods for <see cref="HttpActionContext"/>.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public static class HttpActionContextExtensions
{
/// <summary>
/// Gets the <see cref="ModelMetadataProvider"/> instance for a given <see cref="HttpActionContext"/>.
/// </summary>
/// <param name="actionContext">The context.</param>
/// <returns>An <see cref="ModelMetadataProvider"/> instance.</returns>
public static ModelMetadataProvider GetMetadataProvider(this HttpActionContext actionContext)
{
if (actionContext == null)
{
throw Error.ArgumentNull("actionContext");
}
return actionContext.ControllerContext.Configuration.Services.GetModelMetadataProvider();
}
/// <summary>
/// Gets the collection of registered <see cref="ModelValidatorProvider"/> instances.
/// </summary>
/// <param name="actionContext">The context.</param>
/// <returns>A collection of <see cref="ModelValidatorProvider"/> instances.</returns>
public static IEnumerable<ModelValidatorProvider> GetValidatorProviders(this HttpActionContext actionContext)
{
if (actionContext == null)
{
throw Error.ArgumentNull("actionContext");
}
return actionContext.ControllerContext.Configuration.Services.GetModelValidatorProviders();
}
/// <summary>
/// Gets the collection of registered <see cref="ModelValidator"/> instances.
/// </summary>
/// <param name="actionContext">The context.</param>
/// <param name="metadata">The metadata.</param>
/// <returns>A collection of registered <see cref="ModelValidator"/> instances.</returns>
public static IEnumerable<ModelValidator> GetValidators(this HttpActionContext actionContext, ModelMetadata metadata)
{
if (actionContext == null)
{
throw Error.ArgumentNull("actionContext");
}
IModelValidatorCache validatorCache = actionContext.GetValidatorCache();
return actionContext.GetValidators(metadata, validatorCache);
}
internal static IEnumerable<ModelValidator> GetValidators(this HttpActionContext actionContext, ModelMetadata metadata, IModelValidatorCache validatorCache)
{
if (validatorCache == null)
{
// slow path: there is no validator cache on the configuration
return metadata.GetValidators(actionContext.GetValidatorProviders());
}
else
{
return validatorCache.GetValidators(metadata);
}
}
internal static IModelValidatorCache GetValidatorCache(this HttpActionContext actionContext)
{
Contract.Assert(actionContext != null);
HttpConfiguration configuration = actionContext.ControllerContext.Configuration;
return configuration.Services.GetModelValidatorCache();
}
public static bool TryBindStrongModel<TModel>(this HttpActionContext actionContext, ModelBindingContext parentBindingContext, string propertyName, ModelMetadataProvider metadataProvider, out TModel model)
{
if (actionContext == null)
{
throw Error.ArgumentNull("actionContext");
}
ModelBindingContext propertyBindingContext = new ModelBindingContext(parentBindingContext)
{
ModelMetadata = metadataProvider.GetMetadataForType(null, typeof(TModel)),
ModelName = ModelBindingHelper.CreatePropertyModelName(parentBindingContext.ModelName, propertyName)
};
if (actionContext.Bind(propertyBindingContext))
{
object untypedModel = propertyBindingContext.Model;
model = ModelBindingHelper.CastOrDefault<TModel>(untypedModel);
parentBindingContext.ValidationNode.ChildNodes.Add(propertyBindingContext.ValidationNode);
return true;
}
model = default(TModel);
return false;
}
// Pulls binders from the config
public static bool Bind(this HttpActionContext actionContext, ModelBindingContext bindingContext)
{
Type modelType = bindingContext.ModelType;
HttpConfiguration config = actionContext.ControllerContext.Configuration;
IEnumerable<IModelBinder> binders = from provider in config.Services.GetModelBinderProviders()
select provider.GetBinder(config, modelType);
return Bind(actionContext, bindingContext, binders);
}
/// <summary>
/// Attempt to bind against the given ActionContext.
/// </summary>
/// <param name="actionContext">The action context.</param>
/// <param name="bindingContext">The binding context.</param>
/// <param name="binders">set of binders to use for binding</param>
/// <returns>True if the bind was successful, else false.</returns>
public static bool Bind(this HttpActionContext actionContext, ModelBindingContext bindingContext, IEnumerable<IModelBinder> binders)
{
if (actionContext == null)
{
throw Error.ArgumentNull("actionContext");
}
if (bindingContext == null)
{
throw Error.ArgumentNull("bindingContext");
}
// Protects against stack overflow for deeply nested model binding
RuntimeHelpers.EnsureSufficientExecutionStack();
Type modelType = bindingContext.ModelType;
HttpConfiguration config = actionContext.ControllerContext.Configuration;
ModelBinderProvider providerFromAttr;
if (ModelBindingHelper.TryGetProviderFromAttributes(modelType, out providerFromAttr))
{
IModelBinder binder = providerFromAttr.GetBinder(config, modelType);
if (binder != null)
{
return binder.BindModel(actionContext, bindingContext);
}
}
foreach (IModelBinder binder in binders)
{
if (binder != null)
{
if (binder.BindModel(actionContext, bindingContext))
{
return true;
}
}
}
// Either we couldn't find a binder, or the binder couldn't bind. Distinction is not important.
return false;
}
}
}