ASP.net mvc ActionResult parameter

2019-09-19 15:23发布

问题:

My controller looks like this:

public ActionResult Index(string username)
{
    if (string.IsNullOrEmpty(username))
    {
        _userId = User.Identity.GetUserId();
    }
    else
    {
        var user = UserService.GetUserByUserName(username);

        if (user != null)
        {
            _userId = user.Id;
        }
        else
        {
            return RedirectToAction("Index", "Routines");
        }
    }

    return View();
}

[HttpGet]
public JsonResult GetUserHomeData()
{
    return Json(CreateHomeViewModel(), JsonRequestBehavior.AllowGet);
}

[HttpGet]
public JsonResult GetUserStatisticsOverview()
{
    return Json(CreateUserStatisticsOverviewViewModel(), JsonRequestBehavior.AllowGet);
}

And I have problem with parameter username of ActionResult Index. I've monitored username variable and if I type url like this: www.test.com/profile/someUserName

Variable username is assigned these values:
1. someUserName
2. GetUserHomeData
3. GetUserStatisticsOverview

I call these Get methods from my javaScript file, why is this happening and how can I prevent this, i.e. catch only "someUsername"

Here is my route config:

routes.MapRoute("Profile", "profile/{userName}",
                    new { controller = "Profile", action = "Index", userName = UrlParameter.Optional }
                    );

routes.MapRoute("Default", "{controller}/{action}/{id}",
                    new {controller = "Home", action = "Index", id = UrlParameter.Optional }
                    );

Here is how I access Get methods (I'm using Angular's $http)

getResult: function() {

    var input = $http.get("/Profile/GetUserHomeData");

    var deferred = $q.defer();

    deferred.resolve(input);

    return deferred.promise;
}

回答1:

Problem is you are probably calling something like: @Url.Action("GetUserHomeData", "Profile") inside your JS, but this will be catched by the first route and the action there is Index and nothing else. You can eliminate the problem by just removing the route

routes.MapRoute("Profile", "profile/{userName}",
                new { controller = "Profile", action = "Index", userName = UrlParameter.Optional }
                );

alternatively you can rewrite the rule (that it does not match the controller-name):

routes.MapRoute("ProfileShortRoute", "p/{userName}",
                new { controller = "Profile", action = "Index", userName = UrlParameter.Optional }
                );

This will lead to Urls like this: http://domain/Profile/?userName=someUser or http://domain/p/someUser