DevJEDI Academy or #maritimedevcon 2016

By Sebastien AubeJune 6, 2016 at 9:27 AM

On the morning of June 4th, 2016 at 7:15 AM a contingent of seven padawans met at the Cognitive X Solutions offices to make the trip to Fredericton where fellow Padawans and DevJEDIs are hosting #martimtimedevcon. 

After a few years hiatus, the organisers brought it back in 2015 and in 2016 the conference has already gained some astonishing momentum.  Hundreds of developers and technologist congregated at the WU Centre to learn new tricks and news methods to wield the technology force and a few soft skill sessions brought in the mix. 

Among the many subjects, the overarching theme seemed to be building highly available, scalable and fault tolerant solutions. Topics such as Docker, the Actor Model, and Recursive Architecture helped us peer into the world of (micro, nano)services. As a dev padawan, I just want to dig deeper and see how we can apply these techniques to what we do at Cognitive X Solutions.

On the other hand, we were lucky to see presentations on soft skills such as product management, dealing with a complex project with tight deadlines and a presentation on making a presentation. What the presentation is for the audience and not for the presenter? There were some great tidbits in each of those presentations that I will indeed adopt or adapt in my daily activities.

Kudos to the organising team, sponsors and speakers for putting on such a great conference. I would give you the titles of dev Jedi, but you're probably too humble. We'll go with high padawan, seems to fit your persona better. This conference made many dev padawans happy.

Posted in: Learning | Programming

Tags:



ASP.NET MVC 4 and Mocking ModelState

By Adam GreeneAugust 23, 2012 at 8:37 AM

Actually, mocking isn’t quite the word (but we’ll talk about that in a moment).

At Cognitive X, we specialize in web development using ASP.NET MVC (currently using V4), and we very much love Test Driven Development.  So as part of our development process with MVC, we write tests for our Controller Actions.  One of the problems that we run into with testing controllers outside of the MVC framework is that they are not fully setup and many pieces are missing that allow the controller to function properly.  The biggest one being ModelState.

For example, given the following piece of code, no matter what, it always returns true because the ModelState is actually empty, when run outside the normal MVC pipeline:

if (ModelState.IsValid)
{
    // Perform action
}

So inorder to properly test our controllers, we wrote a method that would take the model and setup ModelState correctly (including running all validations on the model).  It was quite easy with V3 of ASP.NET MVC to do this, but with MVC 4 and the introduction of so many new providers (ModelMetaDataProviders, ValueProviders, etc), the old way no longer worked. I spent a morning chasing ModelStateDictionaries through the MVC code (thank goodness for ILSpy, it made my life so much easier), trying to figure out where it actually got filled out.  What I eventually hit upon was the code hidden within the Controller.TryValidateModel, which did exactly what I wanted it to do. The only problem is that it’s protected internal and no good for a general support extension.  So I pulled the code out, rewrote it a bit, and here it is:

public static void SetupModel<T>(this Controller ctrl, T model)
        {
            if (ctrl.ControllerContext == null)
            {
                Mock<ControllerContext> ctx = new Mock<ControllerContext>();
                ctrl.ControllerContext = ctx.Object;
            }

            DataAnnotationsModelMetadataProvider provider = new DataAnnotationsModelMetadataProvider();

            var metadataForType = provider.GetMetadataForType(() => model, typeof(T));
            var temp = new ViewDataDictionary();

            foreach (var kv in new RouteValueDictionary(model))
            {
                temp.Add(kv.Key, kv.Value);
            }

            DefaultModelBinder binder = new DefaultModelBinder();

            ctrl.ViewData = new ViewDataDictionary(temp) { ModelMetadata = metadataForType, Model = model };

            foreach (ModelValidationResult current in ModelValidator.GetModelValidator(metadataForType, ctrl.ControllerContext).Validate(null))
            {
                ctrl.ViewData.ModelState.AddModelError(CreateSubPropertyName("", current.MemberName), current.Message);
            }
        }

So like I said, Mocking is not really the right word for it, it’s actually setting up ModelState to contain the right validation information / model errors, so that controller actions work as expected.

Posted in: Programming

Tags:



WCF: Multiple Secure Ports

By Adam GreeneJune 25, 2012 at 5:09 AM

The Problem

