Modifying or configuring output with StoryQ - c#

I posted this question on the StoryQ discussion boards, but by looking at the (lack of) responses to other questions, activity there seems sparse at best. I thought I'd let everyone here have a go.
Is there a way to modify or configure the output (both output window and file) to include custom strings? For example, one of my stories requires that a specific exception is thrown. To do this, I catch the exception and save it, then in a separate method test that it's non-null and of the required type. I'd like to be able to append the type of the exception to the output (much like parameters are appended to method calls).
For example
.Then(ExceptionIsThrown<ArgumentNullException>)
would result in the following output
then exception is thrown (ArgumentNullException)

Thanks to Giorgio Minardi for guiding me to look into the StoryQ.Formatting namespace. There I discovered that I can override the method formatting using a simple attribute.
The API provides an OverrideMethodFormatAttribute (subclassed from the abstract class MethodFormatAttribute), which works if you want to use a specific string constant, but C# doesn't like the method's type parameters in attributes. This doesn't compile due to the T in the attribute:
[OverrideMethodFormat(string.Format("exception is thrown ({0})", typeof(T).Name))]
private void ExceptionIsThrown<T>() where T : Exception
{
...
}
The solution is to create another MethodFormatAttribute subclass that specifically searches the method for generic types and output them. This subclass is below:
public class GenericMethodFormatAttribute : MethodFormatAttribute
{
private readonly string _textFormat;
public GenericMethodFormatAttribute()
{
_textFormat = null;
}
public GenericMethodFormatAttribute(string textFormat)
{
_textFormat = textFormat;
}
public override string Format(MethodInfo method,
IEnumerable<string> parameters)
{
var generics = method.GetGenericArguments();
if (_textFormat == null)
{
var genericsList = string.Join<Type>(", ", generics);
return string.Format("{0} ({1})",
UnCamel(method.Name),
genericsList);
}
return string.Format(_textFormat, generics);
}
}
Usage is almost like the supplied attribute, except that you optionally supply a format string instead of a string constant. Omitting the format string un-camel-cases the method name just like the default behavior.
[GenericMethodFormatAttribute]
private void ExceptionIsThrown<T>() where T : Exception
{
...
}
This allows me to declare the attribute in my source, while not having to touch the StoryQ code. Ten points to StoryQ for extensibility!

Best thing is to look at the sources of StoryQ, in particular look at the StoryQ.Formatting namespace. To get a particular output you should follow the FluenInterface pattern used within the framework and wrote your own method, something like ThenExceptionIsThrown(Exception ex) and chain it like the other methods in the story.

Related

Is it possible to infer the name of a type on a null check

