Wiki Link: [discussion:25378]
How to handle QueryString in WCSF?  

Tags: Web Client Software Factory, Project Management Forum, UIP Application Block discussion, User Forum

Apr 4 2008 at 7:40 PM
Hi !!

How do we handle querystring is WCSF Feb 2008?

Apr 4 2008 at 8:50 PM
Edited Apr 4 2008 at 9:59 PM


t_shah wrote:
Hi !!

How do we handle querystring is WCSF Feb 2008?


You can take advantage of the HttpContextLocatorService (it is available to all modules). I make it available to my controller so that I can use it in both my controller and presenter - an example follows:

Controller
    public class ReportsController : IReportsController
    {
        private IHttpContext _context;
        public IHttpContext Context
        {
            get { return _context; }
            set { _context = value; }
        }
 
        public ReportsController() { }
 
        [InjectionConstructor]
        public ReportsController([ServiceDependency]IHttpContextLocatorService service)
        {
            _context = service.GetCurrentContext();
        }
    }

Presenter be sure to add a reference to System.Web as Microsoft.Practices.CompositeWeb.Interfaces.IHttpContext utilizes references from it, i.e., System.Web.HttpRequest Request { get; }
    public class DefaultViewPresenter : Presenter<IDefaultView>
    {
        private IReportsController _controller;
 
        public DefaultViewPresenter([CreateNew] IReportsController controller)
        {
            this._controller = controller;
 
 
        }
        public override void OnViewLoaded()
        {
            string queryString = _controller.Context.Request.QueryString["MyValue"];            
            base.OnViewLoaded();
        }
    }


Controller Interface
    public interface IReportsController
    {
        IHttpContext Context { get; set; }
    }

Curious... In a different message you noted the following - I was curious where and why???

"As far as my understanding goes we don't want System.Web in our presenter module. If thats the case, How can I set/get something from "HttpContext.Current.Cache""




Coordinator
Apr 4 2008 at 10:00 PM
To be clear, the HttpContext BillKrat uses above is a Microsoft.Practices.CompositeWeb.Web.HttpContext, which implements Microsoft.Practices.CompositeWeb.Interfaces.IHttpContext.
I would use the interface, where he uses the derived class, for looser coupling and mockability.
Also, I woudl add to my Presenter or Controller (I would have to actually try it first to determine where it "feels" right) a property for each QueryString value I wanted. It might look something like this:
public string MyValue // Or MyValueFromQueryString if you want to be verbose
{
  get 
  {
     return QueryStringValueResolver.GetValueFromQueryString(Resources.MyValue, (IHttpContext)context );
  }
}

And QueryStringValueResolver would do the lookup, handle errors for when there is a null Reqest and a null QueryString and when the requested key was not there by throwing the appropriate exceptions.

Enjoy,
Michael Puleio - patterns & practices
Webhttp://msdn.microsoft.com/practices/
Bloghttp://blogs.msdn.com/mpuleio/

Apr 4 2008 at 10:44 PM
Edited Apr 4 2008 at 10:55 PM

MichaelPuleio wrote:
To be clear, the HttpContext BillKrat uses above is a Microsoft.Practices.CompositeWeb.Web.HttpContext, which implements Microsoft.Practices.CompositeWeb.Interfaces.IHttpContext.
I would use the interface, where he uses the derived class, for looser coupling and mockability.


