我有一个非常奇怪的问题(使用 SL5、WCF DataServices 5.0.1): 我有一个带有 2 个字符串参数(用户名、密码)的 ServiceOperation,用于检查用户是否存在
public IQueryable<User> Login(string username, string password)
{...}
当我尝试调用它时,一切正常,除了密码哈希中包含“+”字符的情况。在这种情况下,似乎它被替换为空白字符:
var pwd = CRQWKrKzCcQVnlhk2zl0j5QM+c5ujQGMv0XXnh4genI=
this.Context.BeginExecute<User>(new Uri(string.Format("/Login?username='{0}'&password='{1}'", username, pwd), UriKind.Relative), (ar) => { .. }, null);
如果我用 Fiddler 抓取它,请求 header 对我来说似乎没问题......
GET /Service.svc/Login?username='xyz'&password='CRQWKrKzCcQVnlhk2zl0j5QM+c5ujQGMv0XXnh4genI=' HTTP/1.1
但是在 WebForms-Tab 中,Password-QueryString 已经有一个空格而不是“+”。如果我在服务器上调试它,结果相同...
你们有人知道为什么要替换“+”吗? 还有其他无效字符吗? 我怎样才能避免这种情况?
更新/编辑:
令人惊讶的是,以下查询按预期工作:
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;
提前致谢!
最佳答案
URL 的查询字符串部分需要正确编码。对 WCF DS 客户端 LINQ 提供程序(例如 context.Users.Where(...)
)的调用由客户端堆栈自动编码。对 context.Execute
的调用不会以这种方式修改 URL,因此那里的值需要由其他代码进行编码。
在 Visual Studio 中尝试此操作以查看差异:
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; }
}
}
关于wcf-data-services - WCF DataServices 服务操作参数-字符替换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11391860/