MS Azure — неверный запрос 400

Я продолжаю получать ошибку неправильного запроса каждый раз, когда запускаю эту строку кода:

List<Account> accounts = await App.accountTable.Where(account => account.EmailAddress == email).ToListAsync();

Вот сообщение об ошибке:

A first chance exception of type 'Microsoft.WindowsAzure.MobileServices.MobileServiceInvalidOperationException' occurred in mscorlib.dll
Microsoft.WindowsAzure.MobileServices.MobileServiceInvalidOperationException: The request could not be completed.  (Bad Request)
   at Microsoft.WindowsAzure.MobileServices.MobileServiceHttpClient.<ThrowInvalidResponse>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at Microsoft.WindowsAzure.MobileServices.MobileServiceHttpClient.<SendRequestAsync>d__1d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Microsoft.WindowsAzure.MobileServices.MobileServiceHttpClient.<RequestAsync>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Microsoft.WindowsAzure.MobileServices.MobileServiceTable.<ReadAsync>d__b.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Microsoft.WindowsAzure.MobileServices.MobileServiceTable.<ReadAsync>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Microsoft.WindowsAzure.MobileServices.Query.MobileServiceTableQueryProvider.<Execute>d__8`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Microsoft.WindowsAzure.MobileServices.Query.MobileServiceTableQueryProvider.<Execute>d__3`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Microsoft.WindowsAzure.MobileServices.MobileServiceTableQuery`1.<ToListAsync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at eventsphere.Utilities.ValidationUtility.<CheckEmailExistsError>d__2.MoveNext()

Однако у меня есть другая строка, которая в основном такая же, и она отлично работает:

List<Account> accounts = await App.accountTable.Where(account => account.Username == username).ToListAsync();

Я буквально не понимаю, почему одна строка выдает мне ошибку, а другая нет, поскольку все, что изменилось, — это свойство таблицы Account, которую я запрашиваю.

Структура таблицы учетных записей: (не позволяю мне публиковать изображение, потому что у меня недостаточно репутации)

CREATE TABLE [eventsphere].[Accounts] (
    [Id]           NVARCHAR (128)     DEFAULT (newid()) NOT NULL,
    [AccountId]    INT                IDENTITY (1, 1) NOT NULL,
    [Username]     NVARCHAR (MAX)     NULL,
    [EmailAddress] NVARCHAR (MAX)     NULL,
    [Password]     NVARCHAR (MAX)     NULL,
    [IsBusiness]   BIT                NOT NULL,
    [User_Id]      NVARCHAR (128)     NULL,
    [Business_Id]  NVARCHAR (128)     NULL,
    [Version]      ROWVERSION         NOT NULL,
    [CreatedAt]    DATETIMEOFFSET (7) DEFAULT (sysutcdatetime()) NOT NULL,
    [UpdatedAt]    DATETIMEOFFSET (7) NULL,
    [Deleted]      BIT                NOT NULL,
    CONSTRAINT [PK_eventsphere.Accounts] PRIMARY KEY NONCLUSTERED ([Id] ASC),
    CONSTRAINT [FK_eventsphere.Accounts_eventsphere.Businesses_Business_Id] FOREIGN KEY ([Business_Id]) REFERENCES [eventsphere].[Businesses] ([Id]),
    CONSTRAINT [FK_eventsphere.Accounts_eventsphere.Users_User_Id] FOREIGN KEY ([User_Id]) REFERENCES [eventsphere].[Users] ([Id])
);

Любой вклад будет оценен! Заранее спасибо :)


person Graham Kelly    schedule 25.01.2015    source источник
comment
Вы можете проверить, есть ли в вашей таблице столбец адреса электронной почты? также опубликуйте структуру своей таблицы в вопросе.   -  person Raja Nadar    schedule 25.01.2015
comment
Отредактировал мой пост, чтобы включить структуру таблицы Accounts   -  person Graham Kelly    schedule 25.01.2015
comment
В перехватываемом MobileServiceInvalidOperationException есть свойство с именем Response, которое содержит ответ от службы. Можете ли вы просмотреть содержимое ответа, чтобы узнать, есть ли в нем какая-либо информация о том, почему сервер посчитал запрос неверным?   -  person carlosfigueira    schedule 25.01.2015
comment
Привет, вот ответное сообщение, оно совершенно бесполезно: {StatusCode: 400, ReasonPhrase: "Bad Request", Version: 1.1, Content: System.Net.Http.StreamContent, Headers: {Pragma: no-cache X -SourceFiles:?? = UTF-8 B QzpcVXNlcnNcR3JhaGFtXERlc2t0b3BcUmVwb3NpdG9yeVxEaXNzZXJ0YXRpb25cdHJ1bmtccHJvamVjdFxldmVudHNwaGVyZV9tdWx0aVxldmVudHNwaGVyZVNlcnZpY2VcdGFibGVzXEFjY291bnQ = Cache-Control: нет кэша Дата: вс, 25 января 2015 18:43:08 GMT Сервер: Microsoft-IIS / 8.0 X-Powered-By: ASP. NET Content-Length: 2389 Content-Type: application/json; charset=utf-8 Срок действия: 0 }}   -  person Graham Kelly    schedule 25.01.2015


Ответы (2)


Как выглядит ваше свойство EmailAddress на стороне клиента? В какой-то момент он становится строчным - есть ли у вас какие-либо атрибуты в вашей клиентской модели?

Причина, по которой «имя пользователя» и «имя пользователя» работают, заключается в том, что сервер допускает как верхний, так и нижний регистр с первой буквой свойств. Например, адрес электронной почты должен работать.

person brettsam    schedule 29.01.2015
comment
Привет, мы выяснили, что проблема заключалась в том, что веб-API не синхронизировался с таблицами, отсюда и неверный запрос. Глупая ошибка с нашей стороны, даже не подумал об этом (я новичок в Azure). Спасибо за ответ! - person Graham Kelly; 01.02.2015

(Не могу комментировать, пока у меня не будет 10 репутации, поэтому я публикую это как ответ..)

Вот запрос запроса, который сгенерирован и отправлен в локальную копию нашей базы данных:

http://localhost:59737/tables/Account?$filter=(emailaddress%20eq%20%27email%40test.com%27)    

который возвращает этот объект (я думаю, что свойство "сообщение" - это все, что важно):

{"message":"The query specified in the URI is not valid. Could not find a property named 'emailaddress' on type 'eventsphereService.DataObjects.Account'.","exceptionMessage":"Could not find a property named 'emailaddress' on type 'eventsphereService.DataObjects.Account'.","exceptionType":"Microsoft.Data.OData.ODataException","stackTrace":"   at Microsoft.Data.OData.Query.EndPathBinder.GeneratePropertyAccessQueryForOpenType(EndPathToken endPathToken, SingleValueNode parentNode)\r\n   at Microsoft.Data.OData.Query.EndPathBinder.BindEndPath(EndPathToken endPathToken, BindingState state)\r\n   at Microsoft.Data.OData.Query.MetadataBinder.BindEndPath(EndPathToken endPathToken)\r\n   at Microsoft.Data.OData.Query.MetadataBinder.Bind(QueryToken token)\r\n   at Microsoft.Data.OData.Query.BinaryOperatorBinder.GetOperandFromToken(BinaryOperatorKind operatorKind, QueryToken queryToken)\r\n   at Microsoft.Data.OData.Query.BinaryOperatorBinder.BindBinaryOperator(BinaryOperatorToken binaryOperatorToken)\r\n   at Microsoft.Data.OData.Query.MetadataBinder.BindBinaryOperator(BinaryOperatorToken binaryOperatorToken)\r\n   at Microsoft.Data.OData.Query.MetadataBinder.Bind(QueryToken token)\r\n   at Microsoft.Data.OData.Query.FilterBinder.BindFilter(QueryToken filter)\r\n   at Microsoft.Data.OData.Query.ODataUriParser.ParseFilterImplementation(String filter, IEdmType elementType, IEdmEntitySet entitySet)\r\n   at System.Web.Http.OData.Query.FilterQueryOption.get_FilterClause()\r\n   at System.Web.Http.OData.Query.Validators.FilterQueryValidator.Validate(FilterQueryOption filterQueryOption, ODataValidationSettings settings)\r\n   at System.Web.Http.OData.Query.FilterQueryOption.Validate(ODataValidationSettings validationSettings)\r\n   at System.Web.Http.OData.Query.Validators.ODataQueryValidator.Validate(ODataQueryOptions options, ODataValidationSettings validationSettings)\r\n   at System.Web.Http.OData.Query.ODataQueryOptions.Validate(ODataValidationSettings validationSettings)\r\n   at System.Web.Http.OData.EnableQueryAttribute.ValidateQuery(HttpRequestMessage request, ODataQueryOptions queryOptions)\r\n   at System.Web.Http.OData.EnableQueryAttribute.ExecuteQuery(Object response, HttpRequestMessage request, HttpActionDescriptor actionDescriptor)\r\n   at System.Web.Http.OData.EnableQueryAttribute.OnActionExecuted(HttpActionExecutedContext actionExecutedContext)"}

однако при изменении (нами в браузере) следующим образом:

http://localhost:59737/tables/Account?$filter=(EmailAddress%20eq%20%27email%40test.com%27)

он возвращает некоторые данные.

При запросе поля «Имя пользователя» и «Имя пользователя», и «имя пользователя» возвращают данные.

Объект данных учетной записи определяется как:

public class Account : EntityData
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int AccountId { get; set; }
    public string Username { get; set; }
    [DataType(DataType.EmailAddress)]
    public string EmailAddress { get; set; }
    public string Password { get; set; }
    public bool IsBusiness { get; set; }

    public string User_Id { get; set; }
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    [ForeignKey("User_Id")]
    [Association("UserIdAssociation", "UserId", "Id")]
    [Column(Order = 1)]
    public virtual User User { get; set; }

    public string Business_Id { get; set; }
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    [ForeignKey("Business_Id")]
    [Association("BusinessIdAssociation", "BusinessId", "Id")]
    public virtual Business Business { get; set; }
}
person IEatSandvich    schedule 26.01.2015