#c# #asp.net-mvc
#c# #asp.net-mvc
Вопрос:
У меня есть приложение MVC, размещенное в локальном IIS, которое имеет аутентификацию формы. <system.web>
настройка:
<system.web>
<compilation debug="true" targetFramework="4.8"/>
<httpRuntime targetFramework="4.8"/>
<authentication mode="Forms">
<forms loginUrl="~/Login" timeout="2880"/>
</authentication>
<authorization>
<allow users="?" verbs="OPTIONS"/>
<deny users="?"/>
</authorization>
</system.web>
Итак, когда пользователь не аутентифицирован, он перенаправляется на страницу входа. Мой контроллер входа в систему выглядит так:
У него есть API, который является методом POST и возвращает список.
Я получаю доступ к этому API с помощью ajax в пользовательском интерфейсе.
В этом приложении он работает нормально. Теперь у меня есть другое приложение MVC, которое находится в облаке Azure, и ему необходимо получить доступ к этому API. Когда я вызываю его (http://my-premise-application.com/api/customer/list ), он возвращает содержимое страницы входа в систему. Какой возможный способ вызвать api первого приложения из второго приложения? Любые предложения или рекомендации были бы полезны.
Комментарии:
1. Вы хотите получить доступ к своему API из другого проекта MVC с помощью javascript, которым вы поделились. Я правильно вас понял?
2. @G.Dimov, я хочу попасть через код C #
3. Можете ли вы изменить аутентификацию в системе on Prem? Если нет, вам нужно, чтобы приложение c # выполняло процесс входа в систему.
Ответ №1:
Как вы упомянули в комментариях, вам необходимо выполнить HTTP-вызов C # для другого веб-API проекта. Вы можете сделать это, создав в любом месте вашего проекта класс с именем MakeRequestService
и один static
метод с именем MakeWebRequest
, который вернет строку, являющуюся нужным вам JSON.
public class MakeRequestService
{
public static string MakeWebRequest(string url, string verb, int timeout, Dictionary<string, string> headers = null, string contentType = "", string json = "")
{
string myResult = string.Empty;
try
{
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(url);
myRequest.Method = verb;
myRequest.Timeout = timeout;
if (!string.IsNullOrEmpty(contentType))
myRequest.ContentType = contentType;
if (headers != null)
{
foreach (var header in headers)
{
if (header.Key == HttpRequestHeader.Accept.ToString())
myRequest.Accept = header.Value;
else
myRequest.Headers.Add(header.Key, header.Value);
}
}
if (!string.IsNullOrEmpty(json))
{
byte[] bytes = Encoding.UTF8.GetBytes(json);
myRequest.ContentLength = bytes.Length;
using (var streamWriter = new StreamWriter(myRequest.GetRequestStream()))
{
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
}
using (HttpWebResponse response = myRequest.GetResponse() as HttpWebResponse)
{
StreamReader reader = new StreamReader(response.GetResponseStream());
myResult = reader.ReadToEnd();
}
}
catch (WebException ex)
{
if (ex.Status == WebExceptionStatus.ProtocolError)
{
if (ex.Response is HttpWebResponse response)
{
Stream stream = response.GetResponseStream();
StreamReader sr = new StreamReader(stream: stream);
myResult = sr.ReadToEnd();
stream.Position = 0;
}
}
else
{
myResult = ex.Message;
}
}
return myResu<
}
}
Затем вы можете использовать этот метод следующим образом:
string res = MakeRequestService.MakeWebRequest(
url: "The FULL URL of the first project, based on your example, e.g. http://localhost:69963/api/customer",
verb: "POST",
contentType: "application/json"
);
var outcome = JsonConvert.DeserializeObject<IEnumerable<Customer>>(res);
catch
Блок в MakeWebRequest
методе является просто примером и вернет простую строку, содержащую тело ошибки JSON, в случае неудачного вызова API. Вы можете изменить его для своих нужд, например, перестроить WebException
и обработать его так, как вы хотите.
MakeWebRequest
Метод очень абстрактный, поэтому вы можете использовать его и для вызовов API. Если вы делаете POST
запрос с телом JSON — просто передайте тело json
параметру. Если вы делаете GET
запрос с параметрами запроса, просто создайте весь URL-адрес, содержащий параметры запроса, а затем вызовите метод.
Комментарии:
1. Где находится часть входа в систему?
2. как видно из вопроса, метод не требует авторизации
3. «Итак, когда пользователь не аутентифицирован, он перенаправляется на страницу входа» web.config требует аутентифицированных пользователей.
4. «Теперь у меня есть другое приложение MVC, которое находится в облаке Azure, и ему необходимо получить доступ к этому API».
5. Я полагаю, что API является частью приложения Forms auth MVC.
Ответ №2:
Вот некоторый код, который я использую для входа в систему с помощью приложения на C #. Вам нужно будет внести изменения для работы с вашим приложением. SharedCookie необходимо будет добавлять к каждому будущему запросу, поскольку в него включен файл cookie вашего сеанса.
public void Login()
{
byte[] bytes;
string data;
SharedCookie = new CookieContainer();
var url = Host "/login";
try
{
//Start Session
var request = CreateRequest(url, "GET");
request.CookieContainer = SharedCookie;
using (var tmpResponse = request.GetResponse())
{
DoWriteResponse(tmpResponse);
tmpResponse.Close();
}
//Login
data = "username=useramp;password=pass";
bytes = Encoding.UTF8.GetBytes(data);
request = CreateRequest(url, "POST");
request.CookieContainer = SharedCookie;
using (var stream = request.GetRequestStream())
{
stream.Write(bytes, 0, bytes.Length);
}
using (var tmpResponse = request.GetResponse())
{
DoWriteResponse(tmpResponse);
tmpResponse.Close();
}
IsLoggedIn = true;
}
catch (System.Net.WebException ex)
{
Console.WriteLine("Web Error:" ex.Status);
Console.WriteLine("Url:" url);
Console.WriteLine(ex.Message);
}
catch (Exception ex)
{
Console.WriteLine("Url:" url);
Console.WriteLine(ex.Message);
}
}
private void DoWriteResponse(WebResponse tmpResponse)
{
if (debug)
{
Console.WriteLine("************BEGIN**************");
Console.WriteLine("************" tmpResponse.ResponseUri "**************");
Console.WriteLine("*******************************");
using (var reader = new StreamReader(tmpResponse.GetResponseStream()))
{
var pageText = reader.ReadToEnd();
Console.WriteLine(pageText);
}
Console.WriteLine("*************END***************");
}
}
private HttpWebRequest CreateRequest(string url, string method)
{
var request = (HttpWebRequest)WebRequest.Create(url);
request.Referer = Host;
request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36";
request.Method = method;
request.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
return request;
}