Служба WCF слишком рано называется в WebForm?

У меня есть странная проблема, когда кажется, что моя служба WCF вызывается слишком рано, когда вызывается из обработчика событий WebForms.

В частности, направляющий сигнал, передаваемый служебному вызову, является нулевым, как если бы он еще не был создан...

Когда я запускаю отладчик и помещаю часы в переменную guid, я вижу, что он действительно создается как действительный, отличный от нуля Guid.

Здесь код:

protected void button_click(object sender, EventArgs e)
{
    var title = titleTextbox.Text;
    var guid = Guid.NewGuid();

    var CreateIssueResponse = proxy.CreateIssue(new CreateIssueRequest
    {                                                              
        User = user,                                       
        IssueDataContract = new IssueDataContract(title, guid)
    });

    dataBind();
}

Вот контракты:

CreateIssueRequest.cs:

[DataContract(Namespace = "my-service-namespace")]
public class CreateIssueRequest : RequestBase
{

    public CreateIssueRequest() { }

    public CreateIssueRequest(UserDataContract user, IssueDataContract issue)
    {
        UserDataContract = user;
        IssueDataContract = issue;
    }

    [DataMember]
    public UserDataContract UserDataContract;

    [DataMember]
    public IssueDataContract IssueDataContract;
}

IssueDataContract.cs

[DataContract]
public class IssueDataContract : IIssue
{
    internal IssueDataContract() { }

    public IssueDataContract(string title, Guid guid)
    {
        Title = title;
        Guid  = guid;
    }

    [DataMember]
    public int? ID { get; internal set; }

    [DataMember]
    public string Title { get; set; }

    [DataMember]
    public DateTime? DateCreated { get; internal set; }

    [DataMember]
    public string SupportAgentName { get; internal set; }

    [DataMember]
    public string Status { get; internal set; }

    [DataMember]
    public Guid Guid { get; set; }
}

CreateIssue (из договора IssueTrackerService.cs):

[ServiceContract(Name = "IIssueTrackerService", Namespace = "my-service-namespace")]
public interface IIssueTrackerService
{        
    [OperationContract]
    [FaultContract(typeof(FaultBase))]
    [FaultContract(typeof(ArgumentException))]
    [FaultContract(typeof(ArgumentNullException))]
    CreateIssueResponse CreateIssue(CreateIssueRequest request);
}

Реализация службы (IssueTrackerService.cs):

public class IssueTrackerService : IIssueTrackerService
{
    readonly IUserIssueRepository userIssueRepository;

    public IssueTrackerService(IUserIssueRepository userIssueRepository)
    {
        this.userIssueRepository = userIssueRepository;
    }

    public CreateIssueResponse CreateIssue(CreateIssueRequest request)
    {
        // Extract the user from the request, and validate
        var user  = request.UserDataContract;
        userValidator.Validate(user, true);

        // Extract the issue from the request, and validate
        var issue = request.IssueDataContract;
        issueValidator.Validate(issue, true);

        // If the user doesn't exist, add them via the repo
        if (userIssueRepository.GetUser(user.ID) == null)
            userIssueRepository.AddUser(user.ToEntity());

        // Add the issue via the repo, record the new issue id
        var issueId = userIssueRepository.AddIssue(user.ToEntity(), issue.ToEntity());

        // Get the issue with it updated fields from the db
        var issueUpdate = userIssueRepository.GetIssue(issueId);

        // Prepare and return the response
        var response = new CreateIssueResponse { IssueDataContract = issueUpdate.ToDataContract() };
        return response;
    }
}

SqlUserIssueRepository.cs

public class SqlUserIssueRepository : IUserIssueRepository
{
    readonly UserIssueEntities db;

    public SqlUserIssueRepository()
    {
        var connectionString = ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;
        db = new UserIssueEntities(connectionString);
    }

    // User and Issue are EF complex types that implement IUser & IIssue respectively.
    // The IIssue interface defines a property for Guid
    public int AddIssue(User user, Issue issue)
    {
        db.CreateUser(user.ID, user.Username, user.FirstName, user.LastName, user.Email, user.Phone);
        return user.ID;
    }
}

IIssue.cs

public interface IIssue
{
    int?      ID               { get; }
    string    Title            { get; set; }
    DateTime? DateCreated      { get; }
    string    SupportAgentName { get; }
    string    Status           { get; }
    Guid      Guid             { get; set; }
}

Ответ 1

Я не думаю, что ваша проблема в том, что ваш "сервис WCF вызывается слишком рано". Вероятно, это reset где-то или не сериализуется/десериализуется правильно. Сначала я посмотрю ваше свойство Guid на вашем RequestObject.

Кроме того, если вы используете привязку http, вы также можете запустить Fiddler и опросить исходящий запрос, чтобы убедиться, что значение Guid правильное, поскольку оно отправляется от вашего клиента.

Ответ 2

Я не уверен, но постараюсь сделать его "более ясным", поскольку причина, кажется, где-то в другом месте. Вы являетесь беспорядочным интерфейсом (который не является хорошей идеей вообще иметь только свойства в интерфейсе) с свойствами класса, вы "добавили" некоторые мутаторы, а затем помечены как DataMembers... Я бы снял там причину.

Я бы начал с изменения

открытый класс IssueDataContract: IIssue

к

открытый класс IssueDataContract

этот интерфейс очень запутанный для меня.