Autofac non vincolando i dati in ViewModel
-
02-01-2020 - |
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 ...
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.
- .
- 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
. - 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. - Messaggi del modulo si legano a Azione Parametri, non Costruttore Parametri. Dovresti avere un metodo di azione che accetta un oggetto
Master
.
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).