We were faced with an interesting issue on a project recently.  We had WCF (Windows Communication Framework) running on a custom port (as IIS does not allow more than one HTTPS site per port, per IP) and once we purchased a second IP address, we moved the web services site to the regular HTTPS port (443) on that new URL.  But because we already had clients in the field running the application that called the web services, we needed to maintain both ports on the same DNS name (443 and the custom port).   The problem?  WCF does not support this scenario without modification, especially if you have a custom ServiceHost (which we do as we wanted to introduce StructureMap into the WCF bootstrap process).  Let’s look at the solution.

The Solution

The first step in the solution is to tell WCF that you actually want to support this scenario.  You simply add the following line (line #2) to your web.config file in your WCF web services web site:

<system.serviceModel>
		<serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
		<bindings>
			<basicHttpBinding>
				<binding name="BasicHttpBinding_INotify" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferSize="524288" maxBufferPoolSize="524288" maxReceivedMessageSize="524288"
                    messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                    useDefaultWebProxy="true">
					<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
					<security mode="TransportWithMessageCredential">
						<transport clientCredentialType="None" proxyCredentialType="None"
                            realm="" />
						<message clientCredentialType="UserName" algorithmSuite="Default" />
					</security>
				</binding>
			</basicHttpBinding>
		</bindings>
</system.serviceModel>

 

The next step is to make sure that all your end points are using relative Uri’s and not absolute.  In our custom ServiceHostwe had the following code (note line #27):

public ServicesServiceHost(Type serviceType, params Uri[] baseAddresses)
            : base(serviceType, baseAddresses)
        {
            serviceBehaviourType = typeof(ServicesServiceBehavior<>).MakeGenericType(serviceType);
            Initialize(serviceType, baseAddresses);
        }

protected void Initialize(Type serviceType, params Uri[] baseAddresses)
        {
            var httpsAddresses = from ba in baseAddresses
                                 where ba.Scheme == Uri.UriSchemeHttps
                                 select ba;

            ConfigureAuthentication();

            foreach (var httpsAddress in httpsAddresses)
            {
                var serviceContract = serviceType.GetInterfaceWithAttribute(typeof(ServiceContractAttribute));
                if (serviceContract == null)
                {
                    serviceContract = serviceType;
                }

                var binding = ConfigureBinding();
                try
                {
                    this.AddServiceEndpoint(serviceContract, binding, httpsAddress);
                }
                catch (Exception e)
                {
                }

                if (!this.Description.Behaviors.Contains(typeof(ServiceMetadataBehavior)))
                {
                    this.Description.Behaviors.Add(new ServiceMetadataBehavior()
                    {
                        HttpGetEnabled = true
                    });
                }
                var mex = MetadataExchangeBindings.CreateMexHttpBinding();
                this.AddServiceEndpoint(typeof(IMetadataExchange), mex, "mex");

                ((ServiceDebugBehavior)this.Description.Behaviors[typeof(ServiceDebugBehavior)])
	.IncludeExceptionDetailInFaults = true;
                ServiceSecurityAuditBehavior ssab = new ServiceSecurityAuditBehavior()
                {
                    AuditLogLocation = AuditLogLocation.Application,
                    MessageAuthenticationAuditLevel = AuditLevel.SuccessOrFailure,
                    ServiceAuthorizationAuditLevel = AuditLevel.SuccessOrFailure,
                    SuppressAuditFailure = false
                };
                this.Description.Behaviors.Add(ssab);
            }
        }

The simple solution was to change line #27 to:

this.AddServiceEndpoint(serviceContract, binding, "");

and everything worked.  To achieve the same results in XML, you simply would add an endpoint description to the XML like this (note that the address attributes are empty):

<service 
    name="Microsoft.ServiceModel.Samples.CalculatorService"
    behaviorConfiguration="CalculatorServiceBehavior">
  <!-- This endpoint is exposed at the base address provided by host: http://localhost/servicemodelsamples/service.svc  -->
  <endpoint address=""
            binding="basicHttpBinding"
            contract="Microsoft.ServiceModel.Samples.ICalculator" />
  <!-- secure endpoint exposed at {base address}/secure: http://localhost/servicemodelsamples/service.svc/secure -->
  <endpoint address="secure"
            binding="wsHttpBinding"
            contract="Microsoft.ServiceModel.Samples.ICalculator" />
  ...
</service>

Posted in: Programming

Tags: