#asp.net-mvc #rest #asp.net-web-api #json.net #dotnet-httpclient
#asp.net-mvc #остальное #asp.net-web-api #json.net #dotnet-httpclient
Вопрос:
У меня есть ASP.NET Приложение MVC, из которого я хотел бы использовать ASP.NET Служба REST веб-API. Итак, я нашел здесь фрагмент кода.
В моем случае я хотел бы позвонить ASP.NET Метод веб-API (DumpIntoFile) из метода в классе в моем ASP.NET Приложение MVC (этот класс не является контроллером). Мне нужно, чтобы выполнение не продолжалось до тех пор, пока вызов DumpIntoFile не будет завершен и завершен. Как я могу это сделать? Я никогда не использовал async и await, поэтому я вообще не понимаю, как они работают.
public void GetData()
{
Warehouse myData = new Warehouse();
myData.id = 1111;
myData.name = blabla;
string path = "c:temp";
string filename = "myData.dat";
// Stuff here
this.DumpWarehouseDataIntoFile(myData, path, filename);
// Some other stuff here
}
public async void DumpWarehouseDataIntoFile(Warehouse myData, string path, string filename) // See Warehouse class later in this post
{
//Hosted web API REST Service base url
string Baseurl = "http://XXX.XXX.XX.X:YYYY/";
using (var client = new HttpClient())
{
//Passing service base url
client.BaseAddress = new Uri(Baseurl);
client.DefaultRequestHeaders.Clear();
//Define request data format
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// Serialize parameter to pass to the asp web api rest service
string jsonParam = Newtonsoft.JsonConvert.SerializeObject(myData);
//Sending request to find web api REST service resource using HttpClient
// How can I pass parameters jsonParam, path and filename to below call??????? Concatenating it?
HttpResponseMessage Res = await client.GetAsync("api/Warehouse/DumpIntoFile");
//Checking the response is successful or not which is sent using HttpClient
if (Res.IsSuccessStatusCode)
{
// Some other sftuff here
}
}
}
Объект хранилища выглядит следующим образом:
public class Warehouse {
public Warehouse();
public int id { get; set; }
public string name { get; set; }
// some other stuff here
}
И контроллер rest веб-api с методом:
public class MyWebApiController : ApiController
{
public bool DumpIntoFile(string data, string path, string filename)
{
bool resu<
Warehouse myData = JsonConvert.DeserializeObject<Warehouse>(data);
string myPath = path;
string myFilename = filename;
// Here rest of code
return resu<
}
}
Также я пытаюсь сделать следующее:
- Избегайте жесткого кодирования URL-адреса, потому что если ASP.NET Служба Web API REST будет опубликована на другом сервере в будущем, затем мне нужно коснуться кода, изменить его и снова опубликовать мой ASP.NET Приложение MVC. Может быть, поместить URL-адрес в файл web.config и прочитать оттуда?
- Как я могу передать параметры jsonParam, путь и имя файла в службу rest веб-api? объединение его?
ПРИМЕЧАНИЯ: я использую NET 4.5 и Visual Studio 2013.
Комментарии:
1. То есть вы имеете
await client.GetAsync("api/Warehouse/DumpIntoFile");
в виду, что не ждет завершения вызова метода? что вы имеете в виду под этим? что вDumpIntoFile
?2. @Dave я обновил свой пост. Что касается ожидания клиента. GetAsync Я внедряю его прямо сейчас, но я еще не смог его протестировать. Интересно, будет ли await ждать и не переходить к следующей строке кода до тех пор, пока вызов службы web api rest не завершится и не завершится. Я прав?
3. Ральф (извините, я не смог получить ваше имя в @ mentions) — хорошо, да, это должно подождать завершения запроса. Всякий раз, когда вы используете асинхронный метод, вам нужно ожидать их, иначе выполнение не будет ждать завершения асинхронных методов. Проверьте
await client.GetAsync("api/Warehouse/DumpIntoFile");
, ждет ли он или нет. Если вы видите неожиданный результат, возможно, есть что-то, чего не ждут вDumpIntoFile
Ответ №1:
Как я могу это сделать? Я никогда не использовал async и await, поэтому я вообще не понимаю, как они работают.
Я рекомендую вам прочитать мое вступление к async и ознакомиться с рекомендациями по async. Вы узнаете две ключевые вещи:
- Избегайте
async void
. - Это нормально для
async
/await
«расти» через вашу кодовую базу.
В вашем случае DumpWarehouseDataIntoFile
должно быть async Task
вместо async void
. А это значит GetData
, что необходимо , чтобы await
задача была возвращена из DumpWarehouseDataIntoFile
. Что означает GetData
, что тоже должно быть async Task
. Это означает, что вызывающие GetData
устройства должны использоваться await
и т. Д.
Примечание: По соглашению, асинхронные методы должны заканчиваться на Async
.
public async Task GetDataAsync()
{
Warehouse myData = new Warehouse();
myData.id = 1111;
myData.name = blabla;
string path = "c:temp";
string filename = "myData.dat";
// Stuff here
await this.DumpWarehouseDataIntoFileAsync(myData, path, filename);
// Some other stuff here
}
public async Task DumpWarehouseDataIntoFileAsync(Warehouse myData, string path, string filename)
Комментарии:
1. итак, как вы сказали, это означает, что вещи, вызывающие getData, должны использовать await и так далее. Проблема с этим заключается в том, что все методы, задействованные в цепочке, должны быть помечены как асинхронные и выполнять ожидание вызываемого метода. Но мой метод, который вызывает getData, не помечен как асинхронный, поэтому для меня это проблема, если я не помечу его как асинхронный, он не будет работать. На самом деле я хочу сделать синхронный вызов метода службы web api rest service DumpIntoFile, а не асинхронный вызов. Мне нужно дождаться завершения и завершения DumpIntoFile, чтобы выполнить следующие строки кода. Итак, как я могу этого добиться?
2. @Ralph: если сделать его синхронным, поток будет ждать. Если сделать его (правильно) асинхронным, код будет ждать (без блокировки потока). Вы можете думать об
await
этом как об «асинхронном ожидании». Итак, «мне нужно подождать, пока DumpIntoFile завершится и завершится, чтобы выполнить следующие строки кода» выполняется с помощьюawait
.