Hello I am doing functional API testing. This error occurred when I am trying to serialize my json payload. When I try to run my test I get the following error
"The active test run was aborted. Reason: Test host process crashed : Process is terminated due to StackOverflowException"
My helper method worked fine but I believe it has a infinite recursion somewhere. Here is the break down of the different classes I have.
I have one helper class and using custom ContractResolver I am picking the methods name and the attributes I want to apply to and then using my custom serialize method. Please any helper from any c# expert who be highly appreciated!
public class Helper
{
public void Asserts(HttpWebResponse response)
{
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}
[AttributeUsage(AttributeTargets.Property)]
public class UseWithApiMethodsAttribute : Attribute
{
public UseWithApiMethodsAttribute(params string[] methodNames)
{
MethodNames = methodNames;
}
public string[] MethodNames { get; private set; }
}
public class SelectivePropertyResolver : DefaultContractResolver
{
public string ApiMethodName { get; private set; }
public SelectivePropertyResolver(string apiMethodName)
{
ApiMethodName = apiMethodName;
}
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty prop = base.CreateProperty(member, memberSerialization);
if (member.MemberType == MemberTypes.Property)
{
var att = ((PropertyInfo)member).GetCustomAttribute<UseWithApiMethodsAttribute>(true);
if (att == null || !att.MethodNames.Contains(ApiMethodName))
{
prop.Ignored = true;
}
}
return prop;
}
}
public string SerializeForApiMethod(Object model, string methodName)
{
var settings = new JsonSerializerSettings
{
ContractResolver = new SelectivePropertyResolver(methodName),
Formatting = Formatting.Indented
};
return JsonConvert.SerializeObject(model, settings);
}
}
Here is my Model class called TagModel where I am using the get and set and assigning the values
public class TagModel
{
public TagModel defaultModel = new TagModel
{
endpointIds = new List<int> { -2147483612, -2147483611 },
tagIds = new List<int> { 35, 37 },
id = -2147483639,
parentId = 37,
nodeId = 1,
oldParentId = null,
isEndpoint = false,
state = 2,
destinationTag = 2,
};
public TagModel modelForUpdate = new TagModel
{
tagNode = new TagModel.TagNode
{
query = null,
type = 0,
filter = null,
ldapPaths = null,
editPermissions = 0,
id = 0,
disallowed = false,
name = "NewTag"
},
parentId = 7
};
[UseWithApiMethods("UpdateTag")]
public TagNode tagNode { get; set; }
public class TagNode
{
[UseWithApiMethods("UpdateTag")]
public object query { get; set; }
[UseWithApiMethods("UpdateTag")]
public int type { get; set; }
[UseWithApiMethods("UpdateTag")]
public object filter { get; set; }
[UseWithApiMethods("UpdateTag")]
public object ldapPaths { get; set; }
[UseWithApiMethods("UpdateTag")]
public int editPermissions { get; set; }
[UseWithApiMethods("UpdateTag")]
public int id { get; set; }
[UseWithApiMethods("UpdateTag")]
public bool disallowed { get; set; }
[UseWithApiMethods("UpdateTag")]
public string name { get; set; }
}
[UseWithApiMethods("UpdateTagToRoot")]
public int nodeId { get; set; }
[UseWithApiMethods("UpdateTagToRoot")]
public object oldParentId { get; set; }
[UseWithApiMethods("UpdateTagToRoot")]
public bool isEndpoint { get; set; }
[UseWithApiMethods("UpdateTagToRoot")]
public int state { get; set; }
[UseWithApiMethods("UpdateTagToRoot")]
public int destinationTag { get; set; }
[UseWithApiMethods("UpdateEndpointsToTags")]
public List<int> endpointIds { get; set; }
[UseWithApiMethods("UpdateEndpointsToTags")]
public List<int> tagIds { get; set; }
[UseWithApiMethods("UpdateEndpointsFromTags")]
public int id { get; set; }
[UseWithApiMethods("UpdateEndpointsFromTags", "UpdateTag")]
public int parentId { get; set; }
}
}
Lastly I have another class is where my fuction method called "Tags" is where I came calling the SerializeForApiMethod and passing the model class instance and the method name. This class is also inherting TagModel class
public class Tags : TagModel
{
public string BaseUrl = RequestHandler.GenerateRequestURL("svc-searchcontroller") + "Tag/";
public Helper helper = new Helper();
public HttpWebResponse UpdateTag()
{
RequestHandler requestor = new RequestHandler(BaseUrl + "UpdateTag", HttpVerb.POST, AuthenticationType.Bearer);
return requestor.SendRequest(helper.SerializeForApiMethod(modelForUpdate, "UpdateTag"));
}
public HttpWebResponse UpdateEndpointsFromTags()
{
RequestHandler requestor = new RequestHandler(BaseUrl + "UpdateEndpointsFromTags", HttpVerb.POST, AuthenticationType.Bearer);
return requestor.SendRequest(helper.SerializeForApiMethod(defaultModel, "UpdateEndpointsFromTags"));
}
public HttpWebResponse UpdateEndpointsToTags()
{
RequestHandler requestor = new RequestHandler(BaseUrl + "UpdateEndpointsToTags", HttpVerb.POST, AuthenticationType.Bearer);
return requestor.SendRequest(helper.SerializeForApiMethod(defaultModel, "UpdateEndpointsToTags"));
}
public HttpWebResponse UpdateTagToRoot()
{
RequestHandler requestor = new RequestHandler(BaseUrl + "UpdateTagToRoot", HttpVerb.POST, AuthenticationType.Bearer);
return requestor.SendRequest(helper.SerializeForApiMethod(defaultModel, "UpdateTagToRoot"));
}
What I have tried:
After debugging the code, I see it throws the stackoverflow exception when I created the instance of Tagmodel class. When I said
public TagModel defaultModel = new TagModel