7

MVC3 アプリケーションを使用していますが、突然奇妙な動作が発生します。最初にいくつかの背景を説明します (ただし、これをできるだけ簡潔にしようとします)。

私のコントローラー アクションには、次のコードがあります。

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);

このコントローラー アクションは、 JSON リストの書式設定専用に設計されListViewResultたカスタム結果であるため、かなりの量の複雑なロジックを隠しています。ActionResult

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();
        }
    }
}

さて、ときどき aNullReferenceExceptionが行に投げられているようですvm => Url.Content(...)and vm => Url.Action(...). これは常に発生するわけではありませんが、数回更新すると、確実に再現できます。

アップデート

しばらくソース コードを調べてみたところ、問題のあるコードが明らかになったと思います。問題は、UrlRewriterHelper.WasThisRequestRewrittenを呼び出すメソッドにあるようServerVariables.Get("IIS_WasUrlRewritten")です。メソッドは、コードのこの時点で(何らかの理由で)_requestという名前のプライベートフィールドを使用しているようです。null私の最善の推測は、アクションが返されてから結果が実行されるまでの間に、コレクションが への内部参照を失うServerVariablesか、コレクションが への有効な参照なしで再作成されていることです。_requestServerVariables_request

また、これは IIS Express の問題である可能性があることにも気付きました。Visual Studio Development Server で実行している場合、問題を再現できませんでした。最も可能性の高い原因と思われるものを反映するようにタグを更新しました。

4

2 に答える 2

3

IIS Express でこれと同じ問題が発生したところ、IIS に URL 書き換え拡張機能をインストールしてからアンインストールしたことが原因であることがわかりましたが、IIS Express の applicationhost.config ファイルにいくつかの構成が残っていました。(C:\Users\\Documents\IISExpress\config\applicationhost.config)

そのファイルの関連行をコメントアウトし、IIS Express を強制終了して再実行しましたが、問題は再び発生しませんでした。

私がコメントアウトした 2 行は、以下のスニペットでコメント化されています。

<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>
于 2013-03-28T01:18:09.477 に答える
1

デバッグ中にすべての例外を表示するには、チェックしていないビジュアル スタジオをチェックインします。これは、Debug-> exceptions の設定が原因で、内部的に処理された例外である可能性があります。

Just My Code がチェックされていないかどうか、および debug-> exceptions ウィンドウに 2 行のチェックボックスが表示されているかどうかを確認します。

于 2013-02-28T23:37:07.780 に答える