6

I am building an website in asp .net mvc 3.

I am trying to create a simple toggle button which can be used to "Add to favorite" and "Remove from favorite". However, I only want this functionality if the user is logged in otherwise I want to direct him to the "Login" page.

The toggle button works well but it does not check if the user is logged in or not. If a user is not logged in then on clicking the button it toggles but does not update the database. I want it to direct to the login page.

My code is below:

View:

<div class="save-unsave-link">
    @if(Model.IsPropertySaved) {
        @Html.ActionLink("Remove Property", "RemoveSavedProperty", "Property", new { id = Model.Property.PropertyId }, new { @class="unsave-property", onclick = "saveProperty();" })      
    } else {
        @Html.ActionLink("Save Property", "AddSavedProperty", "Property", new { id = Model.Property.PropertyId }, new { @class="save-property", onclick = "saveProperty();" })
    }
</div>

jQuery:

function saveProperty() {
    $('.save-unsave-link').delegate("a", "click", function (e) {
        var id = $(this).attr('href').match(/\d+/);
        if ($(this).hasClass('unsave-property')) {
            $.ajax({
                url: this.href,
                dataType: "text json",
                type: "POST",
                data: {},
                success: function (data, textStatus) { }
            });
            $(this).removeClass().addClass("save-property")
                .attr('href', '/Property/RemoveSavedProperty/' + id)
                .text('Remove Property');
            e.preventDefault();
        } else {
            var id = $(this).attr('href').match(/\d+/);
            $.ajax({
                url: this.href,
                dataType: "text json",
                type: "POST",
                data: {},
                success: function (data, textStatus) { }
            });
            $(this).removeClass().addClass("unsave-property")
                .attr('href', '/Property/AddSavedProperty/' + id)
                .text('Save Property');
            e.preventDefault();
        }
    });
}

Controller:

//
// POST: /Property/AddSavedProperty
[HttpPost]
[Authorize]
public void AddSavedProperty(int id)
{
    websiteRepository.AddSavedProperty(id);
}

//
// POST: /Property/RemoveSavedProperty
[HttpPost]
[Authorize]
public void RemoveSavedProperty(int id)
{
    websiteRepository.RemoveSavedProperty(id);
}

How do I check if the user is logged in before ajax post? and if he is not logged in then how do I direct him to the login page?

5
  • is your JQuery located in your view? If so you could check on User.Identity.IsAuthenticated Commented Nov 21, 2012 at 21:05
  • I have move the jQuery to a file and in the view I call the external js script. Will this work from the external js file? Commented Nov 21, 2012 at 21:10
  • It won't I'm afraid, as you'd need to use some Razor code, which you can't do inside a .js file Commented Nov 21, 2012 at 21:14
  • It gives me a warning saying conditional compilation is switched off Commented Nov 21, 2012 at 21:23
  • One thing to remember is that your users can actually timeout while viewing your page. So at render time they could be logged in but you may still get redirected to login page. Commented Nov 21, 2012 at 22:18

2 Answers 2

4

Why not just render out a link to your Login action if the user isn't logged in? You don't need jQuery for this at all - the Ajax call is completely superfluous when you can already determine whether the user is logged in when you first render the page.

@if (User.Identity.IsAuthenticated)
{
    @Html.ActionLink("Save Property", "AddSavedProperty", "Property", new { id = Model.Property.PropertyId },
        new { @class="save-property", onclick = "saveProperty();" })
}
else
{
    @Html.ActionLink("Save Property", "Login", "Login",
        new { returnUrl = ViewContext.HttpContext.Request.Url.PathAndQuery }, null)
}
Sign up to request clarification or add additional context in comments.

2 Comments

I have thought about it but how do I add a ReturnUrl to the login link?
I've updated my answer to reflect this question. This will add the return URL to your querystring, which you'll then have to pick up in your Login HttpPost action, redirecting if the login was successful.
1

You can run a function after all ajax calls and verify if the page was redirected, for instance, if your login page has a h2 title like this:

<h2>Log On</h2>

You could detect it and redirect yourself:

$(document).ajaxComplete(function (e, xhr) {
    if(xhr.responseText.indexOf("<h2>Log On</h2>") != -1) {
       // redirect code here
    }
});

3 Comments

What happens when you decide to change your <h2> text? Your functionality shouldn't be reliant on your content like this - it's a perfect way for things to get very messy very quickly.
This is just a simple and fast solution, a better way would be to implement a custom Authorize attribute so it will return something different then a code 200 when making an Ajax call.
I disagree - a better way would be not to make an Ajax call at all, since you can determine whether or not the user is authenticated in the previous request and simply render out a different link to the view. That gives you a simpler, faster, more robust solution, which doesn't rely upon jQuery or Ajax and won't stop working when you change your pages.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.