Possiedo un'applicazione MVC3, che improvvisamente mi dà un comportamento strano. Prima un po 'di background (anche se cercherò di renderlo il più breve possibile).Request.ServerVariables genera NullReferenceException
Nella mia azione di controllo, ho questo codice:
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);
Questa azione di controllo nasconde una buona dose di logica complessa, perché ListViewResult
è un risultato personalizzato ActionResult
progettato specificamente per la formattazione degli elenchi JSON.
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();
}
}
}
Ora, sembra che ogni tanto un NullReferenceException
's gettati alla linea vm => Url.Content(...)
e vm => Url.Action(...)
. Questo non avviene sempre, ma se si aggiorna alcune volte, posso riprodurlo in modo affidabile.
Aggiornamento
Dopo aver scavato intorno nel codice sorgente per un po ', credo di aver scoperto il codice incriminato. Il problema sembra essere con il metodo UrlRewriterHelper.WasThisRequestRewritten
che chiama ServerVariables.Get("IIS_WasUrlRewritten")
. Sembra che il metodo utilizzi un campo privato denominato _request
che è null
a questo punto nel codice (per qualche motivo). La mia ipotesi migliore è che un po 'di tempo tra il ritorno dell'azione e il risultato dell'esecuzione, la collezione ServerVariables
o perde il riferimento interno a _request
- O - la raccolta ServerVariables
viene ricreata senza un riferimento valido a _request
.
Ho anche capito che questo potrebbe essere un problema con IIS Express. Durante l'esecuzione in Visual Studio Development Server, non sono stato in grado di duplicare il problema. Ho aggiornato i tag per riflettere su quali sono le cause più probabili.
Interessante domanda, +1. – Brian
era questo dal debug o semplicemente spunta? –
Debug. Mi sono anche reso conto che '_request' è impostato su null da' ServerVarsCollection.Dispose'. Quindi, forse il controller si sta disperdendo (ancora non spiega perché ricevo questo errore solo occasionalmente). –