I'm playing around with an webapi2 project.
Using a controller class ->
calling a service class, which handles business logic, ->
which uses a repository that handles the database calls.
For readability I decided to have nullchecks in my service class (i.e.:
var object = _repository.GetById(5) ?? throw new CustomException(CustomException.Object1NotFound_Exception_Message);
).
This way my controller logic remains clean and readable, avoiding these checks in the controller methods [get/post/put/delete].
This way, I can try/catch my controller logic, and catch (customexception ex)
and call the extention method ex.converttostatuscoderesult. (as shown bellow).
public class CustomException : Exception
{
public const string Object1NotFound_Exception_Message = "Object not found using ID.";
public const string Object2NotFound_Exception_Message = "Object2 not found using ID.";
public const string UserNotAllowedX_Exception_Message = "Current user not allowed to do X.";
public const string UserNotAllowedY_Exception_Message = "Current user not allowed to do Y.";
<~even more strings containing ExceptionMessages>
public int ExceptionStatusCodeDefinition { get; set; }
public CustomException(string message) : base(message)
{
switch (message)
{
case Object1NotFound_Exception_Message:
case Object2NotFound_Exception_Message:
ExceptionStatusCodeDefinition = 404;
break;
case UserNotAllowedX_Exception_Message:
case UserNotAllowedY_Exception_Message:
case UserNotAllowedZ_Exception_Message:
ExceptionStatusCodeDefinition = 403;
break;
default:
ExceptionStatusCodeDefinition = 400;
break;
}
}
}
public static class CustomExceptionExtention
{
public static IActionResult ConvertToStatusCodeResult(this CustomException exception)
{
return new Microsoft.AspNetCore.MvcStatusCodeResult(exception.ExceptionStatusCodeDefinition);
}
}
This method however, requires that I setup the exception messages beforehand.
Which inevitably means i have a way too long list with exception messages.
I tried to refactor this trying to infer the name of the type and having a single exception message NotFound_Exception_Message. And appending the type name at runtime.
At first i tried a switch on Type, which does not work because of compiler reasons (the way i understand it, that if inheritance plays part, its impossible for the compiler to tell which typename i require)
Trying to circumvent this i made this class:
public class TypeCase
{
public static TypeCase GetType(Type type)
{
return new TypeCase(type);
}
public string TypeName { get; set; }
public TypeCase(object type)
{
TypeName = type.GetType().Name;
}
}
This works fine as long as the object has a value, since its impossible to reflect upon an instance of an object if that object reference is null.
I've been breaking my head over this problem.
I'm hoping someone can shed some light on this problem, or explain to me why this is a bad solution.
Because I'm starting to think this approach is a definite code-smell.
(I'm aware that this approach does not return the exception message in the IActionResult. This is an issue too but beyond the scope of this question.)
I would very much appreciate help on this issue.
The direct answer is no, you cannot do what you are trying to do. If you're throwing an exception because a function returned null, you cannot inspect the type of the object that would have been returned.
All you know is the declared type that GetById returns. In other words, if that function is declared as
Foo GetById(int id)
then you know that what it returns is a Foo. If you got a result back you could inspect it to see if its type is Foo or something else that inherits from Foo. But if you don't get a result, all you can know is that it would have been a Foo. But since you were asking for a Foo, that's the only type that matters.
In other words, there's no need to infer the type that the method returns. It declares the type that it returns. You know what the type is because you're calling the method to get an object of that type. If you didn't already know what the type was you wouldn't have a reason to call the method.
Since you know the type, and the only detail that varies one exception message from the next is the type, the next step is to figure out how to communicate the type in the exception message.
To be honest, this is the sort of thing we often overthink. You might be okay with this:
var object = _repository.GetById(5) ?? throw new CustomException("Foo not found using ID.");
Really, how bad is it? Even if the message was just "Foo not found," the stacktrace will show you the method, and from there you can determine that it's trying to retrieve it using an ID.
It's good to use constants, but it's much more important when the values have some significant meaning. If your next exception had a typo - "Blag not foound using ID" - it would be messy, but it wouldn't break anything. I could also see using a constant if the message was much longer and repeated.
That's my first recommendation by far. If you really want to ensure that your exception message is constant, declared only in one place, and you're creating custom exceptions anyway, you could do something like this (although I really, really wouldn't.)
// Really, don't do this.
public class ItemNotFoundByIdException<T> : Exception
{
public ItemNotFoundByIdException()
:base($"{typeof(T).Name} not found by ID.") { }
}
Then if you're trying to get a Foo by ID, you could do this:
var foo = _repository.GetById(5) ?? throw new ItemNotFoundByIdException<Foo>();
But this leads to a complicated hierarchy of exceptions. Unless you or someone else are going to catch this specific exception type and handle it differently from other exception types, it's just extra complexity with no benefit.
I know how we tend to obsess about this sort of thing, but it's not the important part of your application. It's not worth it. I would just hard-code these short exception messages where you need them.
You could try to use generics, and create an helper function to made the check for you.
public static T GetWithNullCheck<T>(Func<T> fetchFunc)
{
T t = fetchFunc();
if (t != null) return t;
var typeOfT = typeof(T);
var typeName = typeOfT.Name;
throw new CustomException($"{typeName} not found.");
// short version
// return fetchFunc() ?? throw new CustomException($"{typeof(T).Name} not found.");
}
And you could use it like this
var object = GetWithNullCheck(() => _repository.GetById(5));

How to use C# attributes to select a method in a class based on a string?

Suppose I have a class like this:
public class MyMethods
{
[SpecialMethod("test")]
public string GetTestString(int i)
{
return string.Format("Hello world {0} times!",i);
}
[SpecialMethod("lorem")]
public string GetSomeLoremIpsumText(int i)
{
// ignores the 'i' variable
return "Lorem ipsum dolor sit amet";
}
// ... more methods with the same signature here ...
public string DefaultMethod(int i)
{
return "The default method happened! The attribute wasn't found.";
}
public string ThisMethodShouldNotShowUpViaAttributes(int i)
{
return "You should not be here.";
}
}
I also have defined the attribute simply like this:
[AttributeUsage(AttributeTargets.Method)]
public class SpecialMethodAttribute : System.Attribute
{
private string _accessor;
public string Accessor
{
get
{
return _accessor;
}
}
public SpecialMethodAttribute(string accessor)
{
_accessor = accessor;
}
}
What I want to be able to do might look like this:
public class MethodAccessViaAttribute
{
private MyMethods _m;
public MethodAccessViaAttribute()
{
_m = new MyMethods();
}
public string CallMethodByAccessor(string accessor, int i)
{
// this is pseudo-code, expressing what I want to be able to do.
Func<int, string> methodToCall = FindAMethodByAttribute(_m, accessor);
if (methodToCall == null)
return _m.DefaultMethod(i);
else
return methodToCall(i);
}
public void Test()
{
// should print "Hello world 3 times!"
Console.WriteLine(CallMethodByAccessor("test",3));
// should print "Lorem ipsum dolor sit amet"
Console.WriteLine(CallMethodByAccessor("lorem",int.MaxValue));
// should print "The default method happened! The attribute wasn't found."
Console.WriteLine(CallMethodByAccessor("I-do-not-exist",0));
}
}
Notice that all methods using the SpecialMethod attribute follow the same method signature. Ideally, the search function would exclude methods not matching the signature, since a try/catch could be used to test if the method matches the Func signature.
Can I get a point in the right direction for how to accomplish this?
I don't like giving "do this instead" answers, but I can't put this inside a comment.
Instead of this, along with all of the supporting code to handle the attributes
public void Test()
{
Console.WriteLine(CallMethodByAccessor("test",3));
Console.WriteLine(CallMethodByAccessor("lorem",int.MaxValue));
Console.WriteLine(CallMethodByAccessor("I-do-not-exist",0));
}
This code does the exact same thing:
public void Test()
{
var methods = new MyMethods();
Console.WriteLine(methods.GetTestString("test", 3));
Console.WriteLine(methods.GetSomeLoremIpsumText("lorem", int.MaxValue));
}
The language is designed on purpose so that if a method doesn't exist, you can't call it. That helps us avoid mistakes at runtime. We don't want our application to execute something or ignore it based on whether or not we spelled a method name correctly. Someone could pull their hair out for hours trying to figure out why the application isn't working and then realize that it's because they misspelled "lorem." Just calling methods the "normal" way prevents all of that. If you misspell a method name then Visual Studio will show an error, the code won't compile, and it's super easy to find and fix. (Plus Intellisense/autocomplete will even help us see the methods that are available.)
Also, if you right-click on a method then Visual Studio will take you right to that method. With the string attributes someone has to follow a lot more code just to figure out which method is actually getting called. And if they need to debug and step through it, they need to step through all that extra stuff.
It's extremely common to have a bunch of classes that each implement the same interface and each have one method. It's good design to have fewer methods - even one - in an interface. (See Interface Segregation Principle.) No one will consider that "ugly." But if we invent our own way of doing it we can really confuse other developers who work on the same code, and it can be challenging to maintain even for the person who wrote it.
So I did figure out how to accomplish this task.
I created a class which all classes that contain methods will inherit from. I then created a private method which actually extract and create Func objects.
We need a method which will search for any method that has the desired attribute. Reflection has a MethodInfo class which represents a method. We can use some LINQ to search all of the methods on the class. We then use a little expression tree fun to generate the Func object that will actually call the method on this specific instance of the class:
// Locates a method on this class that has the SpecialMethod attribute of the given name
private Func<int, string> FindMethodByAccessor(string accessor)
{
// Find all methods containing the attribute
var desiredMethod = this.GetType().GetMethods()
.Where(x => x.GetCustomAttributes(typeof(SpecialMethod), false).Length > 0)
.Where(y => (y.GetCustomAttributes(typeof(SpecialMethod), false).First() as SpecialMethod).Accessor == accessor)
.FirstOrDefault();
if (desiredMethod == null) return null;
// This parameter is the first parameter passed into the method. In this case it is an int.
ParameterExpression x = Expression.Parameter(typeof(int));
// This parameter refers to the instance of the class.
ConstantExpression instance = Expression.Constant(this);
// This generates a piece of code and returns it in a Func object. We effectively are simply calling the method.
return Expression.Lambda<Func<int, string>>(
Expression.Call(instance, desiredMethod, new Expression[] { x }), x).Compile();
}
The idea of expression trees is still new to me, but this function does exactly what I want - it will locate a method on the instance of the class it's running in which has been decorated with the given attribute and return it as a Func object.
We can now finish the method which actually calls the other methods:
public string CallMethodByAccessor(string accessor, int i)
{
Func<int, string> methodToCall = FindMethodByAccessor(accessor);
if (methodToCall == null)
return DefaultMethod(i);
else
return methodToCall(i);
}
public string DefaultMethod(int i) { return "Unknown method requested!"; }
I still have not added checking to see whether the method with the attribute matches the necessary signature, but that could easily be done by working with properties on the MethodInfo object.
Finally, we wrap all this up in a class, which any other class can inherit from. The subclass then implements methods following the signature and decorates them with the attribute. To call the desired method by name, you simply call CallMethodByAccessor.
To respond finally to all of the suggestions to use a different methodology, I respect all of your ideas and, if the use case were different, this would absolutely be overkill and unnecessary. The specific use case at hand involves a Web service which users and developers can configure. The Web service lets a user specify one or more "endpoints". The endpoint in this case is merely a string. The library I am writing receives data from the Web service, and one of the parameters is the desired "endpoint" string. The idea is that the user could write endpoints as methods, give them any function name they desire, and then associate them with the actual endpoint text via the attribute. For example:
[Endpoint("user.login")]
public string performLogin(string credentialString)
{
// ...
}
Since the endpoint name is user.login we cannot simply name a class method with that name. Additionally, even if we did, we would still need to use reflection to dig into the class, extract the correct method, and generate a Func object to call the method. So, in this instance, using attributes simply makes development far easier, because the only alternative would be using a switch/case block that would have to be rigorously maintained. I feel it would be far more easy for a developer to "forget" to add another case block, or to forget to remove a case block which is no longer needed, than it would be to mess up the attributes. The attribute "ties" the endpoint name to the method, rather than having to keep track of both the method name and the endpoint name in a totally different block of code.
Finally, the "default" method is absolutely useful in this case. If a user instructs the Web service to call an endpoint which doesn't exist, the app can return a sensible response, e.g. "The endpoint 'MyEendpoint' does not exist." This would be much easier to debug than simply seeing the API crash!

How can I guarantee that an interface and a class method parameters match without manually checking?

I recently noticed a bug due to a mismatched parameter order in the class to its interface parameter order. I felt that this should have been a compile error. I found out that Interfaces do not constrain the parameter names. So if you see my example below I have firstParameter and secondParameter reversed, I also have parameterOne and parameterTwo, both as valid builds. This may build just fine, but you will likely run into runtime errors.
On the other hand, it does require the order of the types of the parameters to match. So I thought perhaps I do not need to place the parameter names in the interface and just the value types, but that does not work and the interface would still need to provide a description of what the types are in terms of what a consumer would place there.
My Question
Is there a way to guarantee at build time that a class matches the interface parameter names? I would prefer not to do this manually.
The reason this is important is even though the method variables cannot be setup to be used by the interface, someone consuming a service reference or other use of an interface would see the Interface parameters at the time of setup and that is the expected use of the parameters. If I cannot rely on a contract to be exact, what is the point of a contract in the first place?
interface IParameterTest
{
void TwoStringParameters(string firstParameter, string secondParameter);
void TwoStringParametersAndAnInt(string firstParameter, string secondParameter, int thirdParameter);
}
public class ParameterTest : IParameterTest
{
//Builds and matches interface
//public void TwoStringParameters(string firstParameter, string secondParameter)
//{
// throw new NotImplementedException();
//}
//Builds and does not match interface
//public void TwoStringParameters(string secondParameter, string firstParameter)
//{
// throw new NotImplementedException();
//}
//Builds and does not match interface
public void TwoStringParameters(string parameterOne, string parameterTwo)
{
throw new NotImplementedException();
}
//Builds and matches interface
public void TwoStringParametersAndAnInt(string firstParameter, string secondParameter, int thirdParameter)
{
throw new NotImplementedException();
}
//Does not build or match interface
//public void TwoStringParametersAndAnInt(int firstParameter, string secondParameter, string thirdParameter)
//{
// throw new NotImplementedException();
//}
}
Is there a way to guarantee at build time that a class matches the interface parameter names? I would prefer not to do this manually.
Not within the C# language. However:
You could write a unit test to check, reasonably easily. Not quite build time, but still early enough to catch errors before they're big problems.
You could write a Roslyn code diagnostic to flag it as an error (and even provide a code fix for it).
Of course, the unit test could be written via Roslyn as well, but you could do it fairly easily just using plain reflection.
It's not entirely clear from your question whether you've spotted the really nasty problem with parameter names being wrong, by the way - it's not just in terms of human readability, but it can significantly affect behaviour if you use named arguments. For example, suppose you have code like this:
public interface IFoo
{
void Foo(int x, int y);
}
public class FooImpl : IFoo
{
public void Foo(int y, int x) { ... }
}
...
IFoo foo = new FooImpl();
foo.Foo(x: 10, y: 20); // Equivalent to foo.Foo(10, 20)
Now if someone decides to use var instead, the compile-time type of foo is changed, so suddenly the named arguments map to different parameters.
var foo = new FooImpl();
foo.Foo(x: 10, y: 20); // Equivalent to foo.Foo(20, 10)
Perfectly valid code... but with a different meaning to the previous code. There are other times that changing the compile-time type of a variable can affect things, but that's usually around overloading etc... this is in the simple case where there really is just one method.
As Jon says, C# doesn't really care what the parameters are called, but if you wanted to reflectively assert the parameter names for yourself; either at start up or in a unit test, you could use something like this:
public class Program
{
public static void Main(string[] args)
{
var assembly = Assembly.GetAssembly(typeof(Program));
var types = assembly
.GetTypes()
.Where(x => x.IsClass && x.GetInterfaces().Any());
foreach (var type in types)
{
var interfaces = type.GetInterfaces().Where(x => x.Assembly == assembly);
foreach (var iface in interfaces)
{
var classMethods = type.GetMethods();
foreach (var interfaceMethod in iface.GetMethods())
{
var classMethod = classMethods.First(x => x.ToString() == interfaceMethod.ToString());
Debug.Assert(
interfaceMethod.GetParameters().Select(x => x.Name).SequenceEqual(classMethod.GetParameters().Select(x => x.Name)),
"Incorrect parameter names in method: " + type.Name + "." + classMethod.Name);
}
}
}
}
public interface ITest
{
void MethodA(string first, string second);
}
public class TestA : ITest
{
public void MethodA(string first, string second) { }
}
public class TestB : ITest
{
public void MethodA(string second, string first) { }
}
}
FxCop already has a rule to enforce this. You can enable code analysis to run on build in your project properties, then configure the code analysis rule set to treat that warning as an error. If you integrate that into your build process you will force all your developers to address that issue before their builds will succeed.
Yes, you have a few build-time alternatives. You'd have to weigh whether they are worth the effort.
create a custom static code analysis rule (what used to be FxCop)
use Roslyn and plug it into MSBuild
something completely custom plugged into MSBuild that fails the build if you don't have a match
Your question
If I cannot rely on a contract to be exact, what is the point of a contract in the first place?
is worth considering, however names of required parameters as contractual requirement may be considered quite narrow. There is a compile-time way to fix this, and you've even suggested it in your question: you are bound by the order, number and type of parameters. If you needed a very strict interface, you could abstract the parameters by wrapping the simple types, preventing a case such as accidental argument swapping.
Again, you'd have to weigh whether it's worth it. You're buying interface safety at the cost of more code and cognitive load.
In this case I would suggest a much better solution is to refactor the interface to use the parameter object design pattern rather than messing around with enforcing the parameter names of two strings are implemented in the correct order.
Example if string 1 was "firstName" and string 2 was "lastName" you are much better off with a class with two properties FirstName and SecondName and then have your interface depend on this parameter object rather than low level data types such as strings.

How to get the methodname from a known method?

Is it possible to get the name of another method in the same class but without using a manually written string?
class MyClass {
private void doThis()
{
// Wanted something like this
print(otherMethod.name.ToString());
}
private void otherMethod()
{
}
}
You may ask why: well the reason is that I must invoke the method later on like this Invoke("otherMethod"), however I don't want to hardcode this string myself as I can't refactor it anymore within the project.
One approach is you can wrap it into delegate Action, then you can access the name of method:
string name = new Action(otherMethod).Method.Name;
You can use reflection (example - http://www.csharp-examples.net/get-method-names/) to get the method names. You can then look for the method that you're looking for by name, parameters or even use an attribute to tag it.
But the real question is - are you sure this is what you need? This looks as if you don't really need reflection, but need to think over your design. If you already know what method you're going to invoke, why do you need the name? How about a using a delegate? Or exposing the method via an interface and storing a reference to some class implementing it?
Try this:
MethodInfo method = this.GetType().GetMethod("otherMethod");
object result = method.Invoke(this, new object[] { });
Btw. I also found (in the expansions of the internet) an alternative solution for only getting the string of a method. It also works with parameters and return types:
System.Func<float, string> sysFunc = this.MyFunction;
string s = sysFunc.Method.Name; // prints "MyFunction"
public string MyFunction(float number)
{
return "hello world";
}

How do I return a C# web service that has a generic property?

I am creating a web service, and want to be a bit more elegant with the return data, instead of having lots of properties that the consumer needs to check.
Depending on what data is generated behind the scenes, I need to be able to return error data, or the data the consumer was expecting.
Instead of having a large flat object, and filling the properties when needed, and letting the user check a 'success' flag, I'd like a single property, Data, to be either an instance of an error class, or an instance of a success class.
This is kind of what I want to do:
class ItemResponse
{
public bool Success { get; set; }
public T Data{ get; set; }
}
if( /*acceptance criteria*/ )
{
ItemResponse<SuccessData> resp = new ItemResponse<SuccessData>();
resp.Data = new SuccessData();
}
else
{
ItemResponse<ErrorData> resp = new ItemResponse<ErrorData>();
resp.Data = new ErrorData();
}
return resp;
public class SuccessData
{
}
public class ErrorData
{
}
Then have the web method return the object, with the generic property.
Is this possible, and if so, how would I do it, given that the webmethod return type has to be typed correctly?
Generics are a tool for adding type safety during compile time. Consequently, the concrete type used by the consumer of the class must be known at compile time. If you create a function
List<T> myFunction<T>() {...}
...then you need to specify T when calling it, e.g.
var myResult = myFunction<int>();
...which makes the concrete type known at compile time. (Even if you don't specify T because it can be infered, the concrete type is also known at compile time.)
You, however, want the generic type of Data to be determined at run-time: If an error occured, you return an ItemResponse<SuccessData>, otherwise an ItemResponse<ErrorData>. That's just not how generics work.
Short version, you can't do what you're suggesting as you've laid it out.
Long(er) version Part A:
A web service can be considered like a class' method, and actually is a method off of your web service class. I would recommend going over some web service tutorials in order to get a better grasp of the mechanics behind setting up a web service. MSDN has a number of Microsoft stack specific tutorials that are easily found with your favorite search engine.
The return object off of a method is not allowed to have polymorphic behavior, which is essentially what your asking for.
This pseudo code is equivalent to what you're trying to create and that's why the compiler isn't allowing it. It doesn't know which DoSomething() you're attempting to call.
class myFoo
{
public SuccessResponse DoSomething() {....}
public ErrorResponse DoSomething() {....}
}
Alternatively, you could envisage something like this:
public [SuccessResponse | ErrorResponse] DoSomething()
but that fails for what should be obvious reasons as well. C# simply doesn't support polymorphic returns.
Part B
Even if we focus on just resp.Data, that object still has to be declared as some sort of type.
class Response
{
public Collection<someType> Data;
}
If your SuccessData and ErrorData implement the same interface then someType could simply be IyourInterface but that raises another issue. Namely, how will the end user know whether they were given good data in Data or whether there is an error response tucked in there instead.
WCF, I believe, will be nice enough to serialize IyourInterface for you so long as you declare it as a public part of the WCF service object. But that still doesn't resolve how your end user will know what to do.
If you're willing for a little less elegance in the response, a classic pattern is to simply bundle your success data and error objects together into another response class like this:
class myResponse
{
public SuccessResponse myRespData;
public ErrorResponse myError
}
Now, the end user checks to see if there's an error if they care. Presuming no error, then they go and look into the response data.
Based upon your comment, yes, you can do the following too:
class Response
{
public List<IYourData> Data;
public YourEnum ReturnType;
}
public class ResponseData : IYourData { ... }
public class ErrorData : IYourData { ... }
And then on the client, you can perform a simple check like this:
if( ReturnType == YourEnum.Success ) { ... }
else if( ReturnType == YourEnum.Error ) { ... }
else ...
WCF will handle the serialization of List for you. It'll either convert to an array or pass the collection directly depending upon what settings you have in place. There are some SO Q&A's that handle that particular aspect.

Categories

Resources