如何在序列化soap时强制设置某个成员值

时间:2011-09-21 06:05:07

标签: c# .net design-patterns

我有这个方法:

[WebMethod]
public OpenAccountResult OpenAccount()
{
    OpenAccountResult test = new OpenAccountResult(/*true*/)//the true  here wont let the object to be serialized
    {
        //Success = true,
        AccountNumber = "test111"
    };
    return test;
}

OpenAccountResult实际上正在扩展BaseSoapAnswer,所以我为BaseSoapAnswer创建了一个带有bool参数的Success构造函数,但是我得到了一个异常需要参数的构造函数无法序列化。

例外:

[InvalidOperationException: WebService.Services.TradingSystem.OpenAccountResult cannot be serialized because it does not have a parameterless constructor.]

如何强制每个*Result个实例声明bool Success。 我希望通过实现或继承来实现它,因为它会有很多*Result,我不希望任何其他程序员忘记它。

在底线,我想以每个实例必须设置成功的方式构建* Result,如果忘记了,出于安全原因,代码将不会被编译(您可能理解,如果我不需要序列化我不会有问题。)

感谢。

2 个答案:

答案 0 :(得分:3)

创建一个额外的无参数构造函数并将其标记为Obsolete(“仅用于序列化”,true)。 这将允许编译器使用构造函数,但是当您尝试使用此构造函数时,您的用户代码将无法编译,即使是继承:

public abstract class MyBaseClass
{
    public bool Success { get; set; }

    [Obsolete("only for serialization", true)]
    public MyBaseClass(){}

    public MyBaseClass(bool success) { this.Success = success; }
}

public class MyConcreteClass
{
    [Obsolete("only for serialization", true)]
    public MyConcreteClass() : base() {}

    public MyBaseClass(bool success) : base(success) { /* whatever in this instance */ }
}

你甚至可以省略基础构造函数:

public abstract class MyBaseClass
{
    public bool Success { get; set; }

    public MyBaseClass(bool success) { this.Success = success; }
}

public class MyConcreteClass
{
    [Obsolete("only for serialization", true)]
    /* calling base constructor with false success parameter */
    public MyConcreteClass() : base(false) {}

    public MyBaseClass(bool success) : base(success) { /* whatever in this instance */ }
}

答案 1 :(得分:2)

您需要有一个无参数构造函数才能被序列化。但是您希望每个Result都有Success = true

public OpenAccountResult()
{
    Success = true;
}

或者,如果它不是总是为真并且您想要指定Success,那么您可以只使用两个构造函数:

// required for serialization
public OpenAccountResult()
{
}

// alternate constructor for you to use
public OpenAccountResult(bool successValue)
{
    Success = successValue;
}

如果您不想设置每个Result构造函数,请在基类中执行此操作。如果基类没有Success属性,那么创建一个子类,所有结果类都可以从中派生出来:

public abstract class Result : BaseSoapAnswer
{
    public Result()
    {
        this.Success = true;
    }

    public bool Success { get; set; }
}

public class OpenAccountResult : Result 
// ...
public class AnotherResult : Result