简体   繁体   中英

Get the name of view who called controller in ASP.NET MVC

Is there any way to get the name of View that called method in controller and save it for example in some custom variable inside that controller's method?

For example:

I have one View that uses Ajax to get to InfinateScroll method in controller:

<div class="container-post">
    <div id="postListDiv">
        @{Html.RenderAction("PostList", "Posts", new { Model = Model });}
    </div>
    <div id="loadingDiv" style="text-align: center; display: none; margin-bottom: 20px;">
        <img alt="Loading" src="@Url.Content("~/images/ajax-loader.gif")" />
    </div>
</div>

    <script src="@Url.Content("~/Scripts/jquery-1.10.2.min.js")"></script>
    <script type="text/javascript">
        var BlockNumber = 2;
        var NoMoreData = false;
        var inProgress = false;

        $(window).scroll(function () {
            if ($(window).scrollTop() == $(document).height() - $(window).height() && !NoMoreData && !inProgress) {
                inProgress = true;
                $("#loadingDiv").show();

                $.post("@Url.Action("InfinateScroll", "Posts")", { "BlockNumber": BlockNumber },
                    function (data) {
                        BlockNumber = BlockNumber + 1;
                        NoMoreData = data.NoMoreData;
                        $("#postListDiv").append(data.HTMLString);
                        $("#loadingDiv").hide();
                        inProgress = false;
                    });
            }
        });
    </script>

I use this View on two pages. In one case I'm using it to show only posts from specific user (user who is logged in), and on the other view I'm showing posts from all users in database(similar to Facebook wall where you can see only your post, and NewsFeed where you can not only your's but also posts from your frineds).

For some reason I would like to know which page was active when call for InfinateScroll method was made.

This is the method where I would like to make some differences between those two pages so I can do some check out's later.

[HttpPost]
public ActionResult InfinateScroll(int BlockNumber)
{
     int BlockSize = 5;
     var posts = PostManager.GetPosts(BlockNumber, BlockSize);
     JsonModel jsonModel = new JsonModel();
     jsonModel.NoMoreData = posts.Count < BlockSize;
     jsonModel.HTMLString = RenderPartialViewToString("PostList", posts);

     return Json(jsonModel);
}

This method gets posts using helper method GetPosts and it's used for showing more posts on scroll.

You can get the name of the current View from inside the view using the following:

@Path.GetFileNameWithoutExtension(Server.MapPath(VirtualPath))

Source: How to get the current view name in asp.net MVC 3?

so you could add this as a routevalue into your @Url.Action like so:

@Url.Action(
    "InfinateScroll",
    "Posts",
    new{callingView=Path.GetFileNameWithoutExtension(Server.MapPath(VirtualPath))})

Then you could add a parameter to your controller method

public ActionResult InfinateScroll(int BlockNumber, string callingView)

You can create a hidden variable in the html like this -

<input type="hidden" id="pageName" value="myPage1" />

Add an extra parameter to your Action -

public ActionResult InfiniteScroll(int BlockNumber, int pageName)

And then, in your jquery code, when you post, send in pageName as well.

$.post("@Url.Action("InfinateScroll", "Posts")", { "BlockNumber": BlockNumber, "pageName": $('#pageName').val() },

Hope this helps.

In one case I'm using it to show only posts from specific user... and on the other view I'm showing posts from all users in database...

Putting your desired logic on the view is unsafe, especially if showing data is user-based or user-specific. However, if you insists on having the logic on the view then you should pass along another variable to the controller like so:

$.post("@Url.Action("InfinateScroll", "Posts")", 
{ "BlockNumber": BlockNumber, "UserId": userId },
    // rest of your code goes here...
});

You then should have another parameter in your controller:

[HttpPost]
public ActionResult InfinateScroll(int BlockNumber, int userId)
{
    //filter your data based on the "userId" parameter
}

But like I mentioned this is unsafe because someone can easily pass in a valid "userId" and get to the data when you don't want them to. So the safest (or safer) way is to have the "filtering logic" in your controller like so:

[HttpPost]
public ActionResult InfinateScroll(int BlockNumber)
{
    // a context based logic
    var userId = GetLoggedInUserId();
    // that method could return null or zero 
    // and depending on how you approach it       
    //filter your data based on the "userId" 
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM