#c# #asp.net #post #asp.net-web-api #get
Вопрос:
У меня довольно простая система: сервер ASP .NET Core, который размещен на domain.ru. В контроллере API у меня есть 2 метода:
[HttpGet("{id}")]
public string Get(int id)
{
try
{
using (FileStream fstream = new FileStream(string.Format(@"{0}data{1}.txt", _path, id.ToString()), FileMode.OpenOrCreate))
{
byte[] array = System.Text.Encoding.Default.GetBytes(id.ToString());
fstream.Write(array, 0, array.Length);
return "It's ok!";
}
}
catch
{
return "Something went wrong";
}
}
[HttpPost]
public string Post(string resolvedString)
{
try
{
using (FileStream fstream = new FileStream(string.Format(@"{0}dataPost.txt", _path), FileMode.OpenOrCreate))
{
byte[] array = System.Text.Encoding.Default.GetBytes(resolvedString);
fstream.Write(array, 0, array.Length);
return "It's ok!";
}
}
catch
{
return "Something went wrong";
}
}
Таким образом, в основном оба они просто создают текстовые файлы в каталоге _path. Часть, которую я не могу понять, — это когда я пытаюсь вызвать метод Get по url domain.ru/api/values/1 Я вижу файл, который был создан в каталоге _path, и у меня есть ответ «Все в порядке!». Вот как я называю Получить:
var client = new HttpClient();
client.BaseAddress = new Uri(uri);
HttpResponseMessage response = await client.GetAsync("api/values/1");
string result = await response.Content.ReadAsStringAsync();
textBox1.Text = result.ToString();
Но когда я пытаюсь сделать то же самое с Почтой, я получаю либо Плохой запрос, когда я делаю это с помощью C#, либо «Что-то пошло не так», когда я делаю это с Почтальоном.
Вот так я называю Пост
var client = new HttpClient();
client.BaseAddress = new Uri(uri);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
MultipartFormDataContent content = new MultipartFormDataContent();
StringContent str = new StringContent("1");
content.Add(str);
HttpResponseMessage response = await client.PostAsync("api/values/", content);
string returnString = await response.Content.ReadAsStringAsync();
MessageBox.Show(returnString);
Вот что показывает запрос, когда я пытаюсь вручную отладить это
And the most fun part. When I try to do all the same actions when my server is hosted on IIS (localserver) it works just fine! I’ really don’t know what I am doing wrong. Please, help.
UPD. Thanks to Jonathan, I asked my hoster to disable ModSecurity in Plesk and the above code started to work after replacing [HttpPost] by [HttpPost(«{resolvedString}»)]. So far so good!
Then I tried to send a zip archive to the server. Here is the server’s controller code:
[HttpPost]
public string ImportZip(IFormFile file)
{
DirectoryInfo dirInfo = new DirectoryInfo(_extractPath);
try
{
foreach (FileInfo myfile in dirInfo.GetFiles())
{
myfile.Delete();
}
string path = _path "tmp.zip";
if (Request.HasFormContentType)
{
var form = Request.Form;
foreach (var formFile in form.Files)
{
using (var fileStream = new FileStream(path, FileMode.Create))
{
formFile.CopyTo(fileStream);
}
ZipFile.ExtractToDirectory(_path "tmp.zip", _extractPath);
}
}
return "It's OK! At least we've entered the method.";
}
catch
{
return "Oh no no no...";
}
}
И именно так я называю это от клиента:
string filepath = _zipFile;
string filename = _fileName;
var client = new HttpClient();
client.BaseAddress = new Uri(uri);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
MultipartFormDataContent content = new MultipartFormDataContent();
ByteArrayContent fileContent = new ByteArrayContent(File.ReadAllBytes(filepath));
content.Add(fileContent, "file", filename);
HttpResponseMessage response = await client.PostAsync("File/ImportZip/", content);
string result = await response.Content.ReadAsStringAsync();
textBox1.Text = resu<
Еще раз, это работает так, как должно работать, когда я запускаю как сервер, так и клиент на своем компьютере. Я могу видеть загруженный архив и извлеченные файлы в каталогах назначения.
Но когда я загружаю свой сервер на хостинг и пытаюсь выполнить свой запрос еще раз, я получаю ту же ошибку:
пример ошибки
Комментарии:
1. Блокирует ли Plesk modsecurity сообщение? см.: plesk.com/blog/various/modsecurity-comprehensive-guide
2. Отключите отладку try/catch и try8, так как вы получите исключение в visual studio.
3. @AliK, я не могу отлаживать свой код, когда он размещен.
4. @Джонатан, спасибо, это сработало для одного случая. Но это либо вообще не работает, либо я совершаю какие-то глупые ошибки, которых не вижу.
5. Что ж, единственная ошибка, которую вы опубликовали, показывает, что ваш запрос столкнулся с проблемой безопасности Plesk. Какие еще ошибки вы получаете?
Ответ №1:
Что ж, похоже, я сам нашел ответ. Оставлю его здесь, чтобы он мог кому-то помочь (возможно, мне в будущем).
Код метода отправки клиента:
string uri = "https://example.com/controller/action/";
string zipFile = @"C:PathToYourFile.txt";
string response;
using (WebClient client = new WebClient())
{
response = Encoding.Default.GetString(client.UploadFile(uri, zipFile));
}
MessageBox.Show(response);
Здесь мы просто составляем запрос и отправляем файл. Путь и URL-адрес жестко заданы для ex.
Код метода сохранения сервера:
[HttpPost]
public string ImportZip(IFormFile file)
{
try
{
string path = _path "tmp.zip";
if (Request.HasFormContentType)
{
var form = Request.Form;
foreach (var formFile in form.Files)
{
using (var fileStream = new FileStream(path, FileMode.Create))
{
formFile.CopyTo(fileStream);
}
}
return "Done";
}
return "Empty request";
}
catch
{
return "No access";
}
}
Пока я отправляю только один файл, а также знаю его расширение и хочу, чтобы он назывался «tmp», я жестко кодирую его имя и расширение. Вы можете использовать имя/расширение файла по умолчанию, чтобы сохранить его как есть.
Затем я сохраняю все файлы в запросе в выбранном каталоге _path.
В принципе, вот и все.