THRIFT-3510 Add HttpTaskAsyncHandler implementation
Client: C#
Author: Adam Connelly <adam.rpconnelly@gmail.com>
This closes #762
diff --git a/.gitignore b/.gitignore
index 957dc9f..922ac4d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -143,6 +143,7 @@
/lib/c_glib/thrift_c_glib.pc
/lib/csharp/**/bin/
/lib/csharp/**/obj/
+/lib/csharp/src/packages
/lib/d/libthriftd.a
/lib/d/test/serialization_benchmark
/lib/d/test/transport_test
diff --git a/compiler/cpp/src/generate/t_csharp_generator.cc b/compiler/cpp/src/generate/t_csharp_generator.cc
index 629b310..aae595d 100644
--- a/compiler/cpp/src/generate/t_csharp_generator.cc
+++ b/compiler/cpp/src/generate/t_csharp_generator.cc
@@ -140,10 +140,18 @@
void generate_function_helpers(t_function* tfunction);
void generate_service_interface(t_service* tservice);
+ void generate_separate_service_interfaces(t_service* tservice);
+ void generate_sync_service_interface(t_service* tservice);
+ void generate_async_service_interface(t_service* tservice);
+ void generate_combined_service_interface(t_service* tservice);
+ void generate_silverlight_async_methods(t_service* tservice);
void generate_service_helpers(t_service* tservice);
void generate_service_client(t_service* tservice);
void generate_service_server(t_service* tservice);
+ void generate_service_server_sync(t_service* tservice);
+ void generate_service_server_async(t_service* tservice);
void generate_process_function(t_service* tservice, t_function* function);
+ void generate_process_function_async(t_service* tservice, t_function* function);
void generate_deserialize_field(std::ofstream& out,
t_field* tfield,
@@ -1422,11 +1430,25 @@
}
void t_csharp_generator::generate_service_interface(t_service* tservice) {
+ generate_separate_service_interfaces(tservice);
+}
+
+void t_csharp_generator::generate_separate_service_interfaces(t_service* tservice) {
+ generate_sync_service_interface(tservice);
+
+ if (async_ || async_ctp_) {
+ generate_async_service_interface(tservice);
+ }
+
+ generate_combined_service_interface(tservice);
+}
+
+void t_csharp_generator::generate_sync_service_interface(t_service* tservice) {
string extends = "";
string extends_iface = "";
if (tservice->get_extends() != NULL) {
extends = type_name(tservice->get_extends());
- extends_iface = " : " + extends + ".Iface";
+ extends_iface = " : " + extends + ".ISync";
}
generate_csharp_doc(f_service_, tservice);
@@ -1434,7 +1456,7 @@
if (wcf_) {
indent(f_service_) << "[ServiceContract(Namespace=\"" << wcf_namespace_ << "\")]" << endl;
}
- indent(f_service_) << "public interface Iface" << extends_iface << " {" << endl;
+ indent(f_service_) << "public interface ISync" << extends_iface << " {" << endl;
indent_up();
vector<t_function*> functions = tservice->get_functions();
@@ -1450,25 +1472,102 @@
vector<t_field*>::const_iterator x_iter;
for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
indent(f_service_) << "[FaultContract(typeof("
- + type_name((*x_iter)->get_type(), false, false) + "Fault))]" << endl;
+ + type_name((*x_iter)->get_type(), false, false) + "Fault))]" << endl;
}
}
indent(f_service_) << function_signature(*f_iter) << ";" << endl;
+ }
+ indent_down();
+ f_service_ << indent() << "}" << endl << endl;
+}
+
+void t_csharp_generator::generate_async_service_interface(t_service* tservice) {
+ string extends = "";
+ string extends_iface = "";
+ if (tservice->get_extends() != NULL) {
+ extends = type_name(tservice->get_extends());
+ extends_iface = " : " + extends + ".IAsync";
+ }
+
+ generate_csharp_doc(f_service_, tservice);
+
+ if (wcf_) {
+ indent(f_service_) << "[ServiceContract(Namespace=\"" << wcf_namespace_ << "\")]" << endl;
+ }
+ indent(f_service_) << "public interface IAsync" << extends_iface << " {" << endl;
+
+ indent_up();
+ vector<t_function*> functions = tservice->get_functions();
+ vector<t_function*>::iterator f_iter;
+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
+ generate_csharp_doc(f_service_, *f_iter);
+
+ // if we're using WCF, add the corresponding attributes
+ if (wcf_) {
+ indent(f_service_) << "[OperationContract]" << endl;
+
+ const std::vector<t_field*>& xceptions = (*f_iter)->get_xceptions()->get_members();
+ vector<t_field*>::const_iterator x_iter;
+ for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
+ indent(f_service_) << "[FaultContract(typeof("
+ + type_name((*x_iter)->get_type(), false, false) + "Fault))]" << endl;
+ }
+ }
+
+ indent(f_service_) << function_signature_async(*f_iter) << ";" << endl;
+ }
+ indent_down();
+ f_service_ << indent() << "}" << endl << endl;
+}
+
+void t_csharp_generator::generate_combined_service_interface(t_service* tservice) {
+ string extends_iface = " : ISync";
+
+ if (async_ || async_ctp_) {
+ extends_iface += ", IAsync";
+ }
+
+ generate_csharp_doc(f_service_, tservice);
+
+ if (wcf_) {
+ indent(f_service_) << "[ServiceContract(Namespace=\"" << wcf_namespace_ << "\")]" << endl;
+ }
+
+ indent(f_service_) << "public interface Iface" << extends_iface << " {" << endl;
+
+ indent_up();
+
+ // We need to generate extra old style async methods for silverlight. Since
+ // this isn't something you'd want to implement server-side, just put them into
+ // the main Iface interface.
+ generate_silverlight_async_methods(tservice);
+
+ indent_down();
+
+ f_service_ << indent() << "}" << endl << endl;
+}
+
+void t_csharp_generator::generate_silverlight_async_methods(t_service* tservice) {
+ vector<t_function*> functions = tservice->get_functions();
+ vector<t_function*>::iterator f_iter;
+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
+ generate_csharp_doc(f_service_, *f_iter);
+
+ // For backwards compatibility, include the Begin_, End_ methods if we're generating
+ // with the async flag. I'm not sure this is necessary, so someone with more knowledge
+ // can maybe remove these checks if they know it's safe.
if (!async_) {
indent(f_service_) << "#if SILVERLIGHT" << endl;
}
+
indent(f_service_) << function_signature_async_begin(*f_iter, "Begin_") << ";" << endl;
indent(f_service_) << function_signature_async_end(*f_iter, "End_") << ";" << endl;
- if (async_ || async_ctp_) {
- indent(f_service_) << function_signature_async(*f_iter) << ";" << endl;
- }
+
if (!async_) {
indent(f_service_) << "#endif" << endl;
}
}
- indent_down();
- f_service_ << indent() << "}" << endl << endl;
}
void t_csharp_generator::generate_service_helpers(t_service* tservice) {
@@ -1823,6 +1922,16 @@
}
void t_csharp_generator::generate_service_server(t_service* tservice) {
+ if (async_) {
+ generate_service_server_async(tservice);
+ generate_service_server_sync(tservice);
+ }
+ else {
+ generate_service_server_sync(tservice);
+ }
+}
+
+void t_csharp_generator::generate_service_server_sync(t_service* tservice) {
vector<t_function*> functions = tservice->get_functions();
vector<t_function*>::iterator f_iter;
@@ -1836,7 +1945,8 @@
indent(f_service_) << "public class Processor : " << extends_processor << "TProcessor {" << endl;
indent_up();
- indent(f_service_) << "public Processor(Iface iface)";
+ indent(f_service_) << "public Processor(ISync iface)";
+
if (!extends.empty()) {
f_service_ << " : base(iface)";
}
@@ -1846,7 +1956,7 @@
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
f_service_ << indent() << "processMap_[\"" << (*f_iter)->get_name()
- << "\"] = " << (*f_iter)->get_name() << "_Process;" << endl;
+ << "\"] = " << (*f_iter)->get_name() << "_Process;" << endl;
}
scope_down(f_service_);
@@ -1854,23 +1964,24 @@
if (extends.empty()) {
f_service_
- << indent()
- << "protected delegate void ProcessFunction(int seqid, TProtocol iprot, TProtocol oprot);"
- << endl;
+ << indent()
+ << "protected delegate void ProcessFunction(int seqid, TProtocol iprot, TProtocol oprot);"
+ << endl;
}
- f_service_ << indent() << "private Iface iface_;" << endl;
+ f_service_ << indent() << "private ISync iface_;" << endl;
if (extends.empty()) {
f_service_ << indent() << "protected Dictionary<string, ProcessFunction> processMap_ = new "
- "Dictionary<string, ProcessFunction>();" << endl;
+ "Dictionary<string, ProcessFunction>();" << endl;
}
f_service_ << endl;
if (extends.empty()) {
indent(f_service_) << "public bool Process(TProtocol iprot, TProtocol oprot)" << endl;
- } else {
+ }
+ else {
indent(f_service_) << "public new bool Process(TProtocol iprot, TProtocol oprot)" << endl;
}
scope_up(f_service_);
@@ -1881,17 +1992,17 @@
f_service_ << indent() << "TMessage msg = iprot.ReadMessageBegin();" << endl;
f_service_
- << indent() << "ProcessFunction fn;" << endl << indent()
- << "processMap_.TryGetValue(msg.Name, out fn);" << endl << indent() << "if (fn == null) {"
- << endl << indent() << " TProtocolUtil.Skip(iprot, TType.Struct);" << endl << indent()
- << " iprot.ReadMessageEnd();" << endl << indent()
- << " TApplicationException x = new TApplicationException "
- "(TApplicationException.ExceptionType.UnknownMethod, \"Invalid method name: '\" + "
- "msg.Name + \"'\");" << endl << indent()
- << " oprot.WriteMessageBegin(new TMessage(msg.Name, TMessageType.Exception, msg.SeqID));"
- << endl << indent() << " x.Write(oprot);" << endl << indent() << " oprot.WriteMessageEnd();"
- << endl << indent() << " oprot.Transport.Flush();" << endl << indent() << " return true;"
- << endl << indent() << "}" << endl << indent() << "fn(msg.SeqID, iprot, oprot);" << endl;
+ << indent() << "ProcessFunction fn;" << endl << indent()
+ << "processMap_.TryGetValue(msg.Name, out fn);" << endl << indent() << "if (fn == null) {"
+ << endl << indent() << " TProtocolUtil.Skip(iprot, TType.Struct);" << endl << indent()
+ << " iprot.ReadMessageEnd();" << endl << indent()
+ << " TApplicationException x = new TApplicationException "
+ "(TApplicationException.ExceptionType.UnknownMethod, \"Invalid method name: '\" + "
+ "msg.Name + \"'\");" << endl << indent()
+ << " oprot.WriteMessageBegin(new TMessage(msg.Name, TMessageType.Exception, msg.SeqID));"
+ << endl << indent() << " x.Write(oprot);" << endl << indent() << " oprot.WriteMessageEnd();"
+ << endl << indent() << " oprot.Transport.Flush();" << endl << indent() << " return true;"
+ << endl << indent() << "}" << endl << indent() << "fn(msg.SeqID, iprot, oprot);" << endl;
scope_down(f_service_);
@@ -1913,6 +2024,98 @@
indent(f_service_) << "}" << endl << endl;
}
+void t_csharp_generator::generate_service_server_async(t_service* tservice) {
+ vector<t_function*> functions = tservice->get_functions();
+ vector<t_function*>::iterator f_iter;
+
+ string extends = "";
+ string extends_processor = "";
+ if (tservice->get_extends() != NULL) {
+ extends = type_name(tservice->get_extends());
+ extends_processor = extends + ".Processor, ";
+ }
+
+ indent(f_service_) << "public class AsyncProcessor : " << extends_processor << "TAsyncProcessor {" << endl;
+ indent_up();
+
+ indent(f_service_) << "public AsyncProcessor(IAsync iface)";
+ if (!extends.empty()) {
+ f_service_ << " : base(iface)";
+ }
+ f_service_ << endl;
+ scope_up(f_service_);
+ f_service_ << indent() << "iface_ = iface;" << endl;
+
+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
+ f_service_ << indent() << "processMap_[\"" << (*f_iter)->get_name()
+ << "\"] = " << (*f_iter)->get_name() << "_ProcessAsync;" << endl;
+ }
+
+ scope_down(f_service_);
+ f_service_ << endl;
+
+ if (extends.empty()) {
+ f_service_
+ << indent()
+ << "protected delegate Task ProcessFunction(int seqid, TProtocol iprot, TProtocol oprot);"
+ << endl;
+ }
+
+ f_service_ << indent() << "private IAsync iface_;" << endl;
+
+ if (extends.empty()) {
+ f_service_ << indent() << "protected Dictionary<string, ProcessFunction> processMap_ = new "
+ "Dictionary<string, ProcessFunction>();" << endl;
+ }
+
+ f_service_ << endl;
+
+ if (extends.empty()) {
+ indent(f_service_) << "public async Task<bool> ProcessAsync(TProtocol iprot, TProtocol oprot)" << endl;
+ }
+ else {
+ indent(f_service_) << "public new async Task<bool> ProcessAsync(TProtocol iprot, TProtocol oprot)" << endl;
+ }
+ scope_up(f_service_);
+
+ f_service_ << indent() << "try" << endl;
+ scope_up(f_service_);
+
+ f_service_ << indent() << "TMessage msg = iprot.ReadMessageBegin();" << endl;
+
+ f_service_
+ << indent() << "ProcessFunction fn;" << endl << indent()
+ << "processMap_.TryGetValue(msg.Name, out fn);" << endl << indent() << "if (fn == null) {"
+ << endl << indent() << " TProtocolUtil.Skip(iprot, TType.Struct);" << endl << indent()
+ << " iprot.ReadMessageEnd();" << endl << indent()
+ << " TApplicationException x = new TApplicationException "
+ "(TApplicationException.ExceptionType.UnknownMethod, \"Invalid method name: '\" + "
+ "msg.Name + \"'\");" << endl << indent()
+ << " oprot.WriteMessageBegin(new TMessage(msg.Name, TMessageType.Exception, msg.SeqID));"
+ << endl << indent() << " x.Write(oprot);" << endl << indent() << " oprot.WriteMessageEnd();"
+ << endl << indent() << " oprot.Transport.Flush();" << endl << indent() << " return true;"
+ << endl << indent() << "}" << endl << indent() << "await fn(msg.SeqID, iprot, oprot);" << endl;
+
+ scope_down(f_service_);
+
+ f_service_ << indent() << "catch (IOException)" << endl;
+ scope_up(f_service_);
+ f_service_ << indent() << "return false;" << endl;
+ scope_down(f_service_);
+
+ f_service_ << indent() << "return true;" << endl;
+
+ scope_down(f_service_);
+ f_service_ << endl;
+
+ for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
+ generate_process_function_async(tservice, *f_iter);
+ }
+
+ indent_down();
+ indent(f_service_) << "}" << endl << endl;
+}
+
void t_csharp_generator::generate_function_helpers(t_function* tfunction) {
if (tfunction->is_oneway()) {
return;
@@ -2045,6 +2248,119 @@
f_service_ << endl;
}
+void t_csharp_generator::generate_process_function_async(t_service* tservice, t_function* tfunction) {
+ (void)tservice;
+ indent(f_service_) << "public async Task " << tfunction->get_name()
+ << "_ProcessAsync(int seqid, TProtocol iprot, TProtocol oprot)" << endl;
+ scope_up(f_service_);
+
+ string argsname = tfunction->get_name() + "_args";
+ string resultname = tfunction->get_name() + "_result";
+
+ f_service_ << indent() << argsname << " args = new " << argsname << "();" << endl
+ << indent() << "args.Read(iprot);" << endl
+ << indent() << "iprot.ReadMessageEnd();" << endl;
+
+ t_struct* xs = tfunction->get_xceptions();
+ const std::vector<t_field*>& xceptions = xs->get_members();
+ vector<t_field*>::const_iterator x_iter;
+
+ if (!tfunction->is_oneway()) {
+ f_service_ << indent() << resultname << " result = new " << resultname << "();" << endl;
+ }
+
+ f_service_ << indent() << "try" << endl
+ << indent() << "{" << endl;
+ indent_up();
+
+ if (xceptions.size() > 0) {
+ f_service_ << indent() << "try" << endl
+ << indent() << "{" << endl;
+ indent_up();
+ }
+
+ t_struct* arg_struct = tfunction->get_arglist();
+ const std::vector<t_field*>& fields = arg_struct->get_members();
+ vector<t_field*>::const_iterator f_iter;
+
+ f_service_ << indent();
+ if (!tfunction->is_oneway() && !tfunction->get_returntype()->is_void()) {
+ f_service_ << "result.Success = ";
+ }
+ f_service_ << "await iface_." << normalize_name(tfunction->get_name()) << "Async(";
+ bool first = true;
+ prepare_member_name_mapping(arg_struct);
+ for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
+ if (first) {
+ first = false;
+ }
+ else {
+ f_service_ << ", ";
+ }
+ f_service_ << "args." << prop_name(*f_iter);
+ if (nullable_ && !type_can_be_null((*f_iter)->get_type())) {
+ f_service_ << ".Value";
+ }
+ }
+ cleanup_member_name_mapping(arg_struct);
+ f_service_ << ");" << endl;
+
+ prepare_member_name_mapping(xs, xs->get_members(), resultname);
+ if (xceptions.size() > 0) {
+ indent_down();
+ f_service_ << indent() << "}" << endl;
+ for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
+ f_service_ << indent() << "catch (" << type_name((*x_iter)->get_type(), false, false) << " "
+ << (*x_iter)->get_name() << ")" << endl
+ << indent() << "{" << endl;
+ if (!tfunction->is_oneway()) {
+ indent_up();
+ f_service_ << indent() << "result." << prop_name(*x_iter) << " = " << (*x_iter)->get_name()
+ << ";" << endl;
+ indent_down();
+ }
+ f_service_ << indent() << "}" << endl;
+ }
+ }
+ if (!tfunction->is_oneway()) {
+ f_service_ << indent() << "oprot.WriteMessageBegin(new TMessage(\"" << tfunction->get_name()
+ << "\", TMessageType.Reply, seqid)); " << endl;
+ f_service_ << indent() << "result.Write(oprot);" << endl;
+ }
+ indent_down();
+
+ cleanup_member_name_mapping(xs);
+
+ f_service_ << indent() << "}" << endl
+ << indent() << "catch (TTransportException)" << endl
+ << indent() << "{" << endl
+ << indent() << " throw;" << endl
+ << indent() << "}" << endl
+ << indent() << "catch (Exception ex)" << endl
+ << indent() << "{" << endl
+ << indent() << " Console.Error.WriteLine(\"Error occurred in processor:\");" << endl
+ << indent() << " Console.Error.WriteLine(ex.ToString());" << endl;
+
+ if (tfunction->is_oneway()) {
+ f_service_ << indent() << "}" << endl;
+ }
+ else {
+ f_service_ << indent() << " TApplicationException x = new TApplicationException" << indent()
+ << "(TApplicationException.ExceptionType.InternalError,\" Internal error.\");"
+ << endl
+ << indent() << " oprot.WriteMessageBegin(new TMessage(\"" << tfunction->get_name()
+ << "\", TMessageType.Exception, seqid));" << endl
+ << indent() << " x.Write(oprot);" << endl
+ << indent() << "}" << endl;
+ f_service_ << indent() << "oprot.WriteMessageEnd();" << endl
+ << indent() << "oprot.Transport.Flush();" << endl;
+ }
+
+ scope_down(f_service_);
+
+ f_service_ << endl;
+}
+
void t_csharp_generator::generate_csharp_union_reader(std::ofstream& out, t_struct* tunion) {
// Thanks to THRIFT-1768, we don't need to check for required fields in the union
const vector<t_field*>& fields = tunion->get_members();
diff --git a/lib/csharp/src/Server/TServer.cs b/lib/csharp/src/Server/TServer.cs
index cee2ae3..34f06a9 100644
--- a/lib/csharp/src/Server/TServer.cs
+++ b/lib/csharp/src/Server/TServer.cs
@@ -65,11 +65,11 @@
//Construction
public TServer(TProcessor processor,
TServerTransport serverTransport)
- : this(processor, serverTransport,
- new TTransportFactory(),
- new TTransportFactory(),
- new TBinaryProtocol.Factory(),
- new TBinaryProtocol.Factory(),
+ : this(processor, serverTransport,
+ new TTransportFactory(),
+ new TTransportFactory(),
+ new TBinaryProtocol.Factory(),
+ new TBinaryProtocol.Factory(),
DefaultLogDelegate)
{
}
@@ -77,12 +77,12 @@
public TServer(TProcessor processor,
TServerTransport serverTransport,
LogDelegate logDelegate)
- : this(processor,
- serverTransport,
- new TTransportFactory(),
- new TTransportFactory(),
- new TBinaryProtocol.Factory(),
- new TBinaryProtocol.Factory(),
+ : this(processor,
+ serverTransport,
+ new TTransportFactory(),
+ new TTransportFactory(),
+ new TBinaryProtocol.Factory(),
+ new TBinaryProtocol.Factory(),
logDelegate)
{
}
diff --git a/lib/csharp/src/TAsyncProcessor.cs b/lib/csharp/src/TAsyncProcessor.cs
new file mode 100644
index 0000000..ab43225
--- /dev/null
+++ b/lib/csharp/src/TAsyncProcessor.cs
@@ -0,0 +1,38 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+using System.Threading.Tasks;
+using Thrift.Protocol;
+
+namespace Thrift
+{
+ /// <summary>
+ /// Processes a message asynchronously.
+ /// </summary>
+ public interface TAsyncProcessor
+ {
+ /// <summary>
+ /// Processes the next part of the message.
+ /// </summary>
+ /// <param name="iprot">The input protocol.</param>
+ /// <param name="oprot">The output protocol.</param>
+ /// <returns>true if there's more to process, false otherwise.</returns>
+ Task<bool> ProcessAsync(TProtocol iprot, TProtocol oprot);
+ }
+}
diff --git a/lib/csharp/src/TPrototypeProcessorFactory.cs b/lib/csharp/src/TPrototypeProcessorFactory.cs
index d15b2d9..6f56d33 100644
--- a/lib/csharp/src/TPrototypeProcessorFactory.cs
+++ b/lib/csharp/src/TPrototypeProcessorFactory.cs
@@ -29,10 +29,10 @@
public class TPrototypeProcessorFactory<P, H> : TProcessorFactory where P : TProcessor
{
object[] handlerArgs = null;
-
- public TPrototypeProcessorFactory()
+
+ public TPrototypeProcessorFactory()
{
- handlerArgs = new object[0];
+ handlerArgs = new object[0];
}
public TPrototypeProcessorFactory(params object[] handlerArgs)
diff --git a/lib/csharp/src/Thrift.45.csproj b/lib/csharp/src/Thrift.45.csproj
new file mode 100644
index 0000000..949f373
--- /dev/null
+++ b/lib/csharp/src/Thrift.45.csproj
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<Project ToolsVersion="12.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>{EBCE35DA-CF6A-42BC-A357-A9C09B534299}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Thrift</RootNamespace>
+ <AssemblyName>Thrift45</AssemblyName>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</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>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Web" />
+ <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="Collections\TCollections.cs" />
+ <Compile Include="Collections\THashSet.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Protocol\TAbstractBase.cs" />
+ <Compile Include="Protocol\TBase.cs" />
+ <Compile Include="Protocol\TBase64Utils.cs" />
+ <Compile Include="Protocol\TBinaryProtocol.cs" />
+ <Compile Include="Protocol\TCompactProtocol.cs" />
+ <Compile Include="Protocol\TField.cs" />
+ <Compile Include="Protocol\TJSONProtocol.cs" />
+ <Compile Include="Protocol\TList.cs" />
+ <Compile Include="Protocol\TMap.cs" />
+ <Compile Include="Protocol\TMessage.cs" />
+ <Compile Include="Protocol\TMessageType.cs" />
+ <Compile Include="Protocol\TMultiplexedProcessor.cs" />
+ <Compile Include="Protocol\TMultiplexedProtocol.cs" />
+ <Compile Include="Protocol\TProtocol.cs" />
+ <Compile Include="Protocol\TProtocolDecorator.cs" />
+ <Compile Include="Protocol\TProtocolException.cs" />
+ <Compile Include="Protocol\TProtocolFactory.cs" />
+ <Compile Include="Protocol\TProtocolUtil.cs" />
+ <Compile Include="Protocol\TSet.cs" />
+ <Compile Include="Protocol\TStruct.cs" />
+ <Compile Include="Protocol\TType.cs" />
+ <Compile Include="Server\TServer.cs" />
+ <Compile Include="Server\TServerEventHandler.cs" />
+ <Compile Include="Server\TSimpleServer.cs" />
+ <Compile Include="Server\TThreadedServer.cs" />
+ <Compile Include="Server\TThreadPoolServer.cs" />
+ <Compile Include="TApplicationException.cs" />
+ <Compile Include="TControllingHandler.cs" />
+ <Compile Include="TException.cs" />
+ <Compile Include="TAsyncProcessor.cs" />
+ <Compile Include="TProcessor.cs" />
+ <Compile Include="TProcessorFactory.cs" />
+ <Compile Include="TPrototypeProcessorFactory.cs" />
+ <Compile Include="Transport\TBufferedTransport.cs" />
+ <Compile Include="Transport\TFramedTransport.cs" />
+ <Compile Include="Transport\THttpTaskAsyncHandler.cs" />
+ <Compile Include="Transport\THttpClient.cs" />
+ <Compile Include="Transport\THttpHandler.cs" />
+ <Compile Include="Transport\TMemoryBuffer.cs" />
+ <Compile Include="Transport\TNamedPipeClientTransport.cs" />
+ <Compile Include="Transport\TNamedPipeServerTransport.cs" />
+ <Compile Include="Transport\TServerSocket.cs" />
+ <Compile Include="Transport\TServerTransport.cs" />
+ <Compile Include="Transport\TSilverlightSocket.cs" />
+ <Compile Include="Transport\TSocket.cs" />
+ <Compile Include="Transport\TStreamTransport.cs" />
+ <Compile Include="Transport\TTLSServerSocket.cs" />
+ <Compile Include="Transport\TTLSSocket.cs" />
+ <Compile Include="Transport\TTransport.cs" />
+ <Compile Include="Transport\TTransportException.cs" />
+ <Compile Include="Transport\TTransportFactory.cs" />
+ <Compile Include="TSingletonProcessorFactory.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Folder Include="Server\Collections\" />
+ <Folder Include="Server\Protocol\" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.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>
\ No newline at end of file
diff --git a/lib/csharp/src/Thrift.sln b/lib/csharp/src/Thrift.sln
index dd8437d..a29e468 100644
--- a/lib/csharp/src/Thrift.sln
+++ b/lib/csharp/src/Thrift.sln
@@ -4,35 +4,44 @@
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Thrift", "Thrift.csproj", "{499EB63C-D74C-47E8-AE48-A2FC94538E9D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ThriftTest", "..\test\ThriftTest\ThriftTest.csproj", "{48DD757F-CA95-4DD7-BDA4-58DB6F108C2C}"
- ProjectSection(ProjectDependencies) = postProject
- {499EB63C-D74C-47E8-AE48-A2FC94538E9D} = {499EB63C-D74C-47E8-AE48-A2FC94538E9D}
- EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ThriftMSBuildTask", "..\ThriftMSBuildTask\ThriftMSBuildTask.csproj", "{EC0A0231-66EA-4593-A792-C6CA3BB8668E}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Thrift.45", "Thrift.45.csproj", "{EBCE35DA-CF6A-42BC-A357-A9C09B534299}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ThriftMVCTest", "..\test\ThriftMVCTest\ThriftMVCTest.csproj", "{891B4487-C7BA-427E-BBC8-4C596C229A10}"
+EndProject
Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Release|Any CPU.Build.0 = Release|Any CPU
- {48DD757F-CA95-4DD7-BDA4-58DB6F108C2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {48DD757F-CA95-4DD7-BDA4-58DB6F108C2C}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {48DD757F-CA95-4DD7-BDA4-58DB6F108C2C}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {48DD757F-CA95-4DD7-BDA4-58DB6F108C2C}.Release|Any CPU.Build.0 = Release|Any CPU
- {EC0A0231-66EA-4593-A792-C6CA3BB8668E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {EC0A0231-66EA-4593-A792-C6CA3BB8668E}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {EC0A0231-66EA-4593-A792-C6CA3BB8668E}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {EC0A0231-66EA-4593-A792-C6CA3BB8668E}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(MonoDevelopProperties) = preSolution
- StartupItem = Thrift.csproj
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {48DD757F-CA95-4DD7-BDA4-58DB6F108C2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {48DD757F-CA95-4DD7-BDA4-58DB6F108C2C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {48DD757F-CA95-4DD7-BDA4-58DB6F108C2C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {48DD757F-CA95-4DD7-BDA4-58DB6F108C2C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EC0A0231-66EA-4593-A792-C6CA3BB8668E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EC0A0231-66EA-4593-A792-C6CA3BB8668E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EC0A0231-66EA-4593-A792-C6CA3BB8668E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EC0A0231-66EA-4593-A792-C6CA3BB8668E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EBCE35DA-CF6A-42BC-A357-A9C09B534299}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EBCE35DA-CF6A-42BC-A357-A9C09B534299}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EBCE35DA-CF6A-42BC-A357-A9C09B534299}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EBCE35DA-CF6A-42BC-A357-A9C09B534299}.Release|Any CPU.Build.0 = Release|Any CPU
+ {891B4487-C7BA-427E-BBC8-4C596C229A10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {891B4487-C7BA-427E-BBC8-4C596C229A10}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {891B4487-C7BA-427E-BBC8-4C596C229A10}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {891B4487-C7BA-427E-BBC8-4C596C229A10}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(MonoDevelopProperties) = preSolution
+ StartupItem = Thrift.csproj
+ EndGlobalSection
EndGlobal
diff --git a/lib/csharp/src/Transport/THttpTaskAsyncHandler.cs b/lib/csharp/src/Transport/THttpTaskAsyncHandler.cs
new file mode 100644
index 0000000..e491f32
--- /dev/null
+++ b/lib/csharp/src/Transport/THttpTaskAsyncHandler.cs
@@ -0,0 +1,97 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+using System.Threading.Tasks;
+using System.Web;
+using Thrift.Protocol;
+
+namespace Thrift.Transport
+{
+ /// <summary>
+ /// An async task based HTTP handler for processing thrift services.
+ /// </summary>
+ public class THttpTaskAsyncHandler : HttpTaskAsyncHandler
+ {
+ private readonly TAsyncProcessor _processor;
+ private readonly TProtocolFactory _inputProtocolFactory;
+ private readonly TProtocolFactory _outputProtocolFactory;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="THttpTaskAsyncHandler"/> class
+ /// using the <see cref="TBinaryProtocol.Factory"/> for both input and output streams.
+ /// </summary>
+ /// <param name="processor">The async processor implementation.</param>
+ public THttpTaskAsyncHandler(TAsyncProcessor processor)
+ : this(processor, new TBinaryProtocol.Factory())
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="THttpTaskAsyncHandler"/> class
+ /// using <paramref name="protocolFactory"/> for both input and output streams.
+ /// </summary>
+ /// <param name="processor">The async processor implementation.</param>
+ /// <param name="protocolFactory">The protocol factory.</param>
+ public THttpTaskAsyncHandler(TAsyncProcessor processor, TProtocolFactory protocolFactory)
+ : this(processor, protocolFactory, protocolFactory)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="THttpTaskAsyncHandler"/> class.
+ /// </summary>
+ /// <param name="processor">The async processor implementation.</param>
+ /// <param name="inputProtocolFactory">The input protocol factory.</param>
+ /// <param name="outputProtocolFactory">The output protocol factory.</param>
+ public THttpTaskAsyncHandler(TAsyncProcessor processor, TProtocolFactory inputProtocolFactory,
+ TProtocolFactory outputProtocolFactory)
+ {
+ _processor = processor;
+ _inputProtocolFactory = inputProtocolFactory;
+ _outputProtocolFactory = outputProtocolFactory;
+ }
+
+ public override async Task ProcessRequestAsync(HttpContext context)
+ {
+ var transport = new TStreamTransport(context.Request.InputStream, context.Response.OutputStream);
+
+ try
+ {
+ var input = _inputProtocolFactory.GetProtocol(transport);
+ var output = _outputProtocolFactory.GetProtocol(transport);
+
+ while (await _processor.ProcessAsync(input, output))
+ {
+ }
+ }
+ catch (TTransportException)
+ {
+ // Client died, just move on
+ }
+ finally
+ {
+ transport.Close();
+ }
+ }
+ }
+}
diff --git a/lib/csharp/src/Transport/TTLSSocket.cs b/lib/csharp/src/Transport/TTLSSocket.cs
index 833b792..2be7a41 100644
--- a/lib/csharp/src/Transport/TTLSSocket.cs
+++ b/lib/csharp/src/Transport/TTLSSocket.cs
@@ -290,7 +290,7 @@
public void setupTLS()
{
RemoteCertificateValidationCallback validator = this.certValidator ?? DefaultCertificateValidator;
-
+
if( this.localCertificateSelectionCallback != null)
{
this.secureStream = new SslStream(
@@ -308,7 +308,7 @@
validator
);
}
-
+
try
{
if (isServer)
diff --git a/lib/csharp/src/Transport/TTransport.cs b/lib/csharp/src/Transport/TTransport.cs
index a3639d2..6fb1077 100644
--- a/lib/csharp/src/Transport/TTransport.cs
+++ b/lib/csharp/src/Transport/TTransport.cs
@@ -55,7 +55,7 @@
}
catch( IOException)
{
- return false;
+ return false;
}
_hasPeekByte = true;
diff --git a/lib/csharp/test/ThriftMVCTest/App_Start/FilterConfig.cs b/lib/csharp/test/ThriftMVCTest/App_Start/FilterConfig.cs
new file mode 100644
index 0000000..855184f
--- /dev/null
+++ b/lib/csharp/test/ThriftMVCTest/App_Start/FilterConfig.cs
@@ -0,0 +1,31 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+using System.Web.Mvc;
+
+namespace ThriftMVCTest
+{
+ public static class FilterConfig
+ {
+ public static void RegisterGlobalFilters(GlobalFilterCollection filters)
+ {
+ filters.Add(new HandleErrorAttribute());
+ }
+ }
+}
diff --git a/lib/csharp/test/ThriftMVCTest/App_Start/RouteConfig.cs b/lib/csharp/test/ThriftMVCTest/App_Start/RouteConfig.cs
new file mode 100644
index 0000000..b4b6023
--- /dev/null
+++ b/lib/csharp/test/ThriftMVCTest/App_Start/RouteConfig.cs
@@ -0,0 +1,39 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+using System.Web.Mvc;
+using System.Web.Routing;
+
+namespace ThriftMVCTest
+{
+ public static class RouteConfig
+ {
+ public static void RegisterRoutes(RouteCollection routes)
+ {
+ routes.IgnoreRoute("{resource}.thrift");
+ routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
+
+ routes.MapRoute(
+ name: "Default",
+ url: "{controller}/{action}/{id}",
+ defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
+ );
+ }
+ }
+}
diff --git a/lib/csharp/test/ThriftMVCTest/AsyncHttpHandler.cs b/lib/csharp/test/ThriftMVCTest/AsyncHttpHandler.cs
new file mode 100644
index 0000000..7f26184
--- /dev/null
+++ b/lib/csharp/test/ThriftMVCTest/AsyncHttpHandler.cs
@@ -0,0 +1,32 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+using Thrift.Transport;
+
+namespace ThriftMVCTest
+{
+ public class AsyncHttpHandler : THttpTaskAsyncHandler
+ {
+ public AsyncHttpHandler()
+ : base(
+ new Thrift.Test.SecondService.AsyncProcessor(new SecondServiceImpl()))
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/csharp/test/ThriftMVCTest/Controllers/HomeController.cs b/lib/csharp/test/ThriftMVCTest/Controllers/HomeController.cs
new file mode 100644
index 0000000..ab9eada
--- /dev/null
+++ b/lib/csharp/test/ThriftMVCTest/Controllers/HomeController.cs
@@ -0,0 +1,72 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+using System;
+using System.Threading.Tasks;
+using System.Web.Mvc;
+using Thrift.Protocol;
+using Thrift.Test;
+using Thrift.Transport;
+
+namespace ThriftMVCTest.Controllers
+{
+ public class HomeController : Controller
+ {
+ public ActionResult Index()
+ {
+ return View();
+ }
+
+ public async Task<ActionResult> TestThriftAsync()
+ {
+ var baseUri = new Uri(string.Format("{0}://{1}{2}", Request.Url.Scheme, Request.Url.Authority,
+ Url.Content("~")));
+
+ SecondService.IAsync asyncService =
+ new SecondService.Client(new TBinaryProtocol(new THttpClient(new Uri(baseUri, "Async.thrift"))));
+
+ await asyncService.blahBlahAsync();
+ var result = await asyncService.secondtestStringAsync("TestString");
+ if (result != "TestString")
+ {
+ throw new Exception("The wrong result was returned");
+ }
+
+ return RedirectToAction("Index");
+ }
+
+ public ActionResult TestThriftSync()
+ {
+ var baseUri = new Uri(string.Format("{0}://{1}{2}", Request.Url.Scheme, Request.Url.Authority,
+ Url.Content("~")));
+
+ SecondService.ISync service =
+ new SecondService.Client(new TBinaryProtocol(new THttpClient(new Uri(baseUri, "Sync.thrift"))));
+
+ service.blahBlah();
+ var result = service.secondtestString("TestString");
+ if (result != "TestString")
+ {
+ throw new Exception("The wrong result was returned");
+ }
+
+ return RedirectToAction("Index");
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/csharp/test/ThriftMVCTest/Global.asax b/lib/csharp/test/ThriftMVCTest/Global.asax
new file mode 100644
index 0000000..7bb688c
--- /dev/null
+++ b/lib/csharp/test/ThriftMVCTest/Global.asax
@@ -0,0 +1,19 @@
+<%@ Application Codebehind="Global.asax.cs" Inherits="ThriftMVCTest.MvcApplication" Language="C#" %>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
diff --git a/lib/csharp/test/ThriftMVCTest/Global.asax.cs b/lib/csharp/test/ThriftMVCTest/Global.asax.cs
new file mode 100644
index 0000000..59731ef
--- /dev/null
+++ b/lib/csharp/test/ThriftMVCTest/Global.asax.cs
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+using System.Web.Mvc;
+using System.Web.Routing;
+
+namespace ThriftMVCTest
+{
+ public class MvcApplication : System.Web.HttpApplication
+ {
+ protected void Application_Start()
+ {
+ AreaRegistration.RegisterAllAreas();
+ FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
+ RouteConfig.RegisterRoutes(RouteTable.Routes);
+ }
+ }
+}
diff --git a/lib/csharp/test/ThriftMVCTest/Properties/AssemblyInfo.cs b/lib/csharp/test/ThriftMVCTest/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..05556ac
--- /dev/null
+++ b/lib/csharp/test/ThriftMVCTest/Properties/AssemblyInfo.cs
@@ -0,0 +1,53 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+using System.Reflection;
+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("ThriftMVCTest")]
+[assembly: AssemblyDescription("A web project for testing the thrift ASP.NET features.")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("The Apache Software Foundation")]
+[assembly: AssemblyProduct("ThriftMVCTest")]
+[assembly: AssemblyCopyright("The Apache Software Foundation")]
+[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("366f9bd0-3c0e-48aa-b2ca-61fd4a93e427")]
+
+// 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.0.1")]
+[assembly: AssemblyFileVersion("1.0.0.1")]
diff --git a/lib/csharp/test/ThriftMVCTest/SecondServiceImpl.cs b/lib/csharp/test/ThriftMVCTest/SecondServiceImpl.cs
new file mode 100644
index 0000000..dce0148
--- /dev/null
+++ b/lib/csharp/test/ThriftMVCTest/SecondServiceImpl.cs
@@ -0,0 +1,47 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+using System.Threading.Tasks;
+using Thrift.Test;
+
+namespace ThriftMVCTest
+{
+ public class SecondServiceImpl : SecondService.IAsync, SecondService.ISync
+ {
+ public Task blahBlahAsync()
+ {
+ return Task.FromResult(0);
+ }
+
+ public Task<string> secondtestStringAsync(string thing)
+ {
+ return Task.FromResult(thing);
+ }
+
+ public void blahBlah()
+ {
+
+ }
+
+ public string secondtestString(string thing)
+ {
+ return thing;
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/csharp/test/ThriftMVCTest/SyncHttpHandler.cs b/lib/csharp/test/ThriftMVCTest/SyncHttpHandler.cs
new file mode 100644
index 0000000..4fe2662
--- /dev/null
+++ b/lib/csharp/test/ThriftMVCTest/SyncHttpHandler.cs
@@ -0,0 +1,32 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+using Thrift.Transport;
+
+namespace ThriftMVCTest
+{
+ public class SyncHttpHandler : THttpHandler
+ {
+ public SyncHttpHandler()
+ : base(
+ new Thrift.Test.SecondService.Processor(new SecondServiceImpl()))
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/csharp/test/ThriftMVCTest/ThriftMVCTest.csproj b/lib/csharp/test/ThriftMVCTest/ThriftMVCTest.csproj
new file mode 100644
index 0000000..0eb969a
--- /dev/null
+++ b/lib/csharp/test/ThriftMVCTest/ThriftMVCTest.csproj
@@ -0,0 +1,200 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<Project ToolsVersion="12.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>{891B4487-C7BA-427E-BBC8-4C596C229A10}</ProjectGuid>
+ <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>ThriftMVCTest</RootNamespace>
+ <AssemblyName>ThriftMVCTest</AssemblyName>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <MvcBuildViews>false</MvcBuildViews>
+ <UseIISExpress>true</UseIISExpress>
+ <IISExpressSSLPort />
+ <IISExpressAnonymousAuthentication />
+ <IISExpressWindowsAuthentication />
+ <IISExpressUseClassicPipelineMode />
+ </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="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.Core" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Web" />
+ <Reference Include="System.Web.Extensions" />
+ <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="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <Private>True</Private>
+ <HintPath>..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Net.Http">
+ </Reference>
+ <Reference Include="System.Net.Http.WebRequest">
+ </Reference>
+ <Reference Include="System.Web.Helpers, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <Private>True</Private>
+ <HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.Helpers.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <Private>True</Private>
+ <HintPath>..\packages\Microsoft.AspNet.Mvc.5.2.3\lib\net45\System.Web.Mvc.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <Private>True</Private>
+ <HintPath>..\packages\Microsoft.AspNet.Razor.3.2.3\lib\net45\System.Web.Razor.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <Private>True</Private>
+ <HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Web.WebPages.Deployment, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <Private>True</Private>
+ <HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Deployment.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <Private>True</Private>
+ <HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Razor.dll</HintPath>
+ </Reference>
+ <Reference Include="ThriftImpl">
+ <HintPath>.\ThriftImpl.dll</HintPath>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="App_Start\FilterConfig.cs" />
+ <Compile Include="App_Start\RouteConfig.cs" />
+ <Compile Include="SyncHttpHandler.cs" />
+ <Compile Include="AsyncHttpHandler.cs" />
+ <Compile Include="Controllers\HomeController.cs" />
+ <Compile Include="Global.asax.cs">
+ <DependentUpon>Global.asax</DependentUpon>
+ </Compile>
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="SecondServiceImpl.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="favicon.ico" />
+ <Content Include="Global.asax" />
+ <Content Include="Web.config" />
+ <Content Include="Web.Debug.config">
+ <DependentUpon>Web.config</DependentUpon>
+ </Content>
+ <Content Include="Web.Release.config">
+ <DependentUpon>Web.config</DependentUpon>
+ </Content>
+ <Content Include="Views\Web.config" />
+ <Content Include="Views\_ViewStart.cshtml" />
+ <Content Include="Views\Shared\_Layout.cshtml" />
+ <Content Include="Views\Home\Index.cshtml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Folder Include="App_Data\" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="packages.config">
+ <SubType>Designer</SubType>
+ </Content>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\src\Thrift.45.csproj">
+ <Project>{ebce35da-cf6a-42bc-a357-a9c09b534299}</Project>
+ <Name>Thrift.45</Name>
+ </ProjectReference>
+ </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" />
+ <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>57482</DevelopmentServerPort>
+ <DevelopmentServerVPath>/</DevelopmentServerVPath>
+ <IISUrl>http://localhost:57482/</IISUrl>
+ <NTLMAuthentication>False</NTLMAuthentication>
+ <UseCustomServer>False</UseCustomServer>
+ <CustomServerUrl>
+ </CustomServerUrl>
+ <SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
+ </WebProjectProperties>
+ </FlavorProperties>
+ </VisualStudio>
+ </ProjectExtensions>
+ <PropertyGroup>
+ <PreBuildEvent>rmdir /s /q "$(ProjectDir)gen-csharp"
+del /f /q "$(ProjectDir)ThriftImpl.dll"
+SET OUTPUT_DIR=$(ProjectDir)
+SET THRIFT_FILE=$(ProjectDir)\..\..\..\..\test\ThriftTest.thrift
+for %25%25I in ("%25OUTPUT_DIR%25") do set SHORT_DIR=%25%25~fsI
+for %25%25I in ("%25THRIFT_FILE%25") do set THRIFT_SHORT=%25%25~fsI
+"$(ProjectDir)\..\..\..\..\compiler\cpp\Debug\thrift.exe" --gen csharp:async=true -o %25SHORT_DIR%25 %25THRIFT_SHORT%25
+"$(MSBuildToolsPath)\Csc.exe" /t:library /out:"$(ProjectDir)ThriftImpl.dll" /recurse:"$(ProjectDir)gen-csharp"\* /reference:"$(ProjectDir)..\..\src\bin\Debug\Thrift45.dll"</PreBuildEvent>
+ </PropertyGroup>
+ <!-- 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>
\ No newline at end of file
diff --git a/lib/csharp/test/ThriftMVCTest/Views/Home/Index.cshtml b/lib/csharp/test/ThriftMVCTest/Views/Home/Index.cshtml
new file mode 100644
index 0000000..f0ca7da
--- /dev/null
+++ b/lib/csharp/test/ThriftMVCTest/Views/Home/Index.cshtml
@@ -0,0 +1,25 @@
+@*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+*@
+
+@{
+ ViewBag.Title = "Home Page";
+}
+
+<p>@Html.ActionLink("Test Thrift Async Service", "TestThriftAsync")</p>
+<p>@Html.ActionLink("Test Thrift Sync Service", "TestThriftSync")</p>
diff --git a/lib/csharp/test/ThriftMVCTest/Views/Shared/_Layout.cshtml b/lib/csharp/test/ThriftMVCTest/Views/Shared/_Layout.cshtml
new file mode 100644
index 0000000..b41c99a
--- /dev/null
+++ b/lib/csharp/test/ThriftMVCTest/Views/Shared/_Layout.cshtml
@@ -0,0 +1,30 @@
+@*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+*@
+
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Thrift ASP.NET Test</title>
+</head>
+<body>
+ @RenderBody()
+</body>
+</html>
diff --git a/lib/csharp/test/ThriftMVCTest/Views/Web.config b/lib/csharp/test/ThriftMVCTest/Views/Web.config
new file mode 100644
index 0000000..3c21138
--- /dev/null
+++ b/lib/csharp/test/ThriftMVCTest/Views/Web.config
@@ -0,0 +1,60 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<configuration>
+ <configSections>
+ <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
+ <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
+ <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.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=5.2.3.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.Optimization"/>
+ <add namespace="System.Web.Routing" />
+ <add namespace="ThriftMVCTest" />
+ </namespaces>
+ </pages>
+ </system.web.webPages.razor>
+
+ <appSettings>
+ <add key="webpages:Enabled" value="false" />
+ </appSettings>
+
+ <system.webServer>
+ <handlers>
+ <remove name="BlockViewHandler"/>
+ <add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
+ </handlers>
+ </system.webServer>
+
+ <system.web>
+ <compilation>
+ <assemblies>
+ <add assembly="System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
+ </assemblies>
+ </compilation>
+ </system.web>
+</configuration>
diff --git a/lib/csharp/test/ThriftMVCTest/Views/_ViewStart.cshtml b/lib/csharp/test/ThriftMVCTest/Views/_ViewStart.cshtml
new file mode 100644
index 0000000..8cde2ee
--- /dev/null
+++ b/lib/csharp/test/ThriftMVCTest/Views/_ViewStart.cshtml
@@ -0,0 +1,22 @@
+@*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+*@
+
+@{
+ Layout = "~/Views/Shared/_Layout.cshtml";
+}
diff --git a/lib/csharp/test/ThriftMVCTest/Web.Debug.config b/lib/csharp/test/ThriftMVCTest/Web.Debug.config
new file mode 100644
index 0000000..45d56d8
--- /dev/null
+++ b/lib/csharp/test/ThriftMVCTest/Web.Debug.config
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<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>
diff --git a/lib/csharp/test/ThriftMVCTest/Web.Release.config b/lib/csharp/test/ThriftMVCTest/Web.Release.config
new file mode 100644
index 0000000..157c340
--- /dev/null
+++ b/lib/csharp/test/ThriftMVCTest/Web.Release.config
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<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)" />
+ <!--
+ 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>
diff --git a/lib/csharp/test/ThriftMVCTest/Web.config b/lib/csharp/test/ThriftMVCTest/Web.config
new file mode 100644
index 0000000..9c57d11
--- /dev/null
+++ b/lib/csharp/test/ThriftMVCTest/Web.config
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<!--
+ For more information on how to configure your ASP.NET application, please visit
+ http://go.microsoft.com/fwlink/?LinkId=301880
+ -->
+<configuration>
+ <appSettings>
+ <add key="webpages:Version" value="3.0.0.0" />
+ <add key="webpages:Enabled" value="false" />
+ <add key="ClientValidationEnabled" value="true" />
+ <add key="UnobtrusiveJavaScriptEnabled" value="true" />
+ <add key="owin:AutomaticAppStartup" value="false" />
+ </appSettings>
+ <system.web>
+ <authentication mode="None" />
+ <compilation debug="true" targetFramework="4.5" />
+ <httpRuntime targetFramework="4.5" />
+ </system.web>
+ <system.webServer>
+ <modules>
+ <remove name="FormsAuthentication" />
+ </modules>
+ <handlers>
+ <add name="AsyncHttpHandler" verb="*" path="Async.thrift" type="ThriftMVCTest.AsyncHttpHandler, ThriftMVCTest" />
+ <add name="SyncHttpHandler" verb="*" path="Sync.thrift" type="ThriftMVCTest.SyncHttpHandler, ThriftMVCTest" />
+ </handlers>
+ </system.webServer>
+ <runtime>
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+ <dependentAssembly>
+ <assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" />
+ <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="Microsoft.Owin.Security.OAuth" publicKeyToken="31bf3856ad364e35" />
+ <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="Microsoft.Owin.Security.Cookies" publicKeyToken="31bf3856ad364e35" />
+ <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" />
+ <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" />
+ <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />
+ <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
+ <bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
+ <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
+ <bindingRedirect oldVersion="1.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
+ <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
+ </dependentAssembly>
+ </assemblyBinding>
+ </runtime>
+</configuration>
\ No newline at end of file
diff --git a/lib/csharp/test/ThriftMVCTest/favicon.ico b/lib/csharp/test/ThriftMVCTest/favicon.ico
new file mode 100644
index 0000000..a3a7999
--- /dev/null
+++ b/lib/csharp/test/ThriftMVCTest/favicon.ico
Binary files differ
diff --git a/lib/csharp/test/ThriftMVCTest/packages.config b/lib/csharp/test/ThriftMVCTest/packages.config
new file mode 100644
index 0000000..98c8416
--- /dev/null
+++ b/lib/csharp/test/ThriftMVCTest/packages.config
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<packages>
+ <package id="Microsoft.AspNet.Mvc" version="5.2.3" targetFramework="net45" />
+ <package id="Microsoft.AspNet.Razor" version="3.2.3" targetFramework="net45" />
+ <package id="Microsoft.AspNet.WebPages" version="3.2.3" targetFramework="net45" />
+ <package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" />
+</packages>
\ No newline at end of file