Domanda

Ho un'interfaccia che ha una proprietà che è un elenco di un'altra interfaccia e una classe che ha implementato quell'interfaccia, lo ha registrato per Autofac, ma il mio problema è Autofac non vincolando i dati alla mia classe, ho scritto il mio codice qui sotto:

Le mie interfacce:

public interface IDetail
{
    int Id { get; set; }

    string Name { get; set; }
}

public interface IMaster
{
    int Id { get; set; }

    DateTime Description { get; set; }

    List<IDetail> Details { get; set; }
}
.

Le mie classi:

public class Detail : IDetail
{
    public int Id { get; set; }

    public string Name { get; set; }
}

public class Master : IMaster
{
    public int Id { get; set; }

    public DateTime Description { get; set; }

    public List<IDetail> Details { get; set; }
}
.

Il mio controller:

public class HomeController : Controller
    {
        IMaster _t;

        [HttpPost]
        public ActionResult Create(IMaster t)
        {
            _t = t;
        }


    }
.

La mia registrazione Autofac:

    public class DependencyConfigure
        {
//Initializing
            public static void Initialize()
            {
                RegisterServices();
            }

//Registering
            private static void RegisterServices()
            {

                ContainerBuilder builder = new ContainerBuilder();

                builder.RegisterAssemblyTypes(
                    typeof(MvcApplication).Assembly
                    ).PropertiesAutowired();            

                builder.RegisterType<ExtensibleActionInvoker>()
                .As<IActionInvoker>()
                .WithParameter("injectActionMethodParameters", true);
                        builder.RegisterControllers(Assembly.GetExecutingAssembly())
                            .InjectActionInvoker();

                builder.RegisterType(typeof(Master)).As(typeof(IMaster));

                var container = builder.Build();
                DependencyResolver.SetResolver(new AutofacDependencyResolver(container));            
            }

        }
.

E la vista è qui:

@model WebApplication1.Models.Master

@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()

        <div class="form-group">
            @Html.LabelFor(model => model.Description, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Description)
                @Html.ValidationMessageFor(model => model.Description)
            </div>
        </div>

        <div>
            @Html.Label("Details.Name", new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.Editor("Details[0].Name")                
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>
.

In altre parole, quando suppongo, i dati non si legano a master.details ...

È stato utile?

Soluzione 2

La risposta giusta è qui, per questi motivi è necessario scrivere un legante personalizzato su MVC prima di associare i dati sul tuo ViewModel, creare un'istanza di ViewModel e quindi vincolare i dati per ViewModel.Puoi vedere un campione di Binder qui (che ha scritto dal mio caro Freind Senior Developer @Saeed Hamed)

public class InterfaceModelBinderProvider : IModelBinderProvider
{
    public IModelBinder GetBinder(Type modelType)
    {
        if (modelType.IsInterface)
        {
            return new InterfaceModelBinder();
        }
        return null;
    }
}
public class InterfaceModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var item = DependencyResolver.Current.GetService(bindingContext.ModelType);

        bindingContext.ModelMetadata = new ModelMetadata(new DataAnnotationsModelMetadataProvider(),
            bindingContext.ModelMetadata.ContainerType, () => item, item.GetType(), bindingContext.ModelName);

        return base.BindModel(controllerContext, bindingContext);
    }
}
.

Altri suggerimenti

stai facendo alcune cose che non ti sbagliano qui.

    .
  1. Autofac non ha nulla a che fare con il binding del modello. Autofac è per iniettare dipendenze nel costruttore del controller; Il Binder Model MVC ASP.NET Bindisce le richieste HTTP per i parametri di azione. Sono preoccupazioni completamente separate. Sbarazzati della tua iniezione di dipendenza IMaster.
  2. MVC non può associare un post di modulo su un'interfaccia perché non sa quale tipo di calcestruzzo istanziata. Dimentica l'interfaccia IMaster e usa un tipo di modello di vista concreto.
  3. Messaggi del modulo si legano a Azione Parametri, non Costruttore Parametri. Dovresti avere un metodo di azione che accetta un oggetto Master.
  4. Supponendo che questa sia la tua azione di indice, dovresti avere un metodo di azione che sembra qualcosa di simile al tuo HomeController:

    [HttpPost]
    public ActionResult Index(Master model)
    {
        ...
    }
    
    .

    Potrebbe essere necessario effettuare altre modifiche per ottenere dove stai andando ma questo dovrebbe renderti via sulla strada giusta (in questo momento il tuo codice sembra molto confuso).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top