Yep, looks like I saved my edit 1 minute before you posted your rcomment so they may not get that I was using HttpContext versus IHttpcontext (I caught this while writing a unit test using pbolduc's code from the http://www.codeplex.com/websf/Thread/View.aspx?ThreadId=24600 message thread.

A variation of his test (to support the controller holding the httpcontext) follows:
using System;
using System.Text;
using System.Web;
using System.Web.Caching;
using System.Collections.Generic;
using Microsoft.Practices.CompositeWeb;
using Microsoft.Practices.CompositeWeb.Services;
using Microsoft.Practices.CompositeWeb.Interfaces;
using UserInfo.Views;
using UserInfo.Tests.Mocks;
using Rhino.Mocks;
 
// This little snippet was borrowed from the ObjectBuilder's unit test - allows us
// to use the default VS2008 test with NUnit.
#if !NUNIT
using Microsoft.VisualStudio.TestTools.UnitTesting;
#else
using NUnit.Framework;
using TestClass = NUnit.Framework.TestFixtureAttribute;
using TestMethod = NUnit.Framework.TestAttribute;
using TestInitialize = NUnit.Framework.SetUpAttribute;
using TestCleanup = NUnit.Framework.TearDownAttribute;
#endif
 
namespace UserInfo.Tests
{
    /// <summary>
    /// Summary description for UserInfoModuleInitializerFixture
    /// </summary>
    [TestClass]
    public class UserInfoModuleControllerFixture
    {
        private MockRepository mocks;
 
        public UserInfoModuleControllerFixture()
        {
        }
 
        [TestInitialize]
        public void Setup()
        {
            mocks = new MockRepository();
        }
 
        [TestMethod]
        public void ViewLoadedSetsCache()
        {
            // mock up our IHttpContextLocatorService
            IHttpContextLocatorService httpContextLocatorService = mocks.DynamicMock<IHttpContextLocatorService>();
 
            // wire up the mock repository
            IHttpContext httpContext = mocks.DynamicMock<IHttpContext>();
            SetupResult.For(httpContextLocatorService.GetCurrentContext()).Return(httpContext);
 
            // we'll just use HttpRuntime.Cache which is available outside ASP.NET
            Cache cache = HttpRuntime.Cache;
            SetupResult.For(httpContext.Cache).Return(cache);
 
            mocks.ReplayAll(); // 
 
            MockUserInfoController controller = new MockUserInfoController();
            controller.Context = httpContext;
 
            DefaultViewPresenter presenter = new DefaultViewPresenter(controller);
            presenter.View = mocks.DynamicMock<IDefaultView>();
 
            Assert.AreEqual(0, cache.Count);
            Assert.IsNull(cache["DefaultViewPresenter_NameKey"]);
 
            presenter.OnViewLoaded();
 
            Assert.AreEqual(1, cache.Count);
            Assert.IsNotNull(cache["DefaultViewPresenter_NameKey"]);
        }
    }
}

DefaultViewPresenter
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Practices.ObjectBuilder;
using Microsoft.Practices.CompositeWeb;
 
namespace UserInfo.Views
{
    public class DefaultViewPresenter : Presenter<IDefaultView>
    {
        private IUserInfoController _controller;
 
        public DefaultViewPresenter([CreateNew] IUserInfoController controller)
        {
            this._controller = controller;
        }
 
        public override void OnViewLoaded()
        {
            string name = _controller.Context.Cache["DefaultViewPresenter_NameKey"] as string;
            if (name == null)
            {
                name = "Phil";  // this would come from some service or something
                _controller.Context.Cache["DefaultViewPresenter_NameKey"] = name;
            }
 
            base.OnViewLoaded();
        }
 
        public string GetQueryStringValue(string queryName)
        {
            string queryString = _controller.Context.Request.QueryString[queryName];
            return queryString;
        }
    }
}

IUserInfoController interface
using System;
using Microsoft.Practices.CompositeWeb.Web;
using Microsoft.Practices.CompositeWeb.Interfaces;
 
namespace UserInfo
{
    public interface IUserInfoController
    {
        IHttpContext Context { get; set; }
    }
}




Apr 7 2008 at 5:02 PM
Thanks. This helps a lot. Another question.

I have various modules eg. Shell, Module1, Module2 etc. if I had to share a QueryString value or Session value across module, how do I do that? Do I have to create an instance of IHttpContextService or StateValue variable with same name on each of the modules?

Thanks,

Apr 9 2008 at 4:23 PM
Hi,

To obtain those values you can first fetch the IHttpContextLocatorService and call its GetCurrentContext() method to obtain a WCSF IHttpContext object which encapsulates the ASP.NET HttpContext. With this object you can have access to the Session and Request.QueryString properties.

Moreover, you may decorate the member variable you want to share across different classes with the SessionStateKey attribute to specify the session item key.

Related topic: How to Share Session Variable between Shell and other Module

You may read more information on SessionStateKey in this WCSF Help Topic: How to: Use Session State with Unit Testing.

Ignacio Baumann Fonay
http://staff.southworks.net/blogs/ibaumann/

Updating...
© 2006-2010 Microsoft | About CodePlex | Privacy Statement | Terms of Use | Code of Conduct | Advertise With Us | Version 2010.1.12.16187