«Не удается создать экземпляр интерфейса» (мастер MvC 3 внутри Orchard CMS) - PullRequest
2 голосов
/ 09 ноября 2011

Основываясь на отличном ответе на проблемы многоэтапной регистрации в asp.net mvc (разделенные модели просмотра, одиночная модель) , я использовал предоставленный Дарином Димитровым пример для тестирования мастера ASP.net MVC3 , Работает автономно, но не внутри Orchard CMS v1.3.

Я получаю следующую ошибку:


Ошибка сервера в приложении '/'.

Невозможно создать экземпляр интерфейса.

Описание: необработанное исключение произошло во время выполнения текущий веб-запрос. Пожалуйста, просмотрите трассировку стека для более информация об ошибке и ее возникновении в коде.

Сведения об исключении: System.MissingMethodException: невозможно создать экземпляр интерфейса.

Ошибка источника:

Во время выполнения текущий веб-запрос. Информация о происхождении и местонахождении исключение можно определить с помощью трассировки стека исключений, приведенной ниже.

Трассировка стека:

[MissingMethodException: невозможно создать экземпляр интерфейса.]
System.RuntimeTypeHandle.CreateInstance (тип RuntimeType, логическое значение publicOnly, Boolean noCheck, Boolean & canBeCached, RuntimeMethodHandleInternal & ctor, Boolean & bNeedSecurityCheck) + 0
System.RuntimeType.CreateInstanceSlow (Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache) + 98
System.RuntimeType.CreateInstanceDefaultCtor (Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache) +241 System.Activator.CreateInstance (тип, логическое значение непубличный) + 69
System.Web.Mvc.DefaultModelBinder.CreateModel (ControllerContext controllerContext, ModelBindingContext bindingContext, Тип modelType) +199 System.Web.Mvc.DefaultModelBinder.BindComplexModel (ControllerContext controllerContext, ModelBindingContext bindingТекст) + 572
System.Web.Mvc.DefaultModelBinder.BindModel (ControllerContext controllerContext, ModelBindingContext bindingТекст) + 449
System.Web.Mvc.ControllerActionInvoker.GetParameterValue (ControllerContext controllerContext, ParameterDescriptor параметрDescriptor) + 317
System.Web.Mvc.ControllerActionInvoker.GetParameterValues ​​(ControllerContext controllerContext, ActionDescriptor actionDescriptor) + 117
System.Web.Mvc.ControllerActionInvoker.InvokeAction (ControllerContext controllerContext, String actionName) + 343
System.Web.Mvc.Controller.ExecuteCore () + 116
System.Web.Mvc.ControllerBase.Execute (RequestContext requestContext) +97 System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute (RequestContext requestContext) + 10
System.Web.Mvc. <> C__DisplayClassb.b__5 () + 37
System.Web.Mvc.Async. <> C__DisplayClass1.b__0 () + 21
System.Web.Mvc.Async. <> C__DisplayClass8 1.<BeginSynchronous>b__7(IAsyncResult _) +12 System.Web.Mvc.Async.WrappedAsyncResult 1.End () +62 System.Web.Mvc. <> C__DisplayClasse.b__d () + 50
System.Web.Mvc.SecurityUtil.b__0 (Действие f) +7 System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust (Действие действия) +22 System.Web.Mvc.MvcHandler.EndProcessRequest (IAsyncResult asyncResult) + 60
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest (IAsyncResult результат) + 9
Orchard.Mvc.Routes.HttpAsyncHandler.EndProcessRequest (IAsyncResult результат в D: \ Строит \ OrchardFull \ SRC \ Орчард \ Mvc \ \ Маршруты ShellRoute.cs: 148
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute () +8963149 System.Web.HttpApplication.ExecuteStep (шаг IExecutionStep, логический и завершен синхронно) + 184

Информация о версии: Microsoft .NET Framework Версия: 4.0.30319; ASP.NET версия: 4.0.30319.237


Рискну предположить, что именно контроллер вызывает суету. Вот код:

[Themed]
    public class WizardController : Controller
    {
        public ActionResult Index()
        {
            var wizard = new WizardViewModel();
            wizard.Initialize();
            return View(wizard);
        }

        [HttpPost]
        public ActionResult Index([Deserialize] WizardViewModel wizard, IStepViewModel step)
        {
            wizard.Steps[wizard.CurrentStepIndex] = step;
            if (ModelState.IsValid)
            {
                if (!string.IsNullOrEmpty(Request["next"]))
                {
                    wizard.CurrentStepIndex++;
                }
                else if (!string.IsNullOrEmpty(Request["prev"]))
                {
                    wizard.CurrentStepIndex--;
                }
                else
                {
                    // TODO: we have finished: all the step partial
                    // view models have passed validation => map them
                    // back to the domain model and do some processing with
                    // the results

                    return Content("thanks for filling this form", "text/plain");
                }
            }
            else if (!string.IsNullOrEmpty(Request["prev"]))
            {
                // Even if validation failed we allow the user to
                // navigate to previous steps
                wizard.CurrentStepIndex--;
            }
            return View(wizard);
        }
    }

Но я не уверен на 100%, и другим виновником может быть WizardViewModel:

[Serializable]
public class WizardViewModel
{
    public int CurrentStepIndex { get; set; }
    public IList<IStepViewModel> Steps { get; set; }

    public void Initialize()
    {
        Steps = new IStepViewModel[]
        {
            new Step1ViewModel(),
            new Step2ViewModel(),
            new Step3ViewModel()
        };
    }
}

Эта последняя часть представляет собой ручную вставку шагов и изменяет первоначально опубликованный код (напрямую от автора),Любая помощь с благодарностью.

1 Ответ

5 голосов
/ 09 ноября 2011

Судя по всему, используемое средство связывания моделей не может найти модель, для которой необходимо создать экземпляр, из предоставленного интерфейса (IStepViewModel)

Я вполне уверен, что ASP.NET MVC ModelBinder по умолчанию не может сделать такую ​​вещь, поскольку для выбора конкретной реализации интерфейса, которая должна быть реализована, потребовалась бы некоторая пользовательская логика.

Таким образом, у вас есть два решения:

  1. Проверьте ваш пример, я думаю, что он предоставляет собственный ModelBinder, и зарегистрируйте его в Orchard, реализовав IModelBinderProvider
  2. Не запрашивать IStepViewModel в действии Index:

    public ActionResult Index([Deserialize] WizardViewModel wizard, IStepViewModel step)
    

    И заменить его конкретным классом.

...