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

#c# #asp.net #wcf #web-services #guid

#c# #asp.net #wcf #веб-службы #guid

Вопрос:

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

В частности, идентификатор Guid, передаваемый вызову службы, состоит из нулей, как будто он еще не был создан…

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

Вот код:

защищенный void button_click(отправитель объекта, EventArgs e)
{
 var title = titleTextbox.Текст;
 var guid = Guid.Новый гид();

 var CreateIssueResponse = прокси.CreateIssue(новый запрос CreateIssueRequest
 { 
 User = пользователь,
IssueDataContract = новый IssueDataContract(заголовок, идентификатор guid)
 });

 DataBind();
}

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

CreateIssueRequest.cs Создать запрос.cs:

[DataContract(Namespace = "my-service-namespace")]
открытый класс CreateIssueRequest : База запросов
{

 публичный запрос CreateIssueRequest() { }

 публичный запрос CreateIssueRequest(UserDataContract user, IssueDataContract проблема)
 {
 UserDataContract = пользователь;
 IssueDataContract = выпуск;
 }

 [Элемент данных]
 общедоступный UserDataContract UserDataContract;

 [Элемент данных]
 публичный выданный контракт Выданный контракт;
}

IssueDataContract.cs

[DataContract]
публичный класс IssueDataContract: IIssue
{
 внутренний IssueDataContract() { }

 public IssueDataContract(заголовок строки, идентификатор guid guid)
 {
 Title = название;
 Guid = идентификатор пользователя;
 }

 [Элемент данных]
 public int ? ID { получить; внутренний набор; }

 [Элемент данных]
 заголовок общедоступной строки { get; set; }

 [Элемент данных]
 общедоступная дата-время? DateCreated { get; внутренний набор; }

 [Элемент данных]
 общедоступная строка SupportAgentName { get; внутренний набор; }

 [Элемент данных]
 статус общедоступной строки { получить; внутренний набор; }

 [Элемент данных]
 общедоступный идентификатор Guid Guid { get; set; }
}

CreateIssue (из контракта IssueTrackerService.cs):

[ServiceContract(Name = "IIssueTrackerService", Namespace = "my-service-namespace")]
общедоступный интерфейс IIssueTrackerService
{ 
 [OperationContract]
 [FaultContract(typeof(FaultBase))]
 [FaultContract(typeof(ArgumentException))]
 [FaultContract(typeof(ArgumentNullException))]
 CreateIssueResponse CreateIssue(запрос CreateIssueRequest);
}

Service Implementation (IssueTrackerService.cs):

публичный класс IssueTrackerService: IIssueTrackerService
{
 только для чтения IUserIssueRepository userIssueRepository;

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

 public CreateIssueResponse CreateIssue(запрос CreateIssueRequest)
 {
 // Извлеките пользователя из запроса и подтвердите
var user = request .UserDataContract;
 Проверка пользователя.Проверка (user, true);

 // Извлеките проблему из запроса и подтвердите
var issue = request .IssueDataContract;
 issueValidator.Проверка (проблема, истина);

 // Если пользователь не существует, добавьте его через репозиторий
if (userIssueRepository.getUser(user.ID) == null)
 Пользовательское хранилище.AddUser (пользователь.ToEntity());

 // Добавьте проблему через репозиторий, запишите новый идентификатор проблемы
var IssueID = userIssueRepository .Добавить выпуск (user.ToEntity(), проблема.ToEntity());

 // Получите проблему с обновленными полями из db
var issueUpdate = userIssueRepository.GetIssue(IssueID);

 // Подготовьте и верните ответ
var response = new CreateIssueResponse { IssueDataContract = issueUpdate .ToDataContract() };
возвращает ответ;
 }
}

SqlUserIssueRepository.cs

общедоступный класс SqlUserIssueRepository: IUserIssueRepository
{
 UserIssueEntities db только для чтения;

 общедоступный SqlUserIssueRepository()
 {
var ConnectionString = ConfigurationManager .ConnectionStrings["connStr"] .Строка подключения;
 db = новые пользовательские идентификаторы (строка подключения);
 }

 // User и Issue - это сложные типы EF, которые реализуют IUser и IIssue соответственно.
 // Интерфейс IIssue определяет свойство для идентификатора Guid
public int AddIssue(пользователь user, проблема issue)
 {
db.CreateUser(user.ИДЕНТИФИКАТОР, пользователь.Имя пользователя, пользователь.Имя пользователя.Фамилия, пользователь.Электронная почта, пользователь.Телефон);
 вернуть пользователя.ID;
 }
}

IIssue.cs

проблема с открытым интерфейсом
{
 int? ID { get; }
 заголовок строки { get; set; }
 Дата-время? DateCreated { get; }
 строка SupportAgentName { get; }
 статус строки { получить; }
 Guid Guid { get; set; }
}

Комментарии:

1. можете ли вы показать свой контракт на обслуживание / данные?

2. Проблема, похоже, где-то еще дальше по конвейеру. Показать веб-метод службы и код записи базы данных.

3. конструкторы, если IssueDataContract не совпадают

4. Подумайте о том, что это будет означать, если .NET выполнит код из последовательности, когда есть зависимость от последовательности. Подумав об этом, вы понимаете, что ваш код выполняется в правильном порядке, так что это другая проблема.

Ответ №1:

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

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

Ответ №2:

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

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

публичный класс IssueDataContract: IIssue

Для

публичный класс IssueDataContract

этот интерфейс мне очень мешает.