Maddhacker24
Maddhacker24

Reputation: 1875

What's the best way to share a variable between views in ASP.net MVC 4. Trying to eliminate duplicate code

What's the best way to handle the following scenario? I have some code in my _Layout view that checks for a cookie and attempts to set a true/false variable in ViewBag. Then in another view I want to check that ViewBag value and act on it.

I want to determine whether the user has a cookie or not and show an AD based off that.

I can get it to work if I stick all of the code in the _Pictures.cshtml view but I dont want to copy the same code to every view. I'd like to check for the cookie in one spot only.

Should I be using TempData or ViewData instead? It seems like there should be a simple solution but i'm having a brain fart.

The error i'm getting is:

Operator '!' cannot be applied to operand of type 'null'

Thanks for your help.

This is what I have in my _Layout.cshtml view.

@{
    //Interstitial AD Cookie.
    //Used to determine if user has been shown an interstitial within the last hour.
    ViewBag.shownInterstitial = false;
    if (Request.Cookies["Interstitial"] != null)
    {
        ViewBag.shownInterstitial = true;
    }
    //Interstitial cookie does NOT exist.
    else
    {
       ViewBag.shownInterstitial = false;
    }    
}

This is what I have in another view - Pictures.cshtml

@{
    //Check to see if user has the Interstitial ad cookie.
    //If NOT, then show interstitial ad and set a cookie for 1hr.
    if (!ViewBag.shownInterstitial)
    {
        <div class="hidden-md hidden-lg">
            <div class="adnl_zone id_4034"></div>
        </div>

        //Create a cookie to prevent interstitial spam.
        HttpCookie Cookie = new HttpCookie("Interstitial");
        Cookie.Value = "true";
        Cookie.Expires = DateTime.Now.AddHours(1);
        Response.Cookies.Add(Cookie);
    }
}

Upvotes: 0

Views: 997

Answers (2)

JamieD77
JamieD77

Reputation: 13949

One way would be to just create a @Html extension to render the div if Request.Cookies["Interstitial"] != null

public static class DivExtensions
{
    public static string InterstitialAd(this HtmlHelper helper)
    {
        var html = string.Empty;
        if (HttpContext.Current.Request.Cookies["Interstitial"] == null)
        {
            html = "<div class='hidden-md hidden-lg'><div class='adnl_zone id_4034'></div></div>'";
            //Create a cookie to prevent interstitial spam.
            HttpCookie Cookie = new HttpCookie("Interstitial");
            Cookie.Value = "true";
            Cookie.Expires = DateTime.Now.AddHours(1);
            HttpContext.Current.Response.Cookies.Add(Cookie);
        }
        return html;

    }
}

then in you view you just add

@Html.InterstitialAd()

here's a video that might help you out some on how to create custom html helpers https://www.youtube.com/watch?v=2mACi5D739g

Upvotes: 0

LSU.Net
LSU.Net

Reputation: 849

I found a slightly different request, but similar need here. I'm assuming that there are controller actions behind all of your views. If so, you could add a custom action filter which populates the ViewBag for each action per the below.

EDIT: I should add that you could apply this filter to each action via a [CheckShownInterstitial] decoration or by registering as a global filter as the linked answer does.

Embedded code in Razor _Layout.cshtml

Something like the below

  public class CheckShownInterstitial : ActionFilterAttribute
{
    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        if (!filterContext.IsChildAction &&
            !filterContext.HttpContext.Request.IsAjaxRequest() &&
            filterContext.Result is ViewResult)
        {
            var ViewBag = filterContext.Controller.ViewBag;
            var Request = filterContext.HttpContext.Request;

            ViewBag.shownInterstitial = false;
            if (Request.Cookies["Interstitial"] != null)
            {
                ViewBag.shownInterstitial = true;
            }
            //Interstitial cookie does NOT exist.
            else
            {
                ViewBag.shownInterstitial = false;
            }
        }
    }
}

Upvotes: 1

Related Questions