2016-01-14 3 views
1

Можно ли отправить [FromBody] POST данные в контроллер с помощью client.GetAsync() (или PostAsync/SendAsync?C# POSTING [FromBody] данные от одного контроллера к другому

Я должен был создать базовый контроллер, который все API вызовы пройти через

Мой Аякса называет все идут к этому SecureApi контроллеру, и они посылают исходный путь в качестве параметра, что они могут быть перенаправлены на правильный контроллер что-то вроде:..

$.ajax({ 
    url: "./api/SecureApi/?path=/api/OtherApi/SomeRoute", 
    data: { 
     param1: 1, 
     param2: 2 
    } 
}); 

так мой базовый контроллер выглядит примерно так:

public class SecurityApiController : ApiController 
{ 
    [HttpPost] 
    public HttpResponseMessage SecureApi([FromBody]object data, string path) 
    { 
     // do some stuff 

     // get uri 
     var applicationPath = Request.RequestUri.Scheme + "://" + Request.GetRequestContext().VirtualPathRoot.Replace("/", String.Empty); 
     Uri routeUri = new Uri(applicationPath + path); 

     // then redirect to correct controller 
     var config = new HttpConfiguration(); 
     var server = new HttpServer(config); 
     var client = new HttpClient(server); 
     // how can I send [FromBody]object data here? 
     var response = client.GetAsync(routeUri).Result; // or PostAsync/SendAsync? 
     return response; 
    } 
} 

Контроллер other выглядит:

public class OtherApiController : ApiController 
{ 
    [HttpPost] 
    public HttpResponseMessage OtherApi([FromBody]OtherData data) 
    { 
     // do stuff 
    } 
} 

К сожалению, я не могу изменить OtherApi, так что я должен отправить POST данные о [FromBody] таким же образом (в POST).

Возможно ли это?

EDIT:

Per @ ответ Филиппа ниже, я использую PostAsJsonAsync и, кажется, хочет работать, но я получаю 401 Несанкционированное результат. Более подробная информация: (?)

Я пошел с правильным АСИНХРОННЫМ/ЖДЕТ маршрут ...

public async Task<HttpResponseMessage> SecureApi([FromBody]Dictionary<string, dynamic> data, string path) 
{ 
    ... 
    var client = new HttpClient(); 
    var response = await client.PostAsJsonAsync(routePath, data); 
    return response; 
} 

И контроллер Other имеет:

[Authorize(Roles = "Admin")] // I do have the "Admin" role 
[Route("Save")] 
[HttpPost] 
public SaveResultBase Save([FromBody]Dictionary<string, dynamic> data) 
{ 
    ... 
} 

Но этот контроллер никогда не попал (нет там попадают точки останова), и он возвращает 401 Несанкционированный ответ.

Я полагаю, что перед тем, как позвонить PostAsJsonAsync, я должен добавить учетные данные пользователя в заголовки клиентов. Невозможно найти способ сделать это.

ответ

2

Метод GetAsync из HttpClient отправит HTTP-запрос GET, поэтому возможно иметь только [FromUri] аргументов. Потому что аргумент [FromBody] по определению POST-данных, вы хотите использовать PostAsJsonAsync/PostAsXmlAsync/PostAsync. Разница между ними заключается в том, как данные сериализуются.

var response = client.PostAsJsonAsync(routeUri, data).Result; 

Это, как говорится, если у вас есть безопасность в виду, было бы довольно легко для тех, кто называют «правой апи» напрямую. Кроме того, вы увеличите задержку, создав два HTTP-запроса.

Вы должны взглянуть на this guide на MSDN. Я считаю, что authentication filter - это, вероятно, то, что вы ищете.

+0

Спасибо! Мы используем аутентификацию пользователя и авторизацию, но мы хотим иметь возможность использовать шифрование AES для наших стандартных вызовов API, так что это нелегко разоблачить пользователя. Не уверен, что это лучший способ, но это то, что мы придумали. Конечно, для других предложений. (Я собираюсь попробовать PostAsJsonAsync и отмечу это как «ответ», когда я получу его работу). – dmathisen

+0

Я добавил дополнительную информацию вверху под «EDIT» – dmathisen

+0

@dmathisen Основная проблема с этой реализацией заключается в том, что вы либо блокируете маршрутизацию для других API, чтобы вы были уверены, что их нельзя вызывать напрямую (но в этом случае вы также блокируете свои собственные соединения) или что вы разрешаете стандартную маршрутизацию (и безопасный API становится бесполезным, так как любой может получить прямой адрес, просматривая URL-адрес). Что касается ваших ошибок 401, я уверен, что у вас есть эта проблема, потому что сервер не считает SecureAPI тем же самым пользователем, что и «реальный» клиент ... Возможно, есть способ установить контейнер cookie HTTPClient из клиент... – Philippe