Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

First real commit.

  • Loading branch information...
commit 42ddafe883231f16098ec2fc7e1d656051f844b6 1 parent c0e2025
@elishnevsky authored
Showing with 2,220 additions and 0 deletions.
  1. +6 −0 .nuget/NuGet.Config
  2. BIN  .nuget/NuGet.exe
  3. +150 −0 .nuget/NuGet.targets
  4. +33 −0 Ext.Direct.Mvc3.sln
  5. +20 −0 LICENSE.txt
  6. +5 −0 packages/repositories.config
  7. +22 −0 src/Ext.Direct.Mvc/Attributes/DirectEventAttribute.cs
  8. +28 −0 src/Ext.Direct.Mvc/Attributes/DirectHandleErrorAttribute.cs
  9. +9 −0 src/Ext.Direct.Mvc/Attributes/DirectIgnoreAttribute.cs
  10. +9 −0 src/Ext.Direct.Mvc/Attributes/FormHandlerAttribute.cs
  11. +9 −0 src/Ext.Direct.Mvc/Attributes/NamedArgumentsAttributes.cs
  12. +59 −0 src/Ext.Direct.Mvc/DirectAction.cs
  13. +18 −0 src/Ext.Direct.Mvc/DirectApiController.cs
  14. +41 −0 src/Ext.Direct.Mvc/DirectController.cs
  15. +43 −0 src/Ext.Direct.Mvc/DirectDataResponse.cs
  16. +52 −0 src/Ext.Direct.Mvc/DirectErrorResponse.cs
  17. +26 −0 src/Ext.Direct.Mvc/DirectEventResponse.cs
  18. +13 −0 src/Ext.Direct.Mvc/DirectException.cs
  19. +78 −0 src/Ext.Direct.Mvc/DirectMethod.cs
  20. +29 −0 src/Ext.Direct.Mvc/DirectMethodInvoker.cs
  21. +214 −0 src/Ext.Direct.Mvc/DirectProvider.cs
  22. +67 −0 src/Ext.Direct.Mvc/DirectRequest.cs
  23. +79 −0 src/Ext.Direct.Mvc/DirectResponse.cs
  24. +88 −0 src/Ext.Direct.Mvc/DirectResult.cs
  25. +18 −0 src/Ext.Direct.Mvc/DirectRouterController.cs
  26. +83 −0 src/Ext.Direct.Mvc/DirectValueProvider.cs
  27. BIN  src/Ext.Direct.Mvc/Ext.Direct.Mvc.snk
  28. +102 −0 src/Ext.Direct.Mvc/Ext.Direct.Mvc3.csproj
  29. +12 −0 src/Ext.Direct.Mvc/Extensions/JsonExtensions.cs
  30. +22 −0 src/Ext.Direct.Mvc/Extensions/MethodExtensions.cs
  31. +21 −0 src/Ext.Direct.Mvc/Extensions/TypeExtensions.cs
  32. +36 −0 src/Ext.Direct.Mvc/Properties/AssemblyInfo.cs
  33. +81 −0 src/Ext.Direct.Mvc/ProviderConfiguration.cs
  34. +39 −0 src/Ext.Direct.Mvc/RequestDataConverter.cs
  35. +135 −0 src/Ext.Direct.Mvc/Resources/DirectResources.Designer.cs
  36. +144 −0 src/Ext.Direct.Mvc/Resources/DirectResources.resx
  37. +4 −0 src/Ext.Direct.Mvc/packages.config
  38. +19 −0 test/Ext.Direct.Mvc3Test/Controllers/BasicController.cs
  39. +16 −0 test/Ext.Direct.Mvc3Test/Controllers/HomeController.cs
  40. +138 −0 test/Ext.Direct.Mvc3Test/Ext.Direct.Mvc3Test.csproj
  41. +1 −0  test/Ext.Direct.Mvc3Test/Global.asax
  42. +30 −0 test/Ext.Direct.Mvc3Test/Global.asax.cs
  43. +19 −0 test/Ext.Direct.Mvc3Test/Properties/AssemblyInfo.cs
  44. +31 −0 test/Ext.Direct.Mvc3Test/Views/Home/Index.cshtml
  45. +58 −0 test/Ext.Direct.Mvc3Test/Views/Web.config
  46. +30 −0 test/Ext.Direct.Mvc3Test/Web.Debug.config
  47. +31 −0 test/Ext.Direct.Mvc3Test/Web.Release.config
  48. +48 −0 test/Ext.Direct.Mvc3Test/Web.config
  49. +4 −0 test/Ext.Direct.Mvc3Test/packages.config
