MS Azure - Bad Request 400

2019-03-04 03:29发布

I keep getting a bad request error every time I run this line of code:

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

Here is the error message:

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()

However I have another line which is basically the same and it works fine:

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

I am literally clueless as to why one line would give me an error and the other wouldn't since all that has changed is the property of the Account table I am querying.

Account Table Structure: (Won't let me post an image because I haven't enough reputation)

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])
);

Any input would be appreciated! Thanks in advance :)

2条回答
Lonely孤独者°
2楼-- · 2019-03-04 04:05

What does your client-side EmailAddress property look like? It is getting lowercased at some point -- do you have any attributes on it in your client model?

The reason that 'Username' and 'username' both work is because the server allows both upper-and lower-case with the first letter of properties. For example, 'emailAddress' should work.

查看更多
聊天终结者
3楼-- · 2019-03-04 04:12

(Can't comment until I have 10 reputation so I'm posting this as an answer..)

Here is the query request that's generated and sent to the local copy of our database:

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

which returns this object (I think the "message" property is all that's important):

{"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)"}

however when modified (by us, in the browser) as follows:

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

it returns some data.

When querying the Username field both "Username" and "username" returns data.

The Account DataObject is defined as:

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; }
}
查看更多
登录 后发表回答