来自桌面客户端的请求会触发错误的控制器操作

时间:2016-07-07 15:26:26

标签: asp.net .net asp.net-mvc asp.net-mvc-5

在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,因此,可能的原因也是不可能的。

1 个答案:

答案 0 :(得分:0)

堆栈中的某个位置(可能是IIS设置,web.config或应用全局过滤器)所有请求都需要进行身份验证,除非使用[AllowAnonymous]属性明确标记。解决方案很简单,添加该属性:

[HttpPost]
[AllowAnonymous]
public JsonResult APILogin(LoginRequest loginRequest)