简体   繁体   中英

Using an interface as an out parameter in WCF web service

My situation is this. On every call to my web service, I have an out parameter which is an error object. If there is no error, the object indicates so by being empty. If there is an error then different properties are populated such as a "HasError" field, "ErrorMessage", "PrettyMessage", etc. What I'm trying to do with this now is create different types of Error object which all implement an Error interface which I've defined already. I then want to be able to have the out parameter be something like "out IMyError error" and then be able to set that error object either to one of my implementations of that interface depending on what kind of error I get in my method. The problem I'm getting is that serialization doesn't seem to like this. The method runs fine, but I don't get any data back on the client end. Here is some code to hopefully clarify.

My interface

public interface IMyError
{
    bool HasError { get; set; }
    string ErrorType { get; set; }
    string PrettyErrMsg { get; set; }
}

An example class implementation

[Serializable]
[DataContract]
public class AspError : IMyError
{
    public AspError(Exception exception)
    {
        this.HasError = true;
        this.PrettyErrMsg = "An ASP Exception was thrown";
        this.ExceptionMsg = exception.Message;
        this.StackTrace = exception.StackTrace;
    }

    [DataMember(Name = "has_error", IsRequired = true)]
    public bool HasError { get; set; }

    [DataMember(Name = "error_type", IsRequired = true)]
    public string ErrorType
    {
        get
        {
            return "ASP";
        }
        set
        {
        }
    }

    [DataMember(Name = "pretty_error", IsRequired = true)]
    public string PrettyErrMsg { get; set; }

    [DataMember(Name = "exception", IsRequired = true)]
    public string ExceptionMsg { get; set; }

    [DataMember(Name = "stack_trace", IsRequired = true)]
    public string StackTrace { get; set; }
}

And the method in my WCF service

public bool MyMethod(out IMyError error)
{
    error = new MyError() { HasError = false };

    try
    {
        // do some code            
    }
    catch (Exception exception)
    {
        error = new AspError(exception);
        return false;
    }
}

What I want is for that method, when an exception is caught, to return a AspError formatted as json the way it has worked in the past before I tried doing it as an interface. Or if an different implemented class of IMyError occurs then return THAT type formatted as json. I assumed it could work since they are both IMyError classes.

You need to send hint to client how to deserialize your interface. WCF does that with KnownTypeAttribute .

Your service should be changed to look like this:

[KnownType(typeof(AspError))]
public bool MyMethod(out IMyError error)
{
    ...
}

You can find more details in MSDN - http://msdn.microsoft.com/en-us/library/ms730167.aspx

And of course your client should have access to assembly with type AspError to be able to construct that type.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM