C# 如何包装POST请求的正文以便能够发送受限字符

C# 如何包装POST请求的正文以便能够发送受限字符,c#,webrequest,httpwebresponse,C#,Webrequest,Httpwebresponse,使用powershell从外部服务获取用户的当前令牌我没有问题: $uri = "http://myserver/fmetoken/view" $postParams = @{user='Myuser';password='PS78U-w&';} $foo = Invoke-WebRequest -Uri $uri -Method Post -Body $postParams $foo.Content 我收到代币 如果我用邮递员来验证,就没有问题了

使用powershell从外部服务获取用户的当前令牌我没有问题:

$uri = "http://myserver/fmetoken/view"
$postParams = @{user='Myuser';password='PS78U-w&';}
$foo = Invoke-WebRequest -Uri $uri -Method Post -Body $postParams

$foo.Content
我收到代币

如果我用邮递员来验证,就没有问题了

但如果我想在c#中执行相同的操作,答案是: '远程服务器返回错误:(401)未经授权。'当密码包含诸如'&'和'='之类的字符时

var url = $"{fmeServerUrl}/fmetoken/view";
var body = $"user={settingsUserFme}&password={settingsPasswordFme}";

var byteArray = Encoding.UTF8.GetBytes(body);
var responseCode = 0;
var request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.Credentials = CredentialCache.DefaultCredentials;
request.ContentType = "application/x-www-form-urlencoded";

request.ContentLength = byteArray.Length;
var dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();

WebResponse response = request.GetResponse();
using (var reader = new StreamReader(response.GetResponseStream()))
{
    responseresult = reader.ReadToEnd();
    reader.Close();
}
我已经尝试使用:

var bodyencoded = System.Net.WebUtility.UrlEncode(body);
var byteArray = Encoding.UTF8.GetBytes(bodyencoded);

但在本例中,我收到了一个错误的请求

如果您对整个
正文
进行URL编码,正文中用于帮助解析的&和=字符将被丢弃,因此您的请求将转换为如下内容:

user=Myuser&password=PS78U-w&
user=Myuser%26password=PS78U-w%26 // post UrlEncode
因此,服务器只是假设您发送的是一个很长的用户名,而不是两个不同的参数

为了避免这种情况,您可以单独对password参数进行URL编码,然后将其放入
主体
变量中

var passencoded = System.Net.WebUtility.UrlEncode(pass)
var body = $"user={settingsUserFme}&password={passencoded}";
其结果应该是:
user=Myuser&password=PS78U-w%26
,注意密码前面的符号是有效的,并保留下来。

可能的