Skip to content

Commit 66de4c6

Browse files
Fixed internal server error for REST services with string collection output parameters.
1 parent 7e691f1 commit 66de4c6

File tree

5 files changed

+123
-13
lines changed

5 files changed

+123
-13
lines changed

dotnet/src/dotnetframework/GxClasses/Services/GxRestWrapper.cs

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -898,21 +898,32 @@ protected static object MakeRestType( object collectionValue, bool isApiObject)
898898
{
899899
restItemType = ClassLoader.FindType(Config.CommonAssemblyName, itemType.FullName + "_RESTLInterface", null);
900900
}
901-
if (restItemType == null)//Collection<SDTType> convert to GxGenericCollection<SDTType_RESTInterface>
902-
{
903-
restItemType = ClassLoader.FindType(Config.CommonAssemblyName, itemType.FullName + "_RESTInterface", null);
904-
}
905-
object[] attributes = restItemType.GetCustomAttributes(typeof(GxJsonSerialization), false);
906-
IEnumerable<object> serializationAttributes = attributes.Where(a => a.GetType() == typeof(GxJsonSerialization));
907-
if (serializationAttributes != null && serializationAttributes.Any<object>())
901+
else
908902
{
909-
GxJsonSerialization attFmt = (GxJsonSerialization)serializationAttributes.FirstOrDefault();
910-
wrappedStatus = attFmt.JsonUnwrapped;
911-
isWrapped = (isApiObject)? ((wrappedStatus == "wrapped")? true: false): ((wrappedStatus == "unwrapped") ? false : true);
903+
904+
if (typeof(IGxJSONSerializable).IsAssignableFrom(itemType))
905+
{
906+
if (restItemType == null)//Collection<SDTType> convert to GxGenericCollection<SDTType_RESTInterface>
907+
{
908+
restItemType = ClassLoader.FindType(Config.CommonAssemblyName, itemType.FullName + "_RESTInterface", null);
909+
}
910+
object[] attributes = restItemType.GetCustomAttributes(typeof(GxJsonSerialization), false);
911+
IEnumerable<object> serializationAttributes = attributes.Where(a => a.GetType() == typeof(GxJsonSerialization));
912+
if (serializationAttributes != null && serializationAttributes.Any<object>())
913+
{
914+
GxJsonSerialization attFmt = (GxJsonSerialization)serializationAttributes.FirstOrDefault();
915+
wrappedStatus = attFmt.JsonUnwrapped;
916+
isWrapped = (isApiObject) ? ((wrappedStatus == "wrapped") ? true : false) : ((wrappedStatus == "unwrapped") ? false : true);
917+
}
918+
isEmpty = !restItemType.IsDefined(typeof(GxOmitEmptyCollection), false);
919+
Type genericListItemType = typeof(GxGenericCollection<>).MakeGenericType(restItemType);
920+
collectionObject = Activator.CreateInstance(genericListItemType, new object[] { collectionValue, isWrapped, wrappedStatus });
921+
}
922+
else
923+
{
924+
collectionObject = collectionValue;
925+
}
912926
}
913-
isEmpty = !restItemType.IsDefined(typeof(GxOmitEmptyCollection), false);
914-
Type genericListItemType = typeof(GxGenericCollection<>).MakeGenericType(restItemType);
915-
collectionObject = Activator.CreateInstance(genericListItemType, new object[] { collectionValue, isWrapped , wrappedStatus});
916927
}
917928
// Empty collection serialized w/ noproperty
918929
if (collectionObject is IList restList)

dotnet/test/DotNetCoreWebUnitTest/DotNetCoreWebUnitTest.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@
5757
<None Update="apps\createsession.svc">
5858
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
5959
</None>
60+
<None Update="apps\getcollection.svc">
61+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
62+
</None>
6063
<None Update="apps\httpcors.svc">
6164
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
6265
</None>

