Я пытаюсь получить доступ к WebAPI, который использует ValidateAntiForgeryToken. Мой WebAPI Метод заключается в следующем (простой один), который находится внутри контроллера пользователя (только для тестирования):Доступ к WebAPI с AntiForgeryToken в Aspnet 5.0 на Xamarin
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Test(String field)
{
String result = String.Empty;
if (ModelState.IsValid)
{
HtmlSanitizer sanitizer = new HtmlSanitizer();
try
{
result = sanitizer.Sanitize(field);
}
catch (Exception ex)
{
result = ex.Message;
throw;
}
}
return Json(result);
}
С Ajax, я могу получить доступ к нему с легкостью:
$.ajax({
url: '/User/Test',
type: "POST",
contentType: "application/x-www-form-urlencoded",
data: {
field: self.textField(),
__RequestVerificationToken: $("input[name='__RequestVerificationToken']").val(),
},
success: function(e) {
self.textField(e)
self.divField(e);
},
error: function(e) {
console.log(e.error());
},
});
Но, до сих пор я не могу получить доступ к этому webapi с помощью httpclient на xamarin. Это мой код:
private async void DoTestWebApi()
{
try
{
HttpClient clientPage = new HttpClient()
{
BaseAddress = new Uri("https://localhost:44356/user")
};
var pageWithToken = await clientPage.GetAsync(clientPage.BaseAddress);
String verificationToken = GetVerificationToken(await pageWithToken.Content.ReadAsStringAsync());
HttpClient client = new HttpClient()
{
BaseAddress = new Uri("https://localhost:44356/user/test/")
};
HttpRequestMessage message = new HttpRequestMessage()
{
RequestUri = new Uri("https://localhost:44356/user/test/"),
Method = HttpMethod.Post
};
message.Headers.Add("__RequestVerificationToken", verificationToken);
String field = "teste";
//StringContent content = new StringContent("field=test", Encoding.UTF8, "application/x-www-form-urlencoded");
StringContent content = new StringContent("__RequestVerificationToken=" + verificationToken + ",field=test", Encoding.UTF8, "application/x-www-form-urlencoded");
// this doesn't work
//client.DefaultRequestHeaders.Add("__RequestVerificationToken", verificationToken);
var response2 = await client.SendAsync(message);
if (response2.IsSuccessStatusCode)
{
var t = response2.Content.ReadAsStringAsync();
if (true)
{
// just to check if t has value
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw;
}
}
Честно говоря, я не знаю, что еще я мог сделать, чтобы передать свой анти маркера подделки в сообщении. Он отлично работает в ajax, я передаю его внутри содержимого данных, но в xamarin он не работает. Весь код выполняется внутри одного и того же локального хоста. Если я удалю [ValidateAntiForgeryToken], он будет работать.
Что мне не хватает?
Edit:
Итак, теперь я шлю с печеньем, но опять-таки не ударять метод. Это мое обновление:
HttpClient clientPage = new HttpClient()
{
BaseAddress = new Uri("https://localhost:44356/user")
};
var pageWithToken = await clientPage.GetAsync(clientPage.BaseAddress);
String verificationToken = GetVerificationToken(await pageWithToken.Content.ReadAsStringAsync());
List<KeyValuePair<String, String>> cookiesInfo = new List<KeyValuePair<String, String>>();
foreach (var item in pageWithToken.Headers)
{
cookiesInfo.Add(new KeyValuePair<String, String>(item.Key, item.Value.ToString()));
}
cookiesInfo.Add(new KeyValuePair<string, string>("field", "value"));
cookiesInfo.Add(new KeyValuePair<string, string>("__RequestVerificationToken", verificationToken));
CookieContainer cookieContainer = new CookieContainer();
using (var handler = new HttpClientHandler() { CookieContainer = cookieContainer })
{
using (var client = new HttpClient(handler) { BaseAddress = new Uri("https://localhost:44356/user") })
{
var content = new FormUrlEncodedContent(cookiesInfo);
cookieContainer.Add(client.BaseAddress, new Cookie("__RequestVerificationToken", verificationToken));
foreach (var item in cookiesInfo)
{
cookieContainer.Add(client.BaseAddress, new Cookie(item.Key, item.Value));
}
var result = client.PostAsync(new Uri("https://localhost:44356/user/test"), content).Result;
result.EnsureSuccessStatusCode();
}
};
Это сводит меня с ума ... Хорошо тест в локальный, но вскоре это приложение будет в лазури, и это является предварительным условием ...
Edit: GetVerificationToken Метод:
private string GetVerificationToken(String verificationToken)
{
if (verificationToken != null && verificationToken.Length > 0)
{
verificationToken = verificationToken.Substring(verificationToken.IndexOf("__RequestVerificationToken"));
verificationToken = verificationToken.Substring(verificationToken.IndexOf("value=\"") + 7);
verificationToken = verificationToken.Substring(0, verificationToken.IndexOf("\""));
}
return verificationToken;
}
Вы можете захватить запросы, отправленные на ваш API с помощью такого инструмента, как [Скрипач] (http://www.telerik.com/fiddler) и сравните ajax с HttpClient. Это может дать вам некоторые подсказки относительно того, каковы различия. –
'localhost'? localhost, используемый в вашем телефоне/эмуляторе, будет телефоном/эмулятором, а не вашим компьютером. Используйте имя хоста/IP-адрес хоста, на котором запущено приложение aspnet/iis, которое разрешимо с телефона/эмулятора, попробуйте использовать браузер устройства, чтобы открыть этот URL-адрес в качестве теста ... – SushiHangover
да, localhost. потому что все приложения выполняются на одном компьютере. И это работает, это не проблема (если я удалю ValidateAntiForgeryToken, нормально работает) –