#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
этот интерфейс мне очень мешает.