Question

I've a very strange problem (using SL5, WCF DataServices 5.0.1): I've a ServiceOperation with 2 String parameters (Username, Password) which checks if the users exists

public IQueryable<User> Login(string username, string password)
{...}

When I try to call this everythings works fine, except the case that the password-hash contains a '+' character in it. In this case, it seems if it is replaced by a whitespace-character:

var pwd = CRQWKrKzCcQVnlhk2zl0j5QM+c5ujQGMv0XXnh4genI=
this.Context.BeginExecute<User>(new Uri(string.Format("/Login?username='{0}'&password='{1}'", username, pwd), UriKind.Relative), (ar) => { .. }, null);

If I grab that with Fiddler, the Request-Header seems ok to me...

GET /Service.svc/Login?username='xyz'&password='CRQWKrKzCcQVnlhk2zl0j5QM+c5ujQGMv0XXnh4genI=' HTTP/1.1

But in the WebForms-Tab the Password-QueryString already has a whitespace instead of the '+'. Same result if I debug that on the Server...

Does anyone of you know why the '+' is replaced? Are there other invalid characters? How can I avoid that?

Update/EDIT :

Surprisingly the following query works as expected:

var query = (DataServiceQuery<User>) from c in this.Context.Users
                                             where
                                                 c.Username.Equals(username.ToLower()) &&
                                                 c.Password.Equals(Cryptography.ComputeSha256Hash(password + username.ToLower())) 
                                             select c;

Thanks in advance!

Was it helpful?

Solution 2

Thanks to Mark Stafford for the Hint. I've now a solution for this problem:

var pwd = Uri.EscapeDataString(Cryptography.ComputeSha256Hash(password + username.ToLower()));

The Query will now look like this:

/GET Service.svc/Login?username='xyz'&password='CRQWKrKzCcQVnlhk2zl0j5QM%252Bc5ujQGMv0XXnh4genI%253D'

And on the Server the equivalent unsecaping:

var pwd = Uri.UnescapeDataString(password);

See http://www.codebadger.com/blog/post/2010/08/10/Use-EscapeUriString-instead-of-UrlEncode-for-Silverlight.aspx

OTHER TIPS

The query string portion of the URL needs to be encoded properly. Calls to the WCF DS client LINQ provider (e.g., context.Users.Where(...)) are automatically encoded by the client-side stack. Calls to context.Execute do not modify the URL in this manner, so the values there will need to be encoded by other code.

Try this in Visual Studio to see the difference:

using System;
using System.Data.Services.Client;
using System.Linq;

namespace Scratch
{
    public class Program
    {
        public static void Main()
        {
            var context = new DataServiceContext(new Uri("http://services.odata.org/OData/OData.svc/"));
            var query1 = context.CreateQuery<Category>("Categories").Where(c => c.Name == "abcd+efgh=ijlk");
            var query2 = context.Execute<Category>(new Uri("http://services.odata.org/OData/OData.svc/Categories()?$filter=Name eq 'abcd+efgh=ijlk'"));
            Console.WriteLine("context.Categories.Where(...): {0}", query1.ToString());
            Console.WriteLine("context.Execute<Category>(...): {0}", ((QueryOperationResponse)query2).Query.ToString());
        }
    }

    public class Category
    {
        public int ID { get; set; }
        public string Name { get; set; }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top