2016-07-05 42 views
1

Ich habe einen Nancy Service, der eine Ansicht rendert. Die Ansicht enthält zwei Modelle, Mitarbeiter und Person. Beide Modelle haben eine Eigenschaft namens Name. Wenn diese Werte zurückgeschickt werden, scheint Nancy den ersten Bind <> zu übernehmen und wendet ihn auf beide Eigenschaften mit dem gleichen Namen an. Gibt es eine Möglichkeit, die Eingabe an ein bestimmtes Modell zu binden, das ich anders als unten beschrieben habe?Nancy Bindung an Modelle mit gleichen Eigenschaften

Dies ist das Modul.

public class IndexModule : NancyModule 
{ 
    public IndexModule() 
     : base("/") 
    { 
     Get["/"] = parameters => 
     { 
      var returnModel = new ReturnModel(); 

      return View["index.cshtml", returnModel]; 
     }; 

     Post["/"] = parameters => 
     { 
      var person = this.Bind<Person>();  //Name="Name" 
      var employee = this.Bind<Employee>(); //Name="Name", should be "empName" 
      return 200; 
     }; 
    } 
} 

public class ReturnModel 
{ 
    public Person PersonModel; 
    public Employee EmployeeModel; 

    public ReturnModel() 
    { 
     PersonModel = new Person(); 
     EmployeeModel = new Employee(); 
     PersonModel.Name = "Name"; 
     EmployeeModel.Name = "empName"; 
    } 
} 

HTML-Ansicht

@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase<NancyTestSite.Modules.ReturnModel> 
<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="utf-8" /> 
</head> 
<body> 
<form method="POST"> 
    <input name="@(Model.EmployeeModel.Name)" type="text" value="@(Model.EmployeeModel.Name)"> 
    <input name="@(Model.PersonModel.Name)" type="text" value="@(Model.PersonModel.Name)"> 
    <button type="submit">Submit</button> 
</form> 

Antwort

2

Nancys ModelBinding funktioniert durch Bindung des ‚name'-Attribut des HTML-Eingang mit dem Namen einer Eigenschaft in dem gegebenen Modell.

Wenn Sie dies tun ...

<input name="@(Model.PersonModel.Name)" type="text" value="@(Model.PersonModel.Name)"> 

... übersetzt die Viewengine es dazu:

<input name="Name" type="text" value="Name"> 

Es tut dies, weil Sie setzen PersonModel.Name auf "Name" in Ihrem ReturnModel Konstruktor und @(Model.PersonModel.Name) erhält einfach den Wert Model.PersonModel.Name. Da Sie EmployeeModel.Name = "empName" der andere Eingang gesetzt würde wie folgt aussehen:

<input name="empName" type="text" value="empName"> 

Also, wenn Sie Ihr Formular-Daten veröffentlichen, gibt es zwei Eingänge, die wie folgt aussehen etwas sollte:

empName = "empName" 
Name = "Name" 

Wenn Sie sind Dann ruft sie this.Bind<Person>() und this.Bind<Employee>, Nancy bemerkt, dass Sie in diesen Klassen eine Eigenschaft namens "Name" haben und versucht daher, eine Eingabe namens "Name" in den Formulardaten zu finden (dies geschieht bei jeder öffentlichen Eigenschaft). Da in Ihren Formulardaten tatsächlich ein Feld "Name" vorhanden ist, legt Nancy die Eigenschaft Name auf den angegebenen Wert fest, sodass Ihre Person und Ihr Mitarbeiter die Name-Eigenschaften auf "Name" festgelegt haben.

Soweit ich weiß, ist es nicht möglich, eine Eingabe an ein bestimmtes Modell (standardmäßig) zu binden. Aber man könnte einfach etwas tun:

<input name="EmployeeName" type="text" value="@(Model.EmployeeModel.Name)"> 
<input name="PersonName" type="text" value="@(Model.PersonModel.Name)"> 

So ist die Formulardaten, die an den Server gesendet wird, enthält etwa so:

EmployeeName = "empName" 
PersonName = "Name" 

schließlich in Ihrem Controller, tun Sie dies:

Post["/"] = parameters => 
    { 
     var person = new Person(); 
     person.Name = this.Request.Form["PersonName"]; 

     var employee = new Employee(); 
     employee.Name = this.Request.Form["EmployeeName"]; 

     return 200; 
    }; 

Ich hoffe, dies hilft zu verstehen, wie Model-Bindung und Viewengine arbeiten.