dotnet/test/DotNetCoreWebUnitTest/Middleware/RestServiceTest.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public RestServiceTest() : base()
2323
{
2424
ClassLoader.FindType("apps.append", "GeneXus.Programs.apps", "append", Assembly.GetExecutingAssembly(), true);//Force loading assembly for append procedure
2525
ClassLoader.FindType("apps.saveimage", "GeneXus.Programs.apps", "saveimage", Assembly.GetExecutingAssembly(), true);//Force loading assembly for saveimage procedure
26+
ClassLoader.FindType("apps.getcollection", "GeneXus.Programs.apps", "getcollection", Assembly.GetExecutingAssembly(), true);
2627
server.AllowSynchronousIO = true;
2728
}
2829
const string serviceBodyResponse = "OK";
@@ -129,6 +130,7 @@ private async Task<HttpResponseMessage> RunController(HttpClient client)
129130
return response;
130131
}
131132
string ACCESS_CONTROL_MAX_AGE_HEADER = "86400";
133+
132134
[Fact]
133135
public async Task TestHttpResponseOnRestService()
134136
{
@@ -140,6 +142,18 @@ public async Task TestHttpResponseOnRestService()
140142
Assert.Equal(ACCESS_CONTROL_MAX_AGE_HEADER, values.FirstOrDefault());
141143
}
142144

145+
[Fact]
146+
public async Task TestRestServiceWithSimpleCollectionOutput()
147+
{
148+
server.AllowSynchronousIO = true;
149+
HttpClient client = server.CreateClient();
150+
HttpResponseMessage response = await client.PostAsync("rest/apps/getcollection", null);
151+
response.EnsureSuccessStatusCode();
152+
Assert.Equal(System.Net.HttpStatusCode.OK, response.StatusCode);
153+
string responseBody = await response.Content.ReadAsStringAsync();
154+
Assert.Equal("{\"CliType\":1,\"CliCode\":[1,2]}", responseBody);
155+
}
156+
143157
}
144158

145159
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
using GeneXus.Application;
2+
using GeneXus.Data.NTier;
3+
using GeneXus.Procedure;
4+
using GeneXus.Utils;
5+
namespace GeneXus.Programs.apps
6+
{
7+
public class getcollection : GXProcedure
8+
{
9+
public getcollection( )
10+
{
11+
context = new GxContext( );
12+
DataStoreUtil.LoadDataStores( context);
13+
IsMain = true;
14+
context.SetDefaultTheme("FromString", true);
15+
}
16+
17+
public getcollection( IGxContext context )
18+
{
19+
this.context = context;
20+
IsMain = false;
21+
}
22+
23+
public void execute( out short aP0_CliType ,
24+
out GxSimpleCollection<int> aP1_CliCode )
25+
{
26+
this.clitype = 0 ;
27+
this.cliCod = new GxSimpleCollection<int>() ;
28+
initialize();
29+
ExecuteImpl();
30+
aP0_CliType=this.clitype;
31+
aP1_CliCode=this.cliCod;
32+
}
33+
34+
public GxSimpleCollection<int> executeUdp( out short aP0_CliType )
35+
{
36+
execute(out aP0_CliType, out aP1_CliCode);
37+
return cliCod ;
38+
}
39+
40+
public void executeSubmit( out short aP0_CliType ,
41+
out GxSimpleCollection<int> aP1_CliCode )
42+
{
43+
this.clitype = 0 ;
44+
this.cliCod = new GxSimpleCollection<int>() ;
45+
SubmitImpl();
46+
aP0_CliType=this.clitype;
47+
aP1_CliCode=this.cliCod;
48+
}
49+
50+
protected override void ExecutePrivate( )
51+
{
52+
/* GeneXus formulas */
53+
/* Output device settings */
54+
clitype = 1;
55+
cliCod.Add(1, 0);
56+
cliCod.Add(2, 0);
57+
this.cleanup();
58+
}
59+
60+
public override void cleanup( )
61+
{
62+
CloseCursors();
63+
if ( IsMain )
64+
{
65+
context.CloseConnections();
66+
}
67+
ExitApp();
68+
}
69+
70+
public override void initialize( )
71+
{
72+
cliCod = new GxSimpleCollection<int>();
73+
74+
}
75+
76+
private short clitype ;
77+
private GxSimpleCollection<int> cliCod ;
78+
private GxSimpleCollection<int> aP1_CliCode ;
79+
}
80+
81+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<%@ServiceHost Service= "GeneXus.Programs.apps.getcollection,apps.getcollection" %>

0 commit comments

Comments
 (0)