C# MVC登录表单-未找到资源

C# MVC登录表单-未找到资源,c#,asp.net-mvc-5,asp.net-mvc-routing,C#,Asp.net Mvc 5,Asp.net Mvc Routing,我正在尝试实现我自己的登录框架,它起源于我的ASP.NET项目,现在即将迁移到ASP.NET MVC 问题 每当我在CommunityBar.cshtml中单击submit按钮时,我就会被重定向到:localhost/Home/Login?Length=4并收到资源未找到错误,但在过去的几个小时里,我和我们的得力朋友谷歌一起一直没有找到解决方案。所以我希望这里有人能帮忙 接下来是一组代码: RouteConfig.cs // POST home/login routes.MapRoute(

我正在尝试实现我自己的登录框架,它起源于我的ASP.NET项目,现在即将迁移到ASP.NET MVC

问题

每当我在
CommunityBar.cshtml
中单击submit按钮时,我就会被重定向到:
localhost/Home/Login?Length=4
并收到
资源未找到错误
,但在过去的几个小时里,我和我们的得力朋友谷歌一起一直没有找到解决方案。所以我希望这里有人能帮忙

接下来是一组代码:

RouteConfig.cs

// POST home/login
routes.MapRoute(
    name: "Login",
    url: "Home/Login/{model}/{returnUrl}",
    defaults: new { controller = "Home", action = "Login" }
    );
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login(UserViewData model, string returnUrl)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }

    return Content("test");
    //return RedirectToLocal(returnUrl);
}
CommunityBar.cshtml

@using (Html.BeginForm("Login", "Home", new {ReturnUrl = ViewBag.ReturnUrl}, FormMethod.Post, new {role = "form"}))
{
     @Html.AntiForgeryToken()
     @Html.ValidationSummary(true, "", new {@class = "danger"})
     @Html.TextBoxFor(m => m.LoginUsername, new {@class = "form-input", @placeholder = "Username"})
     @Html.ValidationMessageFor(m => m.LoginUsername, "", new {@class = "danger"})
     @Html.TextBoxFor(m => m.LoginPassword, new {@class = "form-input", @placeholder = "Password"})
     @Html.ValidationMessageFor(m => m.LoginPassword, "", new {@class = "danger"})
     @Html.ActionLink("Sign In", "Login", "Home", new {@class = "form-btn"})
}
public class UserViewData
{

    [Required]
    [DataType(DataType.Text)]
    public string LoginUsername { get; set; }

    [Required]
    [DataType(DataType.Password)]
    public string LoginPassword { get; set; }

    public MembershipUser User { get; private set; }
    public bool HasMessages { get; private set; }
    public List<MembershipUserPrivateMessage> Messages { get; private set; }
    public bool HasNotifications { get; private set; }
    public List<Subscription> Subscriptions { get; private set; }

    public UserViewData(MembershipUser user)
    {
        UserService userService = new UserService();

        this.User = user;
        this.HasMessages = userService.CountUnreadPrivateMessages() > 0;
        this.Messages = userService.GetPrivateMessages(false).Where(p => !p.IsRead).Take(5).ToList();
        this.HasNotifications = false;
        this.Subscriptions = null;
    }
}
HomeController.cs

// POST home/login
routes.MapRoute(
    name: "Login",
    url: "Home/Login/{model}/{returnUrl}",
    defaults: new { controller = "Home", action = "Login" }
    );
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login(UserViewData model, string returnUrl)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }

    return Content("test");
    //return RedirectToLocal(returnUrl);
}
用户视图数据模型

@using (Html.BeginForm("Login", "Home", new {ReturnUrl = ViewBag.ReturnUrl}, FormMethod.Post, new {role = "form"}))
{
     @Html.AntiForgeryToken()
     @Html.ValidationSummary(true, "", new {@class = "danger"})
     @Html.TextBoxFor(m => m.LoginUsername, new {@class = "form-input", @placeholder = "Username"})
     @Html.ValidationMessageFor(m => m.LoginUsername, "", new {@class = "danger"})
     @Html.TextBoxFor(m => m.LoginPassword, new {@class = "form-input", @placeholder = "Password"})
     @Html.ValidationMessageFor(m => m.LoginPassword, "", new {@class = "danger"})
     @Html.ActionLink("Sign In", "Login", "Home", new {@class = "form-btn"})
}
public class UserViewData
{

    [Required]
    [DataType(DataType.Text)]
    public string LoginUsername { get; set; }

    [Required]
    [DataType(DataType.Password)]
    public string LoginPassword { get; set; }

    public MembershipUser User { get; private set; }
    public bool HasMessages { get; private set; }
    public List<MembershipUserPrivateMessage> Messages { get; private set; }
    public bool HasNotifications { get; private set; }
    public List<Subscription> Subscriptions { get; private set; }

    public UserViewData(MembershipUser user)
    {
        UserService userService = new UserService();

        this.User = user;
        this.HasMessages = userService.CountUnreadPrivateMessages() > 0;
        this.Messages = userService.GetPrivateMessages(false).Where(p => !p.IsRead).Take(5).ToList();
        this.HasNotifications = false;
        this.Subscriptions = null;
    }
}
CommunityBar.cshtml

@using (Html.BeginForm("Login", "Home", FormMethod.Post))
{
    @Html.AntiForgeryToken()
    <input type="text" name="username" class="form-input" placeholder="Username"/>
    <input type="text" name="password" class="form-input" placeholder="Username"/>
    <input type="submit" value="Sign In"/>
}
@使用(Html.BeginForm(“Login”,“Home”,FormMethod.Post))
{
@Html.AntiForgeryToken()
}
HomeController.cs

