在Windows窗体桌面应用程序中,我向ASP.NET MVC Web应用程序(而非Web API)中的端点发出请求。
请求是针对端点"〜/ Account / APILogin"但是它击中了"〜/ Account / Login" (GET)行动,即使我向前者提出要求。为什么会这样?
以下是相关的代码:
在ASP.NET MVC应用程序中
class AccountController : Controller
{
// The request comes to this guy
[AllowAnonymous]
public ActionResult Login(string returnUrl)
{
// get request for Web browser clients
ViewBag.ReturnUrl = returnUrl;
return View();
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
// post request for Web browser clients
}
// It should really have hit this
[HttpPost]
public JsonResult APILogin(LoginRequest loginRequest)
{
if (loginRequest == null || string.IsNullOrEmpty(loginRequest.UserName) || string.IsNullOrEmpty(loginRequest.Password))
{
return Json(LoginResult.CreateFailure("Invalid login. Please try again."));
}
var hashedPassword = UserManager.PasswordHasher.HashPassword(loginRequest.Password);
var user = BusinessManager.GetUser(loginRequest.UserName, hashedPassword);
if (user == null)
{
return Json(LoginResult.CreateFailure("Invalid login. Please try again."));
}
return Json(LoginResult.CreateSuccess());
}
}
在ASP.NET MVC Web应用程序的Global.asax中
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());
}
}
在Windows窗体桌面客户端应用程序中
private async void btnOk_Click(object sender, EventArgs e)
{
var client = new Client();
var loginRequest = new LoginRequest { UserName = txtUserName.Text.Trim(), Password = txtPassword.Text.Trim() };
var loginResult = await client.LoginAsync(loginRequest);
if (loginResult.Succeeded)
{
Close();
}
else
{
ReportInvalidLogin(loginResult.FailureMessage);
}
}
在代表客户端向ASP.NET Web应用程序发出HTTP请求的类库中
class Client : IDisposable
{
private WebClient _webClient = null;
private string _baseUrl = null;
public Client()
{
_webClient = new WebClient();
_baseUrl = ConfigurationManager.AppSettings["WebApplicationBasePath"];
if (string.IsNullOrEmpty(_baseUrl))
{
throw new ArgumentNullException("Please add a key named WebApplicationBasePath to the configuration file with the base Url of the server web application.");
}
}
public async Task<LoginResult> LoginAsync(LoginRequest loginRequest)
{
var loginUrl = string.Format($"{_baseUrl}Account/APILogin");
var data = await Task.Factory.StartNew<string>(() => JsonConvert.SerializeObject(loginRequest));
_webClient.Headers.Add(HttpRequestHeader.ContentType, "application/json");
var responseString = await _webClient.UploadStringTaskAsync(loginUrl, "POST", data);
var loginResult = await Task.Factory.StartNew<LoginResult>(() =>
JsonConvert.DeserializeObject<LoginResult>(responseString));
return loginResult;
}
}
我 尚未应用AuthorizeAttribute
,因此,可能的原因也是不可能的。
答案 0 :(得分:0)
堆栈中的某个位置(可能是IIS设置,web.config或应用全局过滤器)所有请求都需要进行身份验证,除非使用[AllowAnonymous]
属性明确标记。解决方案很简单,添加该属性:
[HttpPost]
[AllowAnonymous]
public JsonResult APILogin(LoginRequest loginRequest)