Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Request.ServerVariables throws NullReferenceException

I have an MVC3 application, which is suddenly giving me some strange behavior. First some background (although I'll try to make this as brief as possible).

In my controller action, I have this code:

public ActionResult Grid(ApplicationViewModel search = null)
{
    return this.ListView(
        this.Find<Entity>(),
        this.CreateViewModel,
        mixins: new Dictionary<string, Func<EntityViewModel, object>>()
        {
            { "Icon", vm => Url.Content("~\Images\entityType.png") },
            { "Link", vm => Url.Action("Details", vm.ControllerId) }
        });
}

EntityViewModel CreateViewModel(Entity entity);

// Inherited base class methods
protected IQueryable<T> Find<T>(); // Find T entities in DB

protected ListViewResult<TModel, TViewModel> ListView<TModel, TViewModel>(
    IQueriable<TModel> entityQuery, 
    Func<TModel, TViewModel> materializeViewModel,
    IDictionary<string, Func<TViewModel, object>> mixins);

This controller action hides a fair amount of complex logic, because ListViewResult is a custom result ActionResult designed specifically for formatting JSON lists.

public class ListViewResult<TModel, TViewModel> :
    ActionResult
{
    public IQueryable<TModel> ViewData { get; set; }
    public Func<TModel, TViewModel> Materialize { get; set; }
    public Dictionary<string, Func<TViewModel, object>> Mixins { get; private set; }

    ...

    public override void ExecuteResult(ControllerContext context)
    {
        // Perform sorting / paging / formatting on IQueryable

       ...

        var viewModels = this.ViewData.Select(this.Materialize);
        try
        {
            // another custom ActionResult for formatting JSON responses
            new JsonNetResult()
            {
                Data = viewModels.ToArray(),
                SerializerSettings = new JsonSerializerSettings()
                {
                    ContractResolver = new MixinContractResolver() 
                    {
                        Mixins = this.Mixins
                    }
                }
            }.ExecuteResult(context);
        }
        catch (Exception e)
        {
            context.HttpContext.Response.StatusCode = 500;
            context.HttpContext.Response.StatusDescription = e.Message;
        }
    }

    private class MixinContractResolver :
        CamelCasePropertyNamesContractResolver
    {
        public Dictionary<string, Func<TViewModel, object>> Mixins { get; set; }

        private List<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
        {
            List<JsonProperty> props = // get base properties
            foreach (var pair in this.Mixins)
            {
                props.Add(new JsonProperty()
                {
                    Ignored = false,
                    NullValueHandling = NullValueHandling.Include,
                    Readable = true,
                    PropertyName = Inflector.Camelize(pair.Key),
                    PropertyType = typeof(object),
                    ValueProvider = new DelegateValueProvider<TViewModel, object>(pair.Value),
                    Writable = false,
                });
            }
        }
    }

    private class DelegateValueProvider<T, R> :
        Newtonsoft.Json.Serialization.IValueProvider
    {
        private readonly Func<T, R> func;

        public DelegateValueProvider(Func<T, R> func)
        {
            this.func = func;
        }

        public object GetValue(object target)
        {
            return (R)this.func((T)target);
        }

        public void SetValue(object target, object value)
        {
            throw new NotSupportedException();
        }
    }
}

Now, it seems that occasionally a NullReferenceException's being thrown at the line vm => Url.Content(...) and vm => Url.Action(...). This does not always happen, but if I refresh a few times, I can reliably reproduce it.

Update

After digging around in the source code for a while, I believe I've uncovered the offending code. The issue seems to be with the UrlRewriterHelper.WasThisRequestRewritten method which calls ServerVariables.Get("IIS_WasUrlRewritten"). It seems that method makes use of a private field named _request which is null at this point in the code (for some reason). My best guess is that some time between the action returning and the result executing, the ServerVariables collection either looses it's internal reference to _request - OR - the ServerVariables collection is being recreated without a valid reference to _request.

I've also realized that this may be an issue with IIS Express. When running under the Visual Studio Development Server, I haven't been able to duplicate the issue. I've updated the tags to reflect what think is are the most likely causes.

like image 756
p.s.w.g Avatar asked Feb 28 '13 22:02

p.s.w.g


2 Answers

I just had this same issue with IIS Express and found that it was because I had installed the URL Rewrite Extension to IIS and then uninstalled it, but it had left some configuration in the applicationhost.config file for IIS Express. (C:\Users\\Documents\IISExpress\config\applicationhost.config)

I just commented out the related lines in that file, killed IIS Express and reran and I didn't see the issue again.

The two lines I commented out are commented in the snippet below.

<configuration>
    ...
    <system.webServer>
        ...
        <globalModules>

           <!--<add name="RewriteModule" image="%IIS_BIN%\rewrite.dll" />-->
           ...
        </globalModules>
    </system.webServer>
    <location path="" overrideMode="Allow">
        <system.webServer>
          <modules>
              <!--<add name="RewriteModule" />--> 
              ...
          </modules>
        </system.webServer>
    </location>
</configuration>
like image 82
matter Avatar answered Nov 06 '22 02:11

matter


Check in visual studio that you haven't checked off to show all exceptions while debugging. This could just be an internally handled exception that you are seeing because of your Debug-> exceptions settings.

Check if Just My Code is unchecked and if you now show two rows of checkboxes inthe debug-> exceptions windows.

like image 1
Adam Tuliper Avatar answered Nov 06 '22 00:11

Adam Tuliper