// POST: /Home/Login
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(string username, string password)
{
    if (!ModelState.IsValid)
    {
        return Content("fail");
    }

    return Content("success" + username + password);
}
//POST:/Home/Login
[HttpPost]
[ValidateAntiForgeryToken]
公共异步任务登录(字符串用户名、字符串密码)
{
如果(!ModelState.IsValid)
{
返回内容(“失败”);
}
返回内容(“成功”+用户名+密码);
}

我个人不喜欢这样,因为这实际上只是一种隐藏问题的方式,而不是实际的解决方案。所以我要继续问这个问题,如果有人知道我们的原始代码有什么问题。或者我会…

RouteConfig.cs在这种格式下很好

// POST home/login
routes.MapRoute(
    name: "Login",
    url: "Home/Login/",
    defaults: new { controller = "Home", action = "Login" }
);
CommunityBar.cshtml无法提交表单,因为OP中的操作链接会呈现一个只链接回页面的操作标记

@using (Html.BeginForm("Login", "Home", new {ReturnUrl = ViewBag.ReturnUrl}, FormMethod.Post, new {role = "form"}))
{
     @Html.AntiForgeryToken()
     @Html.ValidationSummary(true, "", new {@class = "danger"})
     @Html.TextBoxFor(m => m.LoginUsername, new {@class = "form-input", @placeholder = "Username"})
     @Html.ValidationMessageFor(m => m.LoginUsername, "", new {@class = "danger"})
     @Html.TextBoxFor(m => m.LoginPassword, new {@class = "form-input", @placeholder = "Password"})
     @Html.ValidationMessageFor(m => m.LoginPassword, "", new {@class = "danger"})
     <!-- Remove action link and add Submit button here -->
     <button class="form-btn" type="submit">Sign In</button> 
}
HomeController.cs需要确保它在原始get上传递模型

[HttpGet]
[AllowAnonymous]
public ActionResult Login() {
    var model = new LoginModel();//also why default constructor needed
    return View(model);
}

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }

    //...login logic here

    //if reach this far then redirect
    if (!string.IsNullOrWhiteSpace(returnUrl)) {
        return RedirectToLocal(returnUrl);
    } else {
        return this.RedirectToAction("MyActionNameHere");
    }
}

RouteConfig.cs在这种格式中很好

// POST home/login
routes.MapRoute(
    name: "Login",
    url: "Home/Login/",
    defaults: new { controller = "Home", action = "Login" }
);
CommunityBar.cshtml无法提交表单,因为OP中的操作链接会呈现一个只链接回页面的操作标记

@using (Html.BeginForm("Login", "Home", new {ReturnUrl = ViewBag.ReturnUrl}, FormMethod.Post, new {role = "form"}))
{
     @Html.AntiForgeryToken()
     @Html.ValidationSummary(true, "", new {@class = "danger"})
     @Html.TextBoxFor(m => m.LoginUsername, new {@class = "form-input", @placeholder = "Username"})
     @Html.ValidationMessageFor(m => m.LoginUsername, "", new {@class = "danger"})
     @Html.TextBoxFor(m => m.LoginPassword, new {@class = "form-input", @placeholder = "Password"})
     @Html.ValidationMessageFor(m => m.LoginPassword, "", new {@class = "danger"})
     <!-- Remove action link and add Submit button here -->
     <button class="form-btn" type="submit">Sign In</button> 
}
HomeController.cs需要确保它在原始get上传递模型

[HttpGet]
[AllowAnonymous]
public ActionResult Login() {
    var model = new LoginModel();//also why default constructor needed
    return View(model);
}

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }

    //...login logic here

    //if reach this far then redirect
    if (!string.IsNullOrWhiteSpace(returnUrl)) {
        return RedirectToLocal(returnUrl);
    } else {
        return this.RedirectToAction("MyActionNameHere");
    }
}

@Div,也许应该提到,我试过不走路线。没有成功…在您的路径中,我可以看到一个{model}参数,它似乎没有在您的URL中提供。尝试从路由中删除{model},看看这是否有帮助。@Vahid,不幸的是,同样的结果。这可能不仅仅是因为没有提交按钮,而是一个锚定链接吗?@Div,也许应该提到,我在没有路由的情况下尝试过。没有成功…在您的路径中,我可以看到一个{model}参数,它似乎没有在您的URL中提供。尝试从路由中删除{model},看看是否有帮助。@Vahid,不幸的是,同样的结果。这可能不仅仅是因为没有提交按钮,而是锚链接?Reg。对于UserViewData,我需要向同一个视图传递相当多的信息。因此,我将“LoginModel”合并到UserViewData中。我还需要用你的LoginModel这样做吗?(我不知道我在这篇评论中是否说得够清楚)还不清楚。示例显示了一个非常简化的视图。答案是基于这一点,将对基本上两个模型的需求结合起来,即您的“LoginViewModel”和我的UserViewData。我是否可以将其转换为自己的“组合”视图模型,这样我就拥有了所需的数据和表单所需的LoginView模型?在那之后,表格还能用吗。对于UserViewData,我需要向同一个视图传递相当多的信息。因此,我将“LoginModel”合并到UserViewData中。我还需要用你的LoginModel这样做吗?(我不知道我在这篇评论中是否说得够清楚)还不清楚。示例显示了一个非常简化的视图。答案是基于这一点,将对基本上两个模型的需求结合起来,即您的“LoginViewModel”和我的UserViewData。我是否可以将其转换为自己的“组合”视图模型,这样我就拥有了所需的数据和表单所需的LoginView模型?之后,表单还会工作吗?