2017-10-09 4 views
1

Bitte beachten Sie die Modelle unter:Geschützte Variablen und Modell Bindung

public class Apple //: Fruit 
    { 
     public string Description { get; set; } 
     public int Id { get; protected set; } 
    } 

    public class AppleModel 
    { 
     public int Id { get; set; } 
     public string Description { get; set; } 
    } 

und Controller unter:

[HttpPost] 
      public ActionResult Index(Apple apple) 
      { 
       return View(); 
      } 

      [HttpGet] 
      public ActionResult Index() 
      { 
       var AppleModel = new AppleModel(); 
       AppleModel.Id = 1; 
       AppleModel.Description = "Apple"; 
       var Apple = AutoMapper.Mapper.Map<Apple>(AppleModel); 
       return View("View1",Apple); 
      } 

und die Sicht unter:

@model PreQualification.Web.Controllers.Apple 

    @{ 
     ViewBag.Title = "View1"; 
    } 

    <h2>View1</h2> 


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

     <div class="form-horizontal"> 
      <h4>AppleModel</h4> 
      <hr /> 
      @Html.ValidationSummary(true) 


      <div class="form-group"> 
       @Html.LabelFor(model => model.Id) 
       <div class="col-md-10"> 
        @Html.EditorFor(model => model.Id) 
        @Html.ValidationMessageFor(model => model.Id) 
       </div> 
      </div> 

       <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 class="form-group"> 
        <div class="col-md-offset-2 col-md-10"> 
         <input type="submit" value="Save" class="btn btn-default" /> 
        </div> 
       </div> 
      </div> 
    } 

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

    @section Scripts { 
     @Scripts.Render("~/bundles/jqueryval") 
    } 

Apple.Id 0 in der HttpPost-Methode, da es sich um eine geschützte Variable im Modell handelt. Gibt es das überhaupt?

Der Grund, warum ich frage, ist, weil ich versuche, dies als Modell zu verwenden: https://github.com/nhibernate/NHibernate.AspNet.Identity/tree/master/source/NHibernate.AspNet.Identity und die ID in der Oberklasse enthalten ist geschützt.

+0

@David, ich habe meinen Beitrag aktualisiert. Es tut uns leid. – w0051977

+1

Warum verwenden Sie nicht auch 'AppleModel' in der Post-Methode? – adiga

Antwort

2

Es gibt mehrere Möglichkeiten, darunter eine untergeordnete Klasse, die ein public implementiert, dessen Setter den Wert auf das Feld mit der geschützten ID anwendet.

Diese sind jedoch Bandaids. Im Allgemeinen treten diese Probleme aufgrund eines Unterschieds auf, wie Leute Modelle betrachten. Entweder ist es ein wiederverwendbares Datentransferobjekt oder ist es nicht.

In der Welt, wo es nicht ist, müssen Sie Business-Objekte in bindefähige Modelle beschuhen und immer auf diese seltsamen Probleme stoßen.

In der Welt, in der sie sind, sind sie maßgeschneidert auf die Datenbedürfnisse zugeschnitten und werden in Geschäftsobjekte mit so etwas wie ein AutoMapper zugeordnet. Noch wichtiger: Wenn Sie ein Modell für diese Anforderung erstellen, schützen Sie sich vor Angriffen auf versehentlich exponierte Parameter.

Wenn das behelfsmäßige Geschäftsobjekt über öffentliche Eigenschaften verfügt, die Ihr Verhalten ändern, können diese durch Senden zusätzlicher Parameter mit der Postanforderung ausgenutzt werden.

Ich weiß, dass dies nicht speziell Ihre Frage beantwortet, aber den Pfad zu folgen, wo Modelle nicht DTO sind, ist wahrscheinlich auch nicht die richtige Antwort.

0

Wie von peewee_RotA ausgearbeitet, ist es besser, die konzeptionellen Unterschiede zwischen einem für eine Ansicht verwendeten Modell und einem Domänenmodell zu trennen, das tatsächlich eine Aktion ausführt oder direkt eine Aktion ausführt. Zu diesem Zweck müssen Sie ein Ansichtsmodell wie Apple

public class Apple 
{ 
    public string Description { get; set; } 
    public int Id { get; set; } 
} 

In Ihrem Beitrag Aktion, dann würden Sie haben; obwohl

[HttpPost] 
public ActionResult Index(Apple apple) 
{ 
    // translate your view model to your domain model 
    AppleModel model = new AppleModel(apple.Id, apple.Description); 
    model.DoStuff(); 
} 

In Bezug auf NHiberhate, es ist nicht leicht, das gewünschte Objekt mit der Ansicht Modell ID zu instanziiert und das ist der Kernpunkt Ihrer Frage denke ich. Sie versuchen, Ihr Domänenmodell als Ansichtsmodell zu verwenden, und das Domänenmodell ist ... legitimiert. Es ist Aufgabe zu steuern, wie IdentityUser und dergleichen instanziiert werden, da sie von den zugehörigen Factory-Klassen generiert werden sollen, nicht MVCs Modellbinder.

Lassen Sie Ihr View-Modell zu diesem Zweck so einfach wie möglich und nutzen Sie NHibernate's Factory-Klassen, um die erforderlichen Identity Objekte durch Nachschlagen der ID zu erstellen. This Link kann etwas Licht auf, wie die Benutzer-ID von Apple.Id übergeben.

EDIT

ich ein wenig mehr zu graben auf der Suche, um die Einheit in NHibernate und die following Post getan haben scheint, die Grundlagen zu tun. Erhält das, was Sie brauchen?