View
6 .nuget/NuGet.Config
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+ <solution>
+ <add key="disableSourceControlIntegration" value="true" />
+ </solution>
+</configuration>
View
BIN  .nuget/NuGet.exe
Binary file not shown
View
150 .nuget/NuGet.targets
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">$(MSBuildProjectDirectory)\..\</SolutionDir>
+
+ <!-- Enable the restore command to run before builds -->
+ <RestorePackages Condition=" '$(RestorePackages)' == '' ">false</RestorePackages>
+
+ <!-- Property that enables building a package from a project -->
+ <BuildPackage Condition=" '$(BuildPackage)' == '' ">false</BuildPackage>
+
+ <!-- Determines if package restore consent is required to restore packages -->
+ <RequireRestoreConsent Condition=" '$(RequireRestoreConsent)' != 'false' ">true</RequireRestoreConsent>
+
+ <!-- Download NuGet.exe if it does not already exist -->
+ <DownloadNuGetExe Condition=" '$(DownloadNuGetExe)' == '' ">false</DownloadNuGetExe>
+ </PropertyGroup>
+
+ <ItemGroup Condition=" '$(PackageSources)' == '' ">
+ <!-- Package sources used to restore packages. By default will used the registered sources under %APPDATA%\NuGet\NuGet.Config -->
+ <!--
+ <PackageSource Include="https://nuget.org/api/v2/" />
+ <PackageSource Include="https://my-nuget-source/nuget/" />
+ -->
+ </ItemGroup>
+
+ <PropertyGroup Condition=" '$(OS)' == 'Windows_NT'">
+ <!-- Windows specific commands -->
+ <NuGetToolsPath>$([System.IO.Path]::Combine($(SolutionDir), ".nuget"))</NuGetToolsPath>
+ <PackagesConfig>$([System.IO.Path]::Combine($(ProjectDir), "packages.config"))</PackagesConfig>
+ </PropertyGroup>
+
+ <PropertyGroup Condition=" '$(OS)' != 'Windows_NT'">
+ <!-- We need to launch nuget.exe with the mono command if we're not on windows -->
+ <NuGetToolsPath>$(SolutionDir).nuget</NuGetToolsPath>
+ <PackagesConfig>packages.config</PackagesConfig>
+ </PropertyGroup>
+
+ <PropertyGroup>
+ <!-- NuGet command -->
+ <NuGetExePath Condition=" '$(NuGetExePath)' == '' ">$(NuGetToolsPath)\nuget.exe</NuGetExePath>
+ <PackageSources Condition=" $(PackageSources) == '' ">@(PackageSource)</PackageSources>
+
+ <NuGetCommand Condition=" '$(OS)' == 'Windows_NT'">"$(NuGetExePath)"</NuGetCommand>
+ <NuGetCommand Condition=" '$(OS)' != 'Windows_NT' ">mono --runtime=v4.0.30319 $(NuGetExePath)</NuGetCommand>
+
+ <PackageOutputDir Condition="$(PackageOutputDir) == ''">$(TargetDir.Trim('\\'))</PackageOutputDir>
+
+ <RequireConsentSwitch Condition=" $(RequireRestoreConsent) == 'true' ">-RequireConsent</RequireConsentSwitch>
+ <!-- Commands -->
+ <RestoreCommand>$(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(RequireConsentSwitch) -solutionDir "$(SolutionDir) "</RestoreCommand>
+ <BuildCommand>$(NuGetCommand) pack "$(ProjectPath)" -p Configuration=$(Configuration) -o "$(PackageOutputDir)" -symbols</BuildCommand>
+
+ <!-- We need to ensure packages are restored prior to assembly resolve -->
+ <ResolveReferencesDependsOn Condition="$(RestorePackages) == 'true'">
+ RestorePackages;
+ $(ResolveReferencesDependsOn);
+ </ResolveReferencesDependsOn>
+
+ <!-- Make the build depend on restore packages -->
+ <BuildDependsOn Condition="$(BuildPackage) == 'true'">
+ $(BuildDependsOn);
+ BuildPackage;
+ </BuildDependsOn>
+ </PropertyGroup>
+
+ <Target Name="CheckPrerequisites">
+ <!-- Raise an error if we're unable to locate nuget.exe -->
+ <Error Condition="'$(DownloadNuGetExe)' != 'true' AND !Exists('$(NuGetExePath)')" Text="Unable to locate '$(NuGetExePath)'" />
+ <SetEnvironmentVariable EnvKey="VisualStudioVersion" EnvValue="$(VisualStudioVersion)" Condition=" '$(VisualStudioVersion)' != '' AND '$(OS)' == 'Windows_NT' " />
+ <!--
+ Take advantage of MsBuild's build dependency tracking to make sure that we only ever download nuget.exe once.
+ This effectively acts as a lock that makes sure that the download operation will only happen once and all
+ parallel builds will have to wait for it to complete.
+ -->
+ <MsBuild Targets="_DownloadNuGet" Projects="$(MSBuildThisFileFullPath)" Properties="Configuration=NOT_IMPORTANT" />
+ </Target>
+
+ <Target Name="_DownloadNuGet">
+ <DownloadNuGet OutputFilename="$(NuGetExePath)" Condition=" '$(DownloadNuGetExe)' == 'true' AND !Exists('$(NuGetExePath)')" />
+ </Target>
+
+ <Target Name="RestorePackages" DependsOnTargets="CheckPrerequisites">
+ <Exec Command="$(RestoreCommand)"
+ Condition="'$(OS)' != 'Windows_NT' And Exists('$(PackagesConfig)')" />
+
+ <Exec Command="$(RestoreCommand)"
+ LogStandardErrorAsError="true"
+ Condition="'$(OS)' == 'Windows_NT' And Exists('$(PackagesConfig)')" />
+ </Target>
+
+ <Target Name="BuildPackage" DependsOnTargets="CheckPrerequisites">
+ <Exec Command="$(BuildCommand)"
+ Condition=" '$(OS)' != 'Windows_NT' " />
+
+ <Exec Command="$(BuildCommand)"
+ LogStandardErrorAsError="true"
+ Condition=" '$(OS)' == 'Windows_NT' " />
+ </Target>
+
+ <UsingTask TaskName="DownloadNuGet" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
+ <ParameterGroup>
+ <OutputFilename ParameterType="System.String" Required="true" />
+ </ParameterGroup>
+ <Task>
+ <Reference Include="System.Core" />
+ <Using Namespace="System" />
+ <Using Namespace="System.IO" />
+ <Using Namespace="System.Net" />
+ <Using Namespace="Microsoft.Build.Framework" />
+ <Using Namespace="Microsoft.Build.Utilities" />
+ <Code Type="Fragment" Language="cs">
+ <![CDATA[
+ try {
+ OutputFilename = Path.GetFullPath(OutputFilename);
+
+ Log.LogMessage("Downloading latest version of NuGet.exe...");
+ WebClient webClient = new WebClient();
+ webClient.DownloadFile("https://nuget.org/nuget.exe", OutputFilename);
+
+ return true;
+ }
+ catch (Exception ex) {
+ Log.LogErrorFromException(ex);
+ return false;
+ }
+ ]]>
+ </Code>
+ </Task>
+ </UsingTask>
+
+ <UsingTask TaskName="SetEnvironmentVariable" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
+ <ParameterGroup>
+ <EnvKey ParameterType="System.String" Required="true" />
+ <EnvValue ParameterType="System.String" Required="true" />
+ </ParameterGroup>
+ <Task>
+ <Using Namespace="System" />
+ <Code Type="Fragment" Language="cs">
+ <![CDATA[
+ try {
+ Environment.SetEnvironmentVariable(EnvKey, EnvValue, System.EnvironmentVariableTarget.Process);
+ }
+ catch {
+ }
+ ]]>
+ </Code>
+ </Task>
+ </UsingTask>
+</Project>
View
33 Ext.Direct.Mvc3.sln
@@ -0,0 +1,33 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ext.Direct.Mvc3", "src\Ext.Direct.Mvc\Ext.Direct.Mvc3.csproj", "{A521832A-D1FB-468F-BA7C-1FAE0F7F45EA}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ext.Direct.Mvc3Test", "test\Ext.Direct.Mvc3Test\Ext.Direct.Mvc3Test.csproj", "{D689FA7E-74DC-477B-A69F-EA6FF4C7739B}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{64FA027D-43BA-4FF9-B83C-C6B39B7B73D5}"
+ ProjectSection(SolutionItems) = preProject
+ .nuget\NuGet.Config = .nuget\NuGet.Config
+ .nuget\NuGet.exe = .nuget\NuGet.exe
+ .nuget\NuGet.targets = .nuget\NuGet.targets
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {A521832A-D1FB-468F-BA7C-1FAE0F7F45EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A521832A-D1FB-468F-BA7C-1FAE0F7F45EA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A521832A-D1FB-468F-BA7C-1FAE0F7F45EA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A521832A-D1FB-468F-BA7C-1FAE0F7F45EA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D689FA7E-74DC-477B-A69F-EA6FF4C7739B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D689FA7E-74DC-477B-A69F-EA6FF4C7739B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D689FA7E-74DC-477B-A69F-EA6FF4C7739B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D689FA7E-74DC-477B-A69F-EA6FF4C7739B}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
View
20 LICENSE.txt
@@ -0,0 +1,20 @@
+Copyright 2012 Eugene Lishnevsky
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
View
5 packages/repositories.config
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<repositories>
+ <repository path="..\src\Ext.Direct.Mvc\packages.config" />
+ <repository path="..\test\Ext.Direct.Mvc3Test\packages.config" />
+</repositories>
View
22 src/Ext.Direct.Mvc/Attributes/DirectEventAttribute.cs
@@ -0,0 +1,22 @@
+using System;
+using Ext.Direct.Mvc.Resources;
+
+namespace Ext.Direct.Mvc {
+
+ [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
+ public sealed class DirectEventAttribute : Attribute {
+
+ public DirectEventAttribute(string name) {
+ if (String.IsNullOrEmpty(name)) {
+ throw new ArgumentException(DirectResources.Common_NullOrEmpty, "name");
+ }
+
+ Name = name;
+ }
+
+ public string Name {
+ get;
+ private set;
+ }
+ }
+}
View
28 src/Ext.Direct.Mvc/Attributes/DirectHandleErrorAttribute.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Web.Mvc;
+
+namespace Ext.Direct.Mvc {
+
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
+ public class DirectHandleErrorAttribute : FilterAttribute, IExceptionFilter {
+
+ public void OnException(ExceptionContext filterContext) {
+ if (filterContext == null) {
+ throw new ArgumentNullException("filterContext");
+ }
+
+ if (filterContext.ExceptionHandled) {
+ return;
+ }
+
+ var exception = filterContext.Exception;
+ var directRequest = filterContext.HttpContext.Items[DirectRequest.DirectRequestKey] as DirectRequest;
+
+ if (directRequest != null) {
+ var errorResponse = new DirectErrorResponse(directRequest, exception);
+ errorResponse.Write(filterContext.HttpContext.Response);
+ filterContext.ExceptionHandled = true;
+ }
+ }
+ }
+}
View
9 src/Ext.Direct.Mvc/Attributes/DirectIgnoreAttribute.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace Ext.Direct.Mvc {
+
+ [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
+ public sealed class DirectIgnoreAttribute : Attribute {
+
+ }
+}
View
9 src/Ext.Direct.Mvc/Attributes/FormHandlerAttribute.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace Ext.Direct.Mvc {
+
+ [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
+ public sealed class FormHandlerAttribute : Attribute {
+
+ }
+}
View
9 src/Ext.Direct.Mvc/Attributes/NamedArgumentsAttributes.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace Ext.Direct.Mvc {
+
+ [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
+ public sealed class NamedArgumentsAttribute : Attribute {
+
+ }
+}
View
59 src/Ext.Direct.Mvc/DirectAction.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Web.Mvc;
+using Ext.Direct.Mvc.Resources;
+using Newtonsoft.Json;
+
+namespace Ext.Direct.Mvc {
+
+ public class DirectAction {
+
+ private readonly Dictionary<string, DirectMethod> _methods;
+
+ public string Name {
+ get;
+ private set;
+ }
+
+ public DirectAction(Type type) {
+ Name = type.Name;
+ if (Name.EndsWith("Controller")) {
+ Name = Name.Substring(0, Name.IndexOf("Controller", StringComparison.InvariantCultureIgnoreCase));
+ }
+ _methods = new Dictionary<string, DirectMethod>();
+ Configure(type);
+ }
+
+ private void Configure(Type type) {
+ var methods = type.GetMethods()
+ .Where(x =>
+ x.IsPublic &&
+ (x.ReturnType == typeof(ActionResult) || x.ReturnType.IsSubclassOf(typeof(ActionResult))) &&
+ !x.HasAttribute<DirectIgnoreAttribute>()
+ );
+
+ foreach (MethodInfo method in methods) {
+ var directMethod = new DirectMethod(method);
+ if (_methods.ContainsKey(directMethod.Name)) {
+ throw new Exception(String.Format(DirectResources.DirectAction_MethodExists, directMethod.Name, Name));
+ }
+ _methods.Add(directMethod.Name, directMethod);
+ }
+ }
+
+ public DirectMethod GetMethod(string name) {
+ return _methods.ContainsKey(name) ? _methods[name] : null;
+ }
+
+ public void WriteJson(JsonWriter writer) {
+ writer.WritePropertyName(Name);
+ writer.WriteStartArray();
+ foreach (var method in _methods.Values) {
+ method.WriteJson(writer);
+ }
+ writer.WriteEndArray();
+ }
+ }
+}
View
18 src/Ext.Direct.Mvc/DirectApiController.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Web.Mvc;
+
+namespace Ext.Direct.Mvc {
+
+ public class DirectApiController : Controller {
+
+ private readonly DirectProvider _provider = DirectProvider.GetCurrent();
+
+ [AcceptVerbs("GET")]
+ public ActionResult Index() {
+ // for integration with the Ext Designer
+ bool json = (HttpContext.Request.QueryString["format"] == "json");
+ _provider.Name = HttpContext.Request.QueryString["name"];
+ return JavaScript(_provider.ToString(json));
+ }
+ }
+}
View
41 src/Ext.Direct.Mvc/DirectController.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Text;
+using System.Web.Mvc;
+using Newtonsoft.Json;
+
+namespace Ext.Direct.Mvc {
+
+ public class DirectController : Controller {
+
+ protected override JsonResult Json(object data, string contentType, Encoding contentEncoding) {
+ return Json(data, contentType, contentEncoding, JsonRequestBehavior.DenyGet, null);
+ }
+
+ protected override JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior) {
+ return Json(data, contentType, contentEncoding, behavior, null);
+ }
+
+ protected internal DirectResult Json(object data, params JsonConverter[] converters) {
+ return Json(data, null, converters);
+ }
+
+ protected internal DirectResult Json(object data, string contentType, params JsonConverter[] converters) {
+ return Json(data, contentType, null, converters);
+ }
+
+ protected internal DirectResult Json(object data, string contentType, Encoding contentEncoding, params JsonConverter[] converters) {
+ JsonSerializerSettings settings = (converters != null && converters.Length > 0) ? new JsonSerializerSettings { Converters = converters } : null;
+ return Json(data, contentType, contentEncoding, JsonRequestBehavior.DenyGet, settings);
+ }
+
+ protected internal virtual DirectResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior, JsonSerializerSettings settings) {
+ return new DirectResult {
+ Data = data,
+ ContentType = contentType,
+ ContentEncoding = contentEncoding,
+ Settings = settings,
+ JsonRequestBehavior = behavior
+ };
+ }
+ }
+}
View
43 src/Ext.Direct.Mvc/DirectDataResponse.cs
@@ -0,0 +1,43 @@
+using System;
+using Newtonsoft.Json;
+
+namespace Ext.Direct.Mvc {
+
+ public class DirectDataResponse : DirectResponse {
+
+ public DirectDataResponse(DirectRequest request) : base(request) {
+ TransactionId = request.TransactionId;
+ Action = request.Action;
+ Method = request.Method;
+ }
+
+ [JsonProperty("type")]
+ public virtual string Type {
+ get { return "rpc"; }
+ }
+
+ [JsonProperty("tid")]
+ public int TransactionId {
+ get;
+ set;
+ }
+
+ [JsonProperty("action")]
+ public string Action {
+ get;
+ set;
+ }
+
+ [JsonProperty("method")]
+ public string Method {
+ get;
+ set;
+ }
+
+ [JsonProperty("result", NullValueHandling = NullValueHandling.Ignore)]
+ public object Result {
+ get;
+ set;
+ }
+ }
+}
View
52 src/Ext.Direct.Mvc/DirectErrorResponse.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Collections;
+using Newtonsoft.Json;
+
+namespace Ext.Direct.Mvc {
+
+ [JsonObject]
+ public class DirectErrorResponse : DirectDataResponse {
+
+ public DirectErrorResponse(DirectRequest request, Exception exception) : base(request) {
+ ErrorMessage = exception.Message;
+ ErrorData = exception.Data.Count > 0 ? exception.Data : null;
+#if DEBUG
+ Where = GetErrorLocation(exception);
+#else
+ if (ProviderConfiguration.GetConfiguration().Debug) {
+ Where = GetErrorLocation(exception);
+ }
+#endif
+ if (request.IsFormPost) {
+ Result = new {success = false};
+ }
+ }
+
+ [JsonProperty("type")]
+ public override string Type {
+ get { return "exception"; }
+ }
+
+ [JsonProperty("message")]
+ public string ErrorMessage {
+ get;
+ private set;
+ }
+
+ [JsonProperty("errorData", NullValueHandling = NullValueHandling.Ignore)]
+ public IDictionary ErrorData {
+ get;
+ private set;
+ }
+
+ [JsonProperty("where", NullValueHandling = NullValueHandling.Ignore)]
+ public string Where {
+ get;
+ private set;
+ }
+
+ private static string GetErrorLocation(Exception exception) {
+ return String.Format("{0}\n{1}", exception.GetType(), exception.StackTrace);
+ }
+ }
+}
View
26 src/Ext.Direct.Mvc/DirectEventResponse.cs
@@ -0,0 +1,26 @@
+using Newtonsoft.Json;
+
+namespace Ext.Direct.Mvc {
+
+ public class DirectEventResponse : DirectResponse {
+
+ public DirectEventResponse(DirectRequest request) : base(request) { }
+
+ [JsonProperty("type")]
+ public string Type {
+ get { return "event"; }
+ }
+
+ [JsonProperty("name")]
+ public string Name {
+ get;
+ set;
+ }
+
+ [JsonProperty("data")]
+ public object Data {
+ get;
+ set;
+ }
+ }
+}
View
13 src/Ext.Direct.Mvc/DirectException.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace Ext.Direct.Mvc {
+
+ public class DirectException : ApplicationException {
+
+ public DirectException() { }
+
+ public DirectException(string message) : base(message) { }
+
+ public DirectException(string message, Exception innerException) : base(message, innerException) { }
+ }
+}
View
78 src/Ext.Direct.Mvc/DirectMethod.cs
@@ -0,0 +1,78 @@
+using System.Reflection;
+using System.Web.Mvc;
+using Newtonsoft.Json;
+
+namespace Ext.Direct.Mvc {
+
+ public class DirectMethod {
+
+ public string Name {
+ get;
+ private set;
+ }
+
+ public int Len {
+ get;
+ private set;
+ }
+
+ public string[] Params {
+ get;
+ private set;
+ }
+
+ public bool IsFormHandler {
+ get;
+ private set;
+ }
+
+ public bool UsesNamedArguments {
+ get;
+ private set;
+ }
+
+ public string EventName {
+ get;
+ private set;
+ }
+
+ public DirectMethod(MethodBase method) {
+ var actionNameAttr = method.GetAttribute<ActionNameAttribute>();
+ Name = actionNameAttr != null ? actionNameAttr.Name : method.Name;
+
+ var directEventAttr = method.GetAttribute<DirectEventAttribute>();
+ EventName = directEventAttr != null ? directEventAttr.Name : null;
+
+ var useNamedArgsAttr = method.GetAttribute<NamedArgumentsAttribute>();
+ if (useNamedArgsAttr == null) {
+ Len = method.GetParameters().Length;
+ } else {
+ var parameterInfos = method.GetParameters();
+ Params = new string[parameterInfos.Length];
+ for (int i = 0; i < parameterInfos.Length; i++) {
+ Params[i] = parameterInfos[i].Name;
+ }
+ }
+
+ IsFormHandler = method.HasAttribute<FormHandlerAttribute>();
+ UsesNamedArguments = method.HasAttribute<NamedArgumentsAttribute>();
+ }
+
+ public void WriteJson(JsonWriter writer) {
+ writer.WriteStartObject();
+ writer.WriteProperty("name", Name);
+
+ if (Params != null) {
+ writer.WriteProperty("params", Params);
+ } else {
+ writer.WriteProperty("len", Len);
+ }
+
+ if (IsFormHandler) {
+ writer.WriteProperty("formHandler", true);
+ }
+
+ writer.WriteEndObject();
+ }
+ }
+}
View
29 src/Ext.Direct.Mvc/DirectMethodInvoker.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Web.Mvc;
+using Ext.Direct.Mvc.Resources;
+
+namespace Ext.Direct.Mvc {
+
+ public class DirectMethodInvoker : ControllerActionInvoker {
+
+ protected override IDictionary<string, object> GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) {
+ var directRequest = controllerContext.HttpContext.Items[DirectRequest.DirectRequestKey] as DirectRequest;
+ var parametersDict = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
+ ParameterDescriptor[] parameterDescriptors = actionDescriptor.GetParameters();
+
+ if (directRequest == null) {
+ throw new NullReferenceException(DirectResources.Common_DirectRequestIsNull);
+ }
+
+ if (!directRequest.IsFormPost && directRequest.Data != null) {
+ controllerContext.Controller.ValueProvider = new DirectValueProvider(directRequest, parameterDescriptors);
+ }
+
+ foreach (ParameterDescriptor parameterDescriptor in parameterDescriptors) {
+ parametersDict[parameterDescriptor.ParameterName] = GetParameterValue(controllerContext, parameterDescriptor);
+ }
+ return parametersDict;
+ }
+ }
+}
View
214 src/Ext.Direct.Mvc/DirectProvider.cs
@@ -0,0 +1,214 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.IO;
+using System.Reflection;
+using System.Text;
+using System.Web;
+using System.Web.Compilation;
+using System.Web.Mvc;
+using System.Web.Routing;
+using Ext.Direct.Mvc.Resources;
+using Newtonsoft.Json;
+
+namespace Ext.Direct.Mvc {
+
+ public class DirectProvider {
+
+ private static DirectProvider _current;
+ private static readonly object _lockObj = new object();
+ private Dictionary<string, DirectAction> _actions;
+ private IControllerFactory _factory;
+
+ public string Name { get; set; }
+
+ public string Url {
+ get {
+ string path = HttpContext.Current.Request.ApplicationPath;
+ if (!path.EndsWith("/")) {
+ path += "/";
+ }
+ return path + "DirectRouter/Index";
+ }
+ }
+
+ public static DirectProvider GetCurrent() {
+ if (_current == null) {
+ lock (_lockObj) {
+ if (_current == null) {
+ _current = new DirectProvider();
+ _current.Configure();
+ }
+ }
+ }
+ return _current;
+ }
+
+ private void Configure() {
+ if (_actions == null) {
+ _actions = new Dictionary<string, DirectAction>();
+ var assemblies = BuildManager.GetReferencedAssemblies();
+ foreach (Assembly assembly in assemblies) {
+ var types = assembly.GetTypes().Where(type =>
+ type.IsPublic &&
+ type.IsSubclassOf(typeof(DirectController)) &&
+ !type.HasAttribute<DirectIgnoreAttribute>()
+ );
+ foreach (Type type in types) {
+ var action = new DirectAction(type);
+ if (_actions.ContainsKey(action.Name)) {
+ throw new Exception(String.Format(DirectResources.DirectProvider_ActionExists, action.Name));
+ }
+ _actions.Add(action.Name, action);
+ }
+ }
+ }
+ }
+
+ public DirectAction GetAction(string actionName) {
+ return !_actions.ContainsKey(actionName) ? null : _actions[actionName];
+ }
+
+ public DirectMethod GetMethod(string actionName, string methodName) {
+ DirectMethod method = null;
+ DirectAction action = GetAction(actionName);
+ if (action != null) {
+ method = action.GetMethod(methodName);
+ }
+ return method;
+ }
+
+ #region ToString
+
+ public override string ToString() {
+ return ToString(false);
+ }
+
+ public string ToString(bool json) {
+ var config = ProviderConfiguration.GetConfiguration();
+ var sb = new StringBuilder();
+ var sw = new StringWriter(sb);
+
+ using (var writer = new JsonTextWriter(sw)) {
+#if DEBUG
+ writer.Formatting = Formatting.Indented;
+#else
+ writer.Formatting = config.Debug ? Formatting.Indented : Formatting.None;
+#endif
+ writer.WriteStartObject();
+ writer.WriteProperty("type", "remoting");
+ writer.WriteProperty("url", Url);
+ if (json) {
+ writer.WriteProperty("descriptor", Name ?? config.Name);
+ }
+ if (!String.IsNullOrEmpty(config.Namespace)) {
+ writer.WriteProperty("namespace", config.Namespace);
+ }
+ if (config.Buffer.HasValue) {
+ writer.WriteProperty("enableBuffer", config.Buffer.Value);
+ }
+ if (config.MaxRetries.HasValue) {
+ writer.WriteProperty("maxRetries", config.MaxRetries.Value);
+ }
+ if (config.Timeout.HasValue) {
+ writer.WriteProperty("timeout", config.Timeout.Value);
+ }
+ writer.WritePropertyName("actions");
+ writer.WriteStartObject();
+ foreach (DirectAction action in _actions.Values) {
+ action.WriteJson(writer);
+ }
+ writer.WriteEndObject();
+ writer.WriteEndObject();
+ }
+
+ string name = Name ?? config.Name;
+ if (name.Contains('.')) {
+ name = String.Format("Ext.ns(\"{0}\");\n{1}", name.Substring(0, name.LastIndexOf('.')), name);
+ }
+
+ return json ? sb.ToString() : String.Format("{0}={1};", name, sb);
+ }
+
+ #endregion
+
+ #region Request execution
+
+ public void Execute(RequestContext requestContext) {
+ HttpContextBase httpContext = requestContext.HttpContext;
+ _factory = ControllerBuilder.Current.GetControllerFactory();
+
+ if (httpContext.Request.Form.Count == 0) {
+ // Raw HTTP Post request(s)
+
+ var reader = new StreamReader(httpContext.Request.InputStream, new UTF8Encoding());
+ string json = reader.ReadToEnd();
+
+ if (json.StartsWith("[") && json.EndsWith("]")) {
+ // Batch of requests
+ var requests = JsonConvert.DeserializeObject<List<DirectRequest>>(json);
+ httpContext.Response.Write("[");
+ foreach (DirectRequest request in requests) {
+ ExecuteRequest(requestContext, request);
+ if (request != requests[requests.Count - 1]) {
+ httpContext.Response.Write(",");
+ }
+ }
+ httpContext.Response.Write("]");
+ } else {
+ // Single request
+ var request = JsonConvert.DeserializeObject<DirectRequest>(json);
+ ExecuteRequest(requestContext, request);
+ }
+ } else {
+ // Form Post request
+ var request = new DirectRequest(httpContext.Request);
+ ExecuteRequest(requestContext, request);
+ }
+ }
+
+ private void ExecuteRequest(RequestContext requestContext, DirectRequest request) {
+ if (request == null) {
+ throw new ArgumentNullException("request", DirectResources.Common_DirectRequestIsNull);
+ }
+
+ HttpContextBase httpContext = requestContext.HttpContext;
+ RouteData routeData = requestContext.RouteData;
+
+ routeData.Values["controller"] = request.Action;
+ routeData.Values["action"] = request.Method;
+ httpContext.Items[DirectRequest.DirectRequestKey] = request;
+ var controller = (Controller)_factory.CreateController(requestContext, request.Action);
+
+ DirectAction action = GetAction(request.Action);
+ if (action == null) {
+ throw new NullReferenceException(String.Format(DirectResources.DirectProvider_ActionNotFound, request.Action));
+ }
+
+ DirectMethod method = action.GetMethod(request.Method);
+ if (method == null) {
+ throw new NullReferenceException(String.Format(DirectResources.DirectProvider_MethodNotFound, request.Method, action.Name));
+ }
+
+ if (!method.IsFormHandler && method.Params == null) {
+ if (request.Data == null && method.Len > 0 || request.Data != null && request.Data.Length != method.Len) {
+ throw new ArgumentException(String.Format(DirectResources.DirectProvider_WrongNumberOfArguments, request.Method, request.Action));
+ }
+ }
+
+ try {
+ controller.ActionInvoker = new DirectMethodInvoker();
+ (controller as IController).Execute(requestContext);
+ } catch (DirectException exception) {
+ var errorResponse = new DirectErrorResponse(request, exception);
+ errorResponse.Write(httpContext.Response);
+ } finally {
+ _factory.ReleaseController(controller);
+ }
+
+ httpContext.Items.Remove(DirectRequest.DirectRequestKey);
+ }
+
+ #endregion
+ }
+}
View
67 src/Ext.Direct.Mvc/DirectRequest.cs
@@ -0,0 +1,67 @@
+using System;
+using System.Web;
+using Newtonsoft.Json;
+
+namespace Ext.Direct.Mvc {
+
+ [JsonObject]
+ public class DirectRequest {
+
+ public static string DirectRequestKey = "Ext.Direct.Mvc.DirectRequest";
+
+ public const string RequestFormTransactionId = "extTID";
+ public const string RequestFormType = "extType";
+ public const string RequestFormAction = "extAction";
+ public const string RequestFormMethod = "extMethod";
+ public const string RequestFileUpload = "extUpload";
+
+ public DirectRequest() { }
+
+ public DirectRequest(HttpRequestBase httpRequest) {
+ // This constructor is called in case of Form post only
+ IsFormPost = true;
+ Action = httpRequest[RequestFormAction] ?? String.Empty;
+ Method = httpRequest[RequestFormMethod] ?? String.Empty;
+ Type = httpRequest[RequestFormType] ?? String.Empty;
+ IsFileUpload = Convert.ToBoolean(httpRequest[RequestFileUpload]);
+ TransactionId = Convert.ToInt32(httpRequest[RequestFormTransactionId]);
+ }
+
+ public string Action {
+ get;
+ set;
+ }
+
+ public string Method {
+ get;
+ set;
+ }
+
+ [JsonConverter(typeof(RequestDataConverter))]
+ public object[] Data {
+ get;
+ set;
+ }
+
+ public string Type {
+ get;
+ set;
+ }
+
+ public bool IsFormPost {
+ get;
+ set;
+ }
+
+ public bool IsFileUpload {
+ get;
+ set;
+ }
+
+ [JsonProperty("tid")]
+ public int TransactionId {
+ get;
+ set;
+ }
+ }
+}
View
79 src/Ext.Direct.Mvc/DirectResponse.cs
@@ -0,0 +1,79 @@
+using System;
+using System.IO;
+using System.Text;
+using System.Web;
+using Newtonsoft.Json;
+
+namespace Ext.Direct.Mvc {
+
+ [JsonObject]
+ public abstract class DirectResponse {
+
+ protected DirectResponse(DirectRequest request) {
+ IsFileUpload = request.IsFileUpload;
+ }
+
+ [JsonIgnore]
+ public bool IsFileUpload {
+ get;
+ private set;
+ }
+
+ [JsonIgnore]
+ public JsonSerializerSettings Settings {
+ get;
+ set;
+ }
+
+ public string ToJson() {
+ string jsonResponse;
+ JsonSerializer serializer = JsonSerializer.Create(Settings);
+
+ var converter = ProviderConfiguration.GetDefaultDateTimeConverter();
+ if (converter != null) {
+ // Default DateTime converter is added last therefore will not override the
+ // one provided by the caller.
+ serializer.Converters.Add(converter);
+ }
+
+ using (var stringWriter = new StringWriter()) {
+ using (var jsonWriter = new JsonTextWriter(stringWriter)) {
+#if DEBUG
+ jsonWriter.Formatting = Formatting.Indented;
+#else
+ jsonWriter.Formatting = ProviderConfiguration.GetConfiguration().Debug ? Formatting.Indented : Formatting.None;
+#endif
+ serializer.Serialize(jsonWriter, this);
+ jsonResponse = stringWriter.ToString();
+ }
+ }
+
+ return jsonResponse;
+ }
+
+ public void Write(HttpResponseBase httpResponse) {
+ Write(httpResponse, null, null);
+ }
+
+ public void Write(HttpResponseBase httpResponse, string contentType, Encoding contentEncoding) {
+ string jsonResponse = ToJson();
+
+ if (IsFileUpload) {
+ const string s = "<html><body><textarea>{0}</textarea></body></html>";
+ httpResponse.ContentType = "text/html";
+ httpResponse.Write(String.Format(s, jsonResponse.Replace("&quot;", "\\&quot;")));
+ } else {
+ if (!String.IsNullOrEmpty(contentType)) {
+ httpResponse.ContentType = contentType;
+ } else {
+ httpResponse.ContentType = "application/json";
+ }
+ if (contentEncoding != null) {
+ httpResponse.ContentEncoding = contentEncoding;
+ }
+
+ httpResponse.Write(jsonResponse);
+ }
+ }
+ }
+}
View
88 src/Ext.Direct.Mvc/DirectResult.cs
@@ -0,0 +1,88 @@
+using System;
+using System.Web;
+using System.Web.Mvc;
+using Ext.Direct.Mvc.Resources;
+using Newtonsoft.Json;
+
+namespace Ext.Direct.Mvc {
+
+ public class DirectResult : JsonResult {
+
+ public JsonSerializerSettings Settings {
+ get;
+ set;
+ }
+
+ public override void ExecuteResult(ControllerContext context) {
+ if (context == null) {
+ throw new ArgumentNullException("context");
+ }
+ if (JsonRequestBehavior == JsonRequestBehavior.DenyGet &&
+ String.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase)) {
+ throw new InvalidOperationException(DirectResources.JsonRequest_GetNotAllowed);
+ }
+
+ HttpResponseBase httpResponse = context.HttpContext.Response;
+ var directRequest = context.HttpContext.Items[DirectRequest.DirectRequestKey] as DirectRequest;
+
+ if (directRequest != null) {
+ WriteResponse(directRequest, httpResponse);
+ } else {
+ // Allow regular response when the action is not called through Ext Direct
+ WriteContent(httpResponse);
+ }
+ }
+
+ internal virtual void WriteResponse(DirectRequest directRequest, HttpResponseBase response) {
+ var method = DirectProvider.GetCurrent().GetMethod(directRequest.Action, directRequest.Method);
+ DirectResponse directResponse;
+
+ if (method.EventName != null) {
+ directResponse = new DirectEventResponse(directRequest) {
+ Name = method.EventName,
+ Data = Data,
+ Settings = Settings
+ };
+ } else {
+ directResponse = new DirectDataResponse(directRequest) {
+ Result = Data,
+ Settings = Settings
+ };
+ }
+
+ directResponse.Write(response, ContentType, ContentEncoding);
+ }
+
+ private void WriteContent(HttpResponseBase response) {
+ if (!String.IsNullOrEmpty(ContentType)) {
+ response.ContentType = ContentType;
+ } else {
+ response.ContentType = "application/json";
+ }
+ if (ContentEncoding != null) {
+ response.ContentEncoding = ContentEncoding;
+ }
+
+ if (Data != null) {
+ if (Data is String) {
+ // write strings directly to avoid double quotes around them caused by JsonSerializer
+ response.Write(Data);
+ } else {
+ using (JsonWriter writer = new JsonTextWriter(response.Output)) {
+ JsonSerializer serializer = JsonSerializer.Create(Settings);
+ var converter = ProviderConfiguration.GetDefaultDateTimeConverter();
+ if (converter != null) {
+ serializer.Converters.Add(converter);
+ }
+#if DEBUG
+ writer.Formatting = Formatting.Indented;
+#else
+ writer.Formatting = ProviderConfiguration.GetConfiguration().Debug ? Formatting.Indented : Formatting.None;
+#endif
+ serializer.Serialize(writer, Data);
+ }
+ }
+ }
+ }
+ }
+}
View
18 src/Ext.Direct.Mvc/DirectRouterController.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Web.Mvc;
+
+namespace Ext.Direct.Mvc {
+
+ public class DirectRouterController : Controller {
+
+ private readonly DirectProvider _provider = DirectProvider.GetCurrent();
+
+ [AcceptVerbs("POST")]
+ [ValidateInput(false)]
+ public ActionResult Index() {
+ // Process Ext.Direct requests
+ _provider.Execute(ControllerContext.RequestContext);
+ return new EmptyResult();
+ }
+ }
+}
View
83 src/Ext.Direct.Mvc/DirectValueProvider.cs
@@ -0,0 +1,83 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Web.Mvc;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+namespace Ext.Direct.Mvc {
+
+ public class DirectValueProvider : IValueProvider {
+
+ private readonly Dictionary<string, ValueProviderResult> _values = new Dictionary<string, ValueProviderResult>(StringComparer.OrdinalIgnoreCase);
+
+ public DirectValueProvider(DirectRequest directRequest, ParameterDescriptor[] parameterDescriptors) {
+ int paramCount = parameterDescriptors.Length;
+ Object[] data = directRequest.Data;
+
+ DirectMethod directMethod = DirectProvider.GetCurrent().GetMethod(directRequest.Action, directRequest.Method);
+ bool usesNamedArguments = (directMethod != null && directMethod.UsesNamedArguments);
+
+ if (paramCount > 0) {
+ if (usesNamedArguments) { // named arguments. match params by name
+ var dataObj = data[0] as JObject;
+
+ for (int i = 0; i < paramCount; i++) {
+ string pName = parameterDescriptors[i].ParameterName;
+ Type pType = parameterDescriptors[i].ParameterType;
+ JToken value = dataObj != null ? dataObj.SelectToken(pName) : null;
+ object rawValue = null;
+
+ if (value != null && value.Type != JTokenType.Null && value.Type != JTokenType.Undefined) {
+ Type vType = value.GetType();
+ if (vType == typeof(JObject) && pType != typeof(JObject) ||
+ vType == typeof(JArray) && pType != typeof(JArray)) {
+
+ rawValue = JsonConvert.DeserializeObject(value.ToString(), pType);
+ } else {
+ rawValue = Convert.ChangeType(value.ToString(), pType);
+ }
+ }
+
+ string attemptedValue = Convert.ToString(rawValue, CultureInfo.InvariantCulture);
+ _values.Add(pName, new ValueProviderResult(rawValue, attemptedValue, CultureInfo.InvariantCulture));
+ }
+ } else {
+ for (int i = 0; i < parameterDescriptors.Length; i++) {
+ object rawValue = data[i];
+
+ if (rawValue != null) {
+ Type vType = rawValue.GetType();
+ Type pType = parameterDescriptors[i].ParameterType;
+
+ // Deserialize only objects and arrays and let MVC handle everything else.
+ if (vType == typeof(JObject) && pType != typeof(JObject) ||
+ vType == typeof(JArray) && pType != typeof(JArray)) {
+
+ rawValue = JsonConvert.DeserializeObject(rawValue.ToString(), pType);
+ }
+ }
+
+ string attemptedValue = Convert.ToString(rawValue, CultureInfo.InvariantCulture);
+ _values.Add(parameterDescriptors[i].ParameterName,
+ new ValueProviderResult(rawValue, attemptedValue, CultureInfo.InvariantCulture));
+ }
+ }
+ }
+ }
+
+ public bool ContainsPrefix(string prefix) {
+ return true;
+ }
+
+ public ValueProviderResult GetValue(string key) {
+ if (key == null) {
+ throw new ArgumentNullException("key");
+ }
+
+ ValueProviderResult vpResult;
+ _values.TryGetValue(key, out vpResult);
+ return vpResult;
+ }
+ }
+}
View
BIN  src/Ext.Direct.Mvc/Ext.Direct.Mvc.snk
Binary file not shown
View
102 src/Ext.Direct.Mvc/Ext.Direct.Mvc3.csproj
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{A521832A-D1FB-468F-BA7C-1FAE0F7F45EA}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Ext.Direct.Mvc</RootNamespace>
+ <AssemblyName>Ext.Direct.Mvc</AssemblyName>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <TargetFrameworkProfile />
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <RestorePackages>true</RestorePackages>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\Mvc3\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup>
+ <SignAssembly>true</SignAssembly>
+ </PropertyGroup>
+ <PropertyGroup>
+ <AssemblyOriginatorKeyFile>Ext.Direct.Mvc.snk</AssemblyOriginatorKeyFile>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="Newtonsoft.Json">
+ <HintPath>..\..\packages\Newtonsoft.Json.4.5.10\lib\net40\Newtonsoft.Json.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.configuration" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Web" />
+ <Reference Include="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
+ <Reference Include="System.Web.Routing" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Attributes\DirectEventAttribute.cs" />
+ <Compile Include="Attributes\DirectHandleErrorAttribute.cs" />
+ <Compile Include="Attributes\DirectIgnoreAttribute.cs" />
+ <Compile Include="Attributes\FormHandlerAttribute.cs" />
+ <Compile Include="Attributes\NamedArgumentsAttributes.cs" />
+ <Compile Include="DirectAction.cs" />
+ <Compile Include="DirectApiController.cs" />
+ <Compile Include="DirectController.cs" />
+ <Compile Include="DirectDataResponse.cs" />
+ <Compile Include="DirectErrorResponse.cs" />
+ <Compile Include="DirectEventResponse.cs" />
+ <Compile Include="DirectException.cs" />
+ <Compile Include="DirectMethod.cs" />
+ <Compile Include="DirectMethodInvoker.cs" />
+ <Compile Include="DirectProvider.cs" />
+ <Compile Include="DirectRequest.cs" />
+ <Compile Include="DirectResponse.cs" />
+ <Compile Include="DirectResult.cs" />
+ <Compile Include="DirectRouterController.cs" />
+ <Compile Include="DirectValueProvider.cs" />
+ <Compile Include="Extensions\JsonExtensions.cs" />
+ <Compile Include="Extensions\MethodExtensions.cs" />
+ <Compile Include="Extensions\TypeExtensions.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="ProviderConfiguration.cs" />
+ <Compile Include="RequestDataConverter.cs" />
+ <Compile Include="Resources\DirectResources.Designer.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="Resources\DirectResources.resx" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Ext.Direct.Mvc.snk" />
+ <None Include="packages.config" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(SolutionDir)\.nuget\nuget.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
View
12 src/Ext.Direct.Mvc/Extensions/JsonExtensions.cs
@@ -0,0 +1,12 @@
+using Newtonsoft.Json;
+
+namespace Ext.Direct.Mvc {
+
+ internal static class JsonExtensions {
+
+ internal static void WriteProperty<T>(this JsonWriter jsonWriter, string name, T value) {
+ jsonWriter.WritePropertyName(name);
+ jsonWriter.WriteRawValue(JsonConvert.SerializeObject(value));
+ }
+ }
+}
View
22 src/Ext.Direct.Mvc/Extensions/MethodExtensions.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Reflection;
+
+namespace Ext.Direct.Mvc {
+
+ internal static class MethodExtensions {
+
+ internal static bool HasAttribute<T>(this MethodBase method) where T : Attribute {
+ T attribute = method.GetAttribute<T>();
+ return attribute != null;
+ }
+
+ internal static T GetAttribute<T>(this MethodBase method) where T : Attribute {
+ T attribute = null;
+ var attributes = (T[])method.GetCustomAttributes(typeof(T), true);
+ if (attributes.Length > 0) {
+ attribute = attributes[0];
+ }
+ return attribute;
+ }
+ }
+}
View
21 src/Ext.Direct.Mvc/Extensions/TypeExtensions.cs
@@ -0,0 +1,21 @@
+using System;
+
+namespace Ext.Direct.Mvc {
+
+ internal static class TypeExtensions {
+
+ internal static bool HasAttribute<T>(this Type type) where T : Attribute {
+ T attribute = type.GetAttribute<T>();
+ return attribute != null;
+ }
+
+ internal static T GetAttribute<T>(this Type type) where T : Attribute {
+ T attribute = null;
+ var attributes = (T[])type.GetCustomAttributes(typeof(T), true);
+ if (attributes.Length > 0) {
+ attribute = attributes[0];
+ }
+ return attribute;
+ }
+ }
+}
View
36 src/Ext.Direct.Mvc/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Ext.Direct.Mvc")]
+[assembly: AssemblyDescription("Ext.Direct server-side stack for ASP.NET MVC")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Ext.Direct.Mvc")]
+[assembly: AssemblyCopyright("Copyright © 2012 Eugene Lishnevsky")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("27285a57-6192-44cd-aeaa-cd6ebba7b5ef")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("3.0.0.0")]
+[assembly: AssemblyFileVersion("3.0.0.0")]
View
81 src/Ext.Direct.Mvc/ProviderConfiguration.cs
@@ -0,0 +1,81 @@
+using System;
+using System.Configuration;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Converters;
+
+namespace Ext.Direct.Mvc {
+
+ public class ProviderConfiguration : ConfigurationSection {
+
+ private static ProviderConfiguration _configuration;
+
+ public static ProviderConfiguration GetConfiguration() {
+ if (_configuration == null) {
+ _configuration = ConfigurationManager.GetSection("ext.direct") as ProviderConfiguration;
+ }
+ return _configuration ?? (_configuration = new ProviderConfiguration());
+ }
+
+ public static JsonConverter GetDefaultDateTimeConverter() {
+ string dateFormat = GetConfiguration().DateFormat;
+ JsonConverter converter;
+ switch (dateFormat.ToLower()) {
+ case "js":
+ case "javascript":
+ converter = new JavaScriptDateTimeConverter();
+ break;
+ case "iso":
+ converter = new IsoDateTimeConverter();
+ break;
+ default:
+ converter = null;
+ break;
+ }
+ return converter;
+ }
+
+ [ConfigurationProperty("name", IsRequired = false, DefaultValue = "Ext.app.REMOTING_API")]
+ public string Name {
+ get { return (string)this["name"]; }
+ }
+
+ // Optional namespace for generated proxy methods.
+ [ConfigurationProperty("namespace", IsRequired = false)]
+ public string Namespace {
+ get { return (string)this["namespace"]; }
+ }
+
+ // Number that specifies the amount of time in milliseconds to wait before sending a batched request.
+ // If not specified then the default value, configured by Ext JS will be used, which is 10
+ [ConfigurationProperty("buffer", IsRequired = false, DefaultValue = null)]
+ public int? Buffer {
+ get { return (int?)this["buffer"]; }
+ }
+
+ // Number of times to re-attempt delivery on failure of a call.
+ // If not specified then the default value, configured by Ext JS will be used, which is 1
+ [ConfigurationProperty("maxRetries", IsRequired = false, DefaultValue = null)]
+ public int? MaxRetries {
+ get { return (int?)this["maxRetries"]; }
+ }
+
+ // The timeout to use for each request.
+ // If not specified then the default value, configured by Ext JS will be used, which is I don't remember
+ [ConfigurationProperty("timeout", IsRequired = false, DefaultValue = null)]
+ public int? Timeout {
+ get { return (int?)this["timeout"]; }
+ }
+
+ // The format in which DateTime objects should be returned. Valid values are "Iso", "JS" or "JavaScript". All case insensitive.
+ [ConfigurationProperty("dateFormat", IsRequired = false, DefaultValue = "Iso")]
+ public string DateFormat {
+ get { return (string)this["dateFormat"]; }
+ }
+
+ // Turns debug mode on if set to true. For development only! Set it to false on production environment.
+ [ConfigurationProperty("debug", IsRequired = false, DefaultValue = false)]
+ public bool Debug {
+ get { return (bool)this["debug"]; }
+ }
+ }
+}
View
39 src/Ext.Direct.Mvc/RequestDataConverter.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+namespace Ext.Direct.Mvc {
+
+ internal class RequestDataConverter : JsonConverter {
+ public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
+ var data = new List<object>();
+ JToken dataArray = JToken.ReadFrom(reader);
+
+ if (!dataArray.HasValues) return null;
+
+ if (dataArray is JObject) {
+ data.Add(dataArray);
+ } else {
+ foreach (JToken dataItem in dataArray) {
+ if (dataItem is JValue) {
+ var value = (dataItem as JValue).Value;
+ data.Add(value == null ? null : value.ToString());
+ } else {
+ data.Add(dataItem);
+ }
+ }
+ }
+
+ return data.ToArray();
+ }
+
+ public override bool CanConvert(Type objectType) {
+ return true;
+ }
+
+ public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
+ throw new NotImplementedException();
+ }
+ }
+}
View
135 src/Ext.Direct.Mvc/Resources/DirectResources.Designer.cs
@@ -0,0 +1,135 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.261
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Ext.Direct.Mvc.Resources {
+ using System;
+
+
+ /// <summary>
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ /// </summary>
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class DirectResources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal DirectResources() {
+ }
+
+ /// <summary>
+ /// Returns the cached ResourceManager instance used by this class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Ext.Direct.Mvc.Resources.DirectResources", typeof(DirectResources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ /// <summary>
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to DirectRequest is null. Check that POST parameters were passed..
+ /// </summary>
+ internal static string Common_DirectRequestIsNull {
+ get {
+ return ResourceManager.GetString("Common_DirectRequestIsNull", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Value cannot be null or empty..
+ /// </summary>
+ internal static string Common_NullOrEmpty {
+ get {
+ return ResourceManager.GetString("Common_NullOrEmpty", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Method {0} has already been configured for action {1}..
+ /// </summary>
+ internal static string DirectAction_MethodExists {
+ get {
+ return ResourceManager.GetString("DirectAction_MethodExists", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Action {0} has already been configured..
+ /// </summary>
+ internal static string DirectProvider_ActionExists {
+ get {
+ return ResourceManager.GetString("DirectProvider_ActionExists", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Unable to find action {0}..
+ /// </summary>
+ internal static string DirectProvider_ActionNotFound {
+ get {
+ return ResourceManager.GetString("DirectProvider_ActionNotFound", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Unable to find method {0} in action {1}..
+ /// </summary>
+ internal static string DirectProvider_MethodNotFound {
+ get {
+ return ResourceManager.GetString("DirectProvider_MethodNotFound", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Number of arguments does not match the definition of method {0} in action {1}..
+ /// </summary>
+ internal static string DirectProvider_WrongNumberOfArguments {
+ get {
+ return ResourceManager.GetString("DirectProvider_WrongNumberOfArguments", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet..
+ /// </summary>
+ internal static string JsonRequest_GetNotAllowed {
+ get {
+ return ResourceManager.GetString("JsonRequest_GetNotAllowed", resourceCulture);
+ }
+ }
+ }
+}
View
144 src/Ext.Direct.Mvc/Resources/DirectResources.resx
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <data name="Common_DirectRequestIsNull" xml:space="preserve">
+ <value>DirectRequest is null. Check that POST parameters were passed.</value>
+ </data>
+ <data name="Common_NullOrEmpty" xml:space="preserve">
+ <value>Value cannot be null or empty.</value>
+ </data>
+ <data name="DirectAction_MethodExists" xml:space="preserve">
+ <value>Method {0} has already been configured for action {1}.</value>
+ </data>
+ <data name="DirectProvider_ActionExists" xml:space="preserve">
+ <value>Action {0} has already been configured.</value>
+ </data>
+ <data name="DirectProvider_ActionNotFound" xml:space="preserve">
+ <value>Unable to find action {0}.</value>
+ </data>
+ <data name="DirectProvider_MethodNotFound" xml:space="preserve">
+ <value>Unable to find method {0} in action {1}.</value>
+ </data>
+ <data name="DirectProvider_WrongNumberOfArguments" xml:space="preserve">
+ <value>Number of arguments does not match the definition of method {0} in action {1}.</value>
+ </data>
+ <data name="JsonRequest_GetNotAllowed" xml:space="preserve">
+ <value>This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet.</value>
+ </data>
+</root>
View
4 src/Ext.Direct.Mvc/packages.config
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="Newtonsoft.Json" version="4.5.10" targetFramework="net40" />
+</packages>
View
19 test/Ext.Direct.Mvc3Test/Controllers/BasicController.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web;
+using System.Web.Mvc;
+using Ext.Direct.Mvc;
+
+namespace Ext.Direct.Mvc3Test.Controllers {
+
+ public class BasicController : DirectController {
+
+ public ActionResult Echo(string text, DateTime date) {
+ return Json(new {
+ text,
+ date
+ });
+ }
+ }
+}
View
16 test/Ext.Direct.Mvc3Test/Controllers/HomeController.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web;
+using System.Web.Mvc;
+
+namespace Ext.Direct.Mvc3Test.Controllers {
+
+ public class HomeController : Controller {
+
+ // GET: /Index/
+ public ActionResult Index() {
+ return View();
+ }
+ }
+}
View
138 test/Ext.Direct.Mvc3Test/Ext.Direct.Mvc3Test.csproj
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>
+ </ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{D689FA7E-74DC-477B-A69F-EA6FF4C7739B}</ProjectGuid>
+ <ProjectTypeGuids>{E53F8FEA-EAE0-44A6-8774-FFD645390401};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Ext.Direct.Mvc3Test</RootNamespace>
+ <AssemblyName>Ext.Direct.Mvc3Test</AssemblyName>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <MvcBuildViews>false</MvcBuildViews>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>4.0</OldToolsVersion>
+ <UseIISExpress>true</UseIISExpress>
+ <IISExpressSSLPort />
+ <IISExpressAnonymousAuthentication />
+ <IISExpressWindowsAuthentication />
+ <IISExpressUseClassicPipelineMode />
+ <UpgradeBackupLocation />
+ <TargetFrameworkProfile />
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <RestorePackages>true</RestorePackages>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="Newtonsoft.Json">
+ <HintPath>..\..\packages\Newtonsoft.Json.4.5.10\lib\net40\Newtonsoft.Json.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="System.Web.Extensions" />
+ <Reference Include="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
+ <Reference Include="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
+ <Reference Include="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Web.DynamicData" />
+ <Reference Include="System.Web.Entity" />
+ <Reference Include="System.Web.ApplicationServices" />
+ <Reference Include="System.ComponentModel.DataAnnotations" />
+ <Reference Include="System.Web" />
+ <Reference Include="System.Web.Abstractions" />
+ <Reference Include="System.Web.Routing" />
+ <Reference Include="System.Xml" />
+ <Reference Include="System.Configuration" />
+ <Reference Include="System.Web.Services" />
+ <Reference Include="System.EnterpriseServices" />
+ <Reference Include="System.Xml.Linq" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Controllers\BasicController.cs" />
+ <Compile Include="Controllers\HomeController.cs" />
+ <Compile Include="Global.asax.cs">
+ <DependentUpon>Global.asax</DependentUpon>
+ </Compile>
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="Global.asax" />
+ <Content Include="Web.config" />
+ <Content Include="Views\Web.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\src\Ext.Direct.Mvc\Ext.Direct.Mvc3.csproj">
+ <Project>{a521832a-d1fb-468f-ba7c-1fae0f7f45ea}</Project>
+ <Name>Ext.Direct.Mvc3</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="packages.config" />
+ <Content Include="Views\Home\Index.cshtml" />
+ <None Include="Web.Debug.config">
+ <DependentUpon>Web.config</DependentUpon>
+ </None>
+ <None Include="Web.Release.config">
+ <DependentUpon>Web.config</DependentUpon>
+ </None>
+ </ItemGroup>
+ <PropertyGroup>
+ <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
+ <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
+ </PropertyGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
+ <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target> -->
+ <Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
+ <AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
+ </Target>
+ <ProjectExtensions>
+ <VisualStudio>
+ <FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
+ <WebProjectProperties>
+ <UseIIS>True</UseIIS>
+ <AutoAssignPort>True</AutoAssignPort>
+ <DevelopmentServerPort>0</DevelopmentServerPort>
+ <DevelopmentServerVPath>/</DevelopmentServerVPath>
+ <IISUrl>http://localhost:59908/</IISUrl>
+ <NTLMAuthentication>False</NTLMAuthentication>
+ <UseCustomServer>False</UseCustomServer>
+ <CustomServerUrl>
+ </CustomServerUrl>
+ <SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
+ </WebProjectProperties>
+ </FlavorProperties>
+ </VisualStudio>
+ </ProjectExtensions>
+ <Import Project="$(SolutionDir)\.nuget\nuget.targets" />
+</Project>
View
1  test/Ext.Direct.Mvc3Test/Global.asax
@@ -0,0 +1 @@
+<%@ Application Codebehind="Global.asax.cs" Inherits="Ext.Direct.Mvc3Test.MvcApplication" Language="C#" %>
View
30 test/Ext.Direct.Mvc3Test/Global.asax.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web;
+using System.Web.Mvc;
+using System.Web.Routing;
+
+namespace Ext.Direct.Mvc3Test {
+ // Note: For instructions on enabling IIS6 or IIS7 classic mode,
+ // visit http://go.microsoft.com/?LinkId=9394801
+
+ public class MvcApplication : System.Web.HttpApplication {
+ public static void RegisterRoutes(RouteCollection routes) {
+ routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
+
+ routes.MapRoute(
+ "Default", // Route name
+ "{controller}/{action}/{id}", // URL with parameters
+ new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
+ );
+
+ }
+
+ protected void Application_Start() {
+ AreaRegistration.RegisterAllAreas();
+
+ RegisterRoutes(RouteTable.Routes);
+ }
+ }
+}
View
19 test/Ext.Direct.Mvc3Test/Properties/AssemblyInfo.cs
@@ -0,0 +1,19 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Ext.Direct.Mvc3Test")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Ext.Direct.Mvc3Test")]
+[assembly: AssemblyCopyright("Copyright © 2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: ComVisible(false)]
+
+[assembly: Guid("20e8af73-00de-4998-b20f-3d0402c2dc74")]
+
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
View
31 test/Ext.Direct.Mvc3Test/Views/Home/Index.cshtml
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Ext.Direct.Mvc Test Page</title>
+ <link href="http://cdn.sencha.io/ext-3.4.0/resources/css/ext-all.css" rel="stylesheet" type="text/css" />
+ <script type="text/javascript" src="http://cdn.sencha.io/ext-3.4.0/adapter/ext/ext-base.js"></script>
+ <script type="text/javascript" src="http://cdn.sencha.io/ext-3.4.0/ext-all.js"></script>
+ <script type="text/javascript" src="@Url.Content("~/directapi")"></script>
+ <script type="text/javascript">
+ Ext.onReady(function () {
+ Ext.BLANK_IMAGE_URL = 'http://cdn.sencha.io/ext-3.4.0/resources/images/default/s.gif';
+ Ext.Direct.addProvider(Ext.app.REMOTING_API);
+ Ext.QuickTips.init();
+
+ Ext.fly('testButton').on('click', function () {
+ Basic.Echo("lorem ipsum dolor sit amet", new Date(), function (result, event) {
+ if (event.status == true) {
+ var date = Date.parseDate(result.date, 'c').format('l, F d, Y g:i:s A');
+ console.log(result.text, date);
+ }
+ });
+ });
+ });
+ </script>
+</head>
+<body>
+ <div style="margin:20px">
+ <input type="button" value="Test Button" id="testButton"/>
+ </div>
+</body>
+</html>
View
58 test/Ext.Direct.Mvc3Test/Views/Web.config
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+
+<configuration>
+ <configSections>
+ <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
+ <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
+ <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
+ </sectionGroup>
+ </configSections>
+
+ <system.web.webPages.razor>
+ <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
+ <pages pageBaseType="System.Web.Mvc.WebViewPage">
+ <namespaces>
+ <add namespace="System.Web.Mvc" />
+ <add namespace="System.Web.Mvc.Ajax" />
+ <add namespace="System.Web.Mvc.Html" />
+ <add namespace="System.Web.Routing" />
+ </namespaces>
+ </pages>
+ </system.web.webPages.razor>
+
+ <appSettings>
+ <add key="webpages:Enabled" value="false" />
+ </appSettings>
+
+ <system.web>
+ <httpHandlers>
+ <add path="*" verb="*" type="System.Web.HttpNotFoundHandler"/>
+ </httpHandlers>
+
+ <!--
+ Enabling request validation in view pages would cause validation to occur
+ after the input has already been processed by the controller. By default
+ MVC performs request validation before a controller processes the input.
+ To change this behavior apply the ValidateInputAttribute to a
+ controller or action.
+ -->
+ <pages
+ validateRequest="false"
+ pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
+ pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
+ userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
+ <controls>
+ <add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" tagPrefix="mvc" />
+ </controls>
+ </pages>
+ </system.web>
+
+ <system.webServer>
+ <validation validateIntegratedModeConfiguration="false" />
+
+ <handlers>
+ <remove name="BlockViewHandler"/>
+ <add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
+ </handlers>
+ </system.webServer>
+</configuration>
View
30 test/Ext.Direct.Mvc3Test/Web.Debug.config
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- For more information on using web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=125889 -->
+
+<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
+ <!--
+ In the example below, the "SetAttributes" transform will change the value of
+ "connectionString" to use "ReleaseSQLServer" only when the "Match" locator
+ finds an attribute "name" that has a value of "MyDB".
+
+ <connectionStrings>
+ <add name="MyDB"
+ connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
+ xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
+ </connectionStrings>
+ -->
+ <system.web>
+ <!--
+ In the example below, the "Replace" transform will replace the entire
+ <customErrors> section of your web.config file.
+ Note that because there is only one customErrors section under the
+ <system.web> node, there is no need to use the "xdt:Locator" attribute.
+
+ <customErrors defaultRedirect="GenericError.htm"
+ mode="RemoteOnly" xdt:Transform="Replace">
+ <error statusCode="500" redirect="InternalError.htm"/>
+ </customErrors>
+ -->
+ </system.web>
+</configuration>
View
31 test/Ext.Direct.Mvc3Test/Web.Release.config
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- For more information on using web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=125889 -->
+
+<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
+ <!--
+ In the example below, the "SetAttributes" transform will change the value of
+ "connectionString" to use "ReleaseSQLServer" only when the "Match" locator
+ finds an attribute "name" that has a value of "MyDB".
+
+ <connectionStrings>
+ <add name="MyDB"
+ connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
+ xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
+ </connectionStrings>
+ -->
+ <system.web>
+ <compilation xdt:Transform="RemoveAttributes(debug)" />
+