MVCは、より低レイヤーに送信する前に、強くタイプのビュー、およびサーバー側の設定プロパティですか?
-
29-10-2019 - |
質問
ビジネスレイヤーにコマンドを送信するレイヤードアプリケーションがあります(実際、アプリケーションはに基づいています NCQRSフレームワーク, 、しかし、私はそれがここで重要だとは思わない)。
コマンドは次のようになります:
public class RegisterUserCommand : CommandBase
{
public string UserName { get; set; }
public string Email{ get; set; }
public DateTime RegistrationDate { get; set; }
public string ApiKey {get; set;} // edit
}
このクラスにはロジックはなく、データのみがデータのみです。
ユーザーにユーザー名、電子メールを入力してもらいたいので、システムに現在の日付を使用してコマンドを作成したいと考えています。
間に最適なもの:
RegisterUserCommandに基づいて強くタイプされたビューを作成し、ビジネスレイヤーに送信する直前に日付とAPIキーを挿入しますか?
RegisterUserViewModelクラスを作成し、このクラスでビューを作成し、ビュー入力に基づいてコマンドオブジェクトを作成しますか?
次のコードを書きました(ソリューションn°2用):
public class RegisterController : Controller
{
//
// GET: /Register/
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(RegisterUserViewModel registrationData)
{
var service = NcqrsEnvironment.Get<ICommandService>();
service.Execute(
new RegisterUserCommand
{
RegistrationDate = DateTime.UtcNow,
Email= registrationData.Email,
UserName= registrationData.Name,
ApiKey = "KeyFromConfigSpecificToCaller" // edit
}
);
return View();
}
public class RegisterUserViewModel
{
[Required]
[StringLength(16)]
public string Name { get; set; }
[Required]
[StringLength(64)]
public string Email{ get; set; }
}
}
このコードは機能しています...しかし、私は正しい方法を選んだのだろうか...
アドバイスをありがとう
編集 DateTimeが誤解を引き起こすように見えるので、私は別のプロパティ「Apikey」を追加しました。これは、Webレイヤーからサーバー側にも設定されるはずです(コマンドレイヤーからではありません)
編集2 Erikの提案を試して、私が想像した最初の解決策を実装してください:
[HttpPost]
public ActionResult Index(RegisterUserCommand registrationCommand)
{
var service = NcqrsEnvironment.Get<ICommandService>();
registrationCommand.RegistrationDate = DateTime.UtcNow;
registrationCommand.ApiKey = "KeyFromConfigSpecificToCaller";
service.Execute(
registrationCommand
);
return View();
}
...それは受け入れられますか?
解決
Option#2を使用すると、別のViewModelとコマンドがあります。それは(ある程度)冗長に見えるかもしれませんが、あなたのコマンドはあなたのWebサーバーからコマンドハンドラーへの本当にメッセージです。これらのメッセージは、ViewModelと同じようにフォーマットされていない場合もありません。また、NCQRSを使用している場合は、コマンドをARメソッドとコンストラクターにマッピングする必要があります。
それはあなたに少し時間を節約するかもしれませんが、あなたはあなたのビューモデルの後にあなたのドメインをモデル化するためにあなた自身を鳩の穴に穴を開けていると思います、そしてそれはそうではないはずです。あなたのViewModelsは、ユーザーが経験していることを反映している必要があります。あなたのドメインはあなたのビジネスのルールと知識を反映しているべきであり、あなたの見解に常に反映されているとは限りません。
今はもう少し作業のように思えるかもしれませんが、自分自身に好意を与え、ビューモデルとは別にコマンドを維持してください。後で感謝します。
これが役立つことを願っています。幸運を!
他のヒント
これをRegisterUserCommandクラスのコンストラクターに入れることをお勧めします。そうすれば、デフォルトの動作は常にそれをdateTime.utcnowに設定することです。明示的に何かに設定する必要がある場合は、Object initializerに追加することができます。これは、プロジェクトの他の部分でこのクラスを使用しているシナリオでも役立ち、登録日を明示的に設定することを忘れます。
public class RegisterUserCommand : CommandBase
{
public string UserName { get; set; }
public string Email{ get; set; }
public DateTime RegistrationDate { get; set; }
public RegisterUserCommand()
{
RegistrationDate = DateTime.UtcNow;
}
}
およびコントローラー
public class RegisterController : Controller
{
//
// GET: /Register/
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(RegisterUserViewModel registrationData)
{
var service = NcqrsEnvironment.Get<ICommandService>();
service.Execute(
new RegisterUserCommand
{
Email= registrationData.Email,
OpenIdIdentifier = registrationData.OpenIdIdentifier
}
);
return View();
}
public class RegisterUserViewModel
{
[Required]
[StringLength(16)]
public string Name { get; set; }
[Required]
[StringLength(64)]
public string Email{ get; set; }
}
}
ナンバー1を使用して使用します System.comPonentModel.DataAnnotations.Metadatatype 検証用。
別の質問のために例(答え)を作成しました ここ.
これにより、モデルを別のライブラリに維持し、フィールドを検証し、Data Annotationを使用して内部/プライベートクラスのようなフィールドを表示できます。私は、データを別のクラスに戻す必要がある間、付加価値のないビューのために完全に独立したクラスを作成することの大ファンではありません。 (ドロップダウンリスト値、またはデフォルト値などの追加値がある場合は、理にかなっていると思います)。
それ以外の
[HttpPost]
public ActionResult Index(RegisterUserViewModel registrationData)
{
var service = NcqrsEnvironment.Get<ICommandService>();
service.Execute(
new RegisterUserCommand
{
RegistrationDate = DateTime.UtcNow,
Email= registrationData.Email,
UserName= registrationData.Name,
ApiKey = "KeyFromConfigSpecificToCaller" // edit
}
);
return View();
}
あなたが持つことができます
[HttpPost]
public ActionResult Index(RegisterUserCommand registrationData)
{
var service = NcqrsEnvironment.Get<ICommandService>();
registrationData.ApiKey = "KeyFromConfigSpecificToCaller";
service.Execute(registrationData);
return View();
}