Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Proposal] Tupled model #13315

Closed
VBAndCs opened this issue Aug 21, 2019 · 3 comments
Closed

[Proposal] Tupled model #13315

VBAndCs opened this issue Aug 21, 2019 · 3 comments
Labels
area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates

Comments

@VBAndCs
Copy link

VBAndCs commented Aug 21, 2019

We add many trivial classes corresponding to each view, like this one needed for login view:

public class LoginModel {
    [Required] [UIHint("email")]
    public string Email { get; set; }

    [Required] [UIHint("password")]
    public string Password { get; set; }
}

It will be better if we can express it as a record like this:

public class LoginModel (
    [Required] [UIHint("email")] string Email,
    [Required] [UIHint("password")] string Password 
)

But this needs to allow mutable records, which I wish to reconsider!

This can be more better, if it can be expressed inline as a tuple-like record, to be used directly in the view:

@model ([Required] [UIHint("email")] string Email,
    [Required] [UIHint("password")] string Password)

And in the post method, dependency injection can resolve the arguments from the tupled model object:

[HttpPost]
public IActionResult Login(string Email,
    string Password)

If this is not easy for some reason, we can mark the action method with [Tupled] attribute to direct the view to inspect the view for the record properties.

this can be called tupled model or anonymous model, and Razor should generate it as a full class:

public class SomeCompilerName {
    [Required] [UIHint("email")]
    public string string Email { get; set; }

    [Required] [UIHint("password")]
    public string Password { get; set; }
}

and the view will be compiled to:

@model SomeCompilerName

Another approach is just to use tuples:

@model (string Email, string Password)

But we need tag helpers to apply the effect of the [Required] and [UIHint("email")] directly on the html input elements used for email and password, which can be easier with some tag helpers, say asp-required and asp-hint.
In this case, we just define the same tuple as a parameter for the action method:

[HttpPost]
public IActionResult Login((string Email, string Password) data)
@pranavkm pranavkm added the area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates label Aug 21, 2019
@davidfowl
Copy link
Member

This should be part of the records discussion happening in c# 9

@VBAndCs
Copy link
Author

VBAndCs commented Aug 21, 2019

@davidfowl
I don't think so, for three reasons:

  1. Records are immutable.
  2. Razor has its own syntax and compiler and generates C# classes at runtime, so it can do it independent of the programming language.
  3. ASP.Net Core uses attributes intensively, which is not the case of general C# code, so attributed records don't have w wide demand in C#.
    Thanks

@danroth27
Copy link
Member

danroth27 commented Aug 21, 2019

@VBAndCs Razor & MVC is based on C#. We don't independently design language extensions to C# that are specific to Razor. The right place to discuss this is with the C# folks.

@ghost ghost locked as resolved and limited conversation to collaborators Dec 2, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates
Projects
None yet
Development

No branches or pull requests

4 participants