问题描述
我有一个在内部IIS中托管的MVC应用程序,该应用程序具有表单身份验证。 <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>
因此,当用户未通过身份验证时,它将重定向到登录页面。我的登录控制器如下所示:
在此应用程序中工作正常。现在,我还有另一个MVC应用程序,它位于天蓝色的云中,它需要访问此API。 当我调用它(http://my-premise-application.com/api/customer/list)时,它正在返回登录页面的内容。 有什么方法可以从第二个应用程序调用第一个应用程序的api?任何建议或指导都会有所帮助。
解决方法
如注释中所述,您必须对另一个项目Web API进行C#HTTP调用。您可以通过在项目中的任何地方创建一个名为MakeRequestService
的类和一个名为static
的{{1}}方法来实现此目的,该方法将返回一个字符串,即您所需的JSON。
MakeWebRequest
然后可以通过以下方式使用此方法:
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 myResult;
}
}
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
块只是一个示例,在API调用失败的情况下,将返回包含JSON错误正文的纯字符串。您可以根据需要对其进行修改,例如重新扔MakeWebRequest
并按照您想要的方式处理它。
WebException
方法非常抽象,因此您也可以将其用于API调用。如果您使用JSON正文发出MakeWebRequest
请求-只需将正文传递给POST
参数即可。如果您使用查询参数发出json
请求,则只需构建包含查询参数的整个URL,然后调用该方法即可。
这是我用来登录C#应用程序的一些代码。您将需要进行修改以使用您的应用程序。由于其中包含您的会话Cookie,因此需要将SharedCookie添加到以后的每个请求中。
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=user&password=pass";
bytes = Encoding.UTF8.GetBytes(data);
request = CreateRequest(url,"POST");
request.CookieContainer = SharedCookie;
using (var stream = request.GetRequestStream())
{
stream.Write(bytes,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;
}