0% found this document useful (0 votes)
0 views

07. CSharp ASP NET Core Working With Data

Uploaded by

hungntgch220055
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
0 views

07. CSharp ASP NET Core Working With Data

Uploaded by

hungntgch220055
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 24

Working with Data

Model Binding, Data Validation and Files in ASP.NET Core


Table of Contents

 Model Binding
– Custom Model Binding
 Model Validation
– Custom Model Validation
 Working with Files
– Upload and Download Files

2
MODEL BINDING

3
Model Binding

• Model binding in ASP.NET Core MVC maps data from HTTP requests to
action method parameters.
– The parameters may be primitive types or complex types
– Implemented abstractly, paving the way for reusability in different apps
• The framework binds request data to action parameters by name
– The value of each parameter will be searched, using the parameter name
– Classes are mapped using the names of the public settable properties

Request URL PostsController

https://mysite.com/posts/edit/6 public IActionResult Edit(int? id)


Model Binding

• Model binding can look through several data sources per Request
– Form values – POST Request parameters
– Route values – The set of Route values provided by the Routing
– Query strings – The query string parameters in the URL
– Even in headers, cookies, session, etc. in custom model binders
– Data from these sources are stored as name-value pairs
• The framework checks each of the data sources for a parameter value
– If there is no parameter in the data source, the next in order is checked
– The data sources are checked in the order specified above

5
Incoming Request to MVC

Populate Instance Created


Model State by Model Binder

Model public MyController : Controller


Validation {
Binder IActionResult Index(MyInputModel
input)
{
if (ModelState.IsValid)
{
return View();
}
MyInputModel }
instance }

6
Model Binding

• If binding fails, the framework does not throw an error


– Every action, accepting user input, should check if binding was successful
– This is done through the ModelState.IsValid property
• Each entry in the controller's ModelState property is a ModelStateEntry
– Each ModelStateEntry contains an Errors property
– It's rarely necessary to query this collection, though
• Default Model binding works great for most development scenarios
– It is also extensible, and you can customize the built-in behavior

7
Model Binding

• You can easily iterate over the errors in the ModelState


public class UsersController : Controller
{
public IActionResult Register(RegisterUserBindingModel model)
{
if(!ModelState.IsValid)
{
foreach (var error in ModelState.Values.SelectMany(v =>
v.Errors))
{
DoSomething(error);
}

// TODO: Return Error Page


}

return Ok("Success!");
}
}

8
Model Binding

• Built-in Model binding behavior can be directed to a different source


– The framework provides several attributes for that
Attribute Description

[BindRequired] Adds a model state error if binding cannot occur.

[BindNever] Thells the model binder to never bind this parameter.

[From{source}] Used to specify the exact binding source. [FromHeader], [FromQuery], [FromRoute],
[FromForm]
[FromServices] Uses dependency injection to bind parameters from services.
[FromBody] Use configure formatters to bind data from request body. Formatter is selected based
on Content-Type of Request.
[ModelBinder] Used to override the default model binder, binding source and name.

9
Custom Model Binder

• Custom Model Binding can be completely customized


– You need to create a BindingProvider and a Binder

[ModelBinder(BinderType = public class StudentEntityBinder :


typeof(StudentEntityBinder))] IModelBinder
public class Student {
{ public Task BindModelAsync
public int Id { get; set; } (ModelBindingContext bindingContext)
public string Name { get; set; } {
public int Age { get; set; } //TODO: Do Magic ...
}
bindingContext.Result
=
ModelBindingResult.Success(model);
return Task.CompletedTask;
}
}

10
Custom Model Binder

public class StudentEntityBinderProvider : IModelBinderProvider


{
public IModelBinder GetBinder(ModelBinderProviderContext context)
{
if(context == null) throw new
ArgumentNullException(nameof(context));
if(context.Metadata.ModelType == typeof(Student))
return new
BinderTypeModelBinder(typeof(StudentEntityBinder));

return null;
}
}
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(options =>
{
options.ModelBinderProviders
.Insert(0, new StudentEntityBinderProvider()); // Add custom binder to
beginning

});
} 11
MODEL VALIDATION

Once Model binding is complete, Validation occurs

12
Model Validation

• Validation is absolutely necessary before persisting data


– The may be potential security threats
– There may be malformed data (type, size, data constraints)
• In ASP.NET Core MVC, validation happens both on client and server
Model Validation

• .NET provides us an abstracted validation through attributes


– Some attributes configure model validation by constraint
• Similar to validation on database fields
– Other apply patterns to data to enforce business rules
• Credit Cards, Phone Numbers, Email Addresses etc.
• Validation attributes make enforcing these requirements simple
– They are specified at the property or parameter level

14
Model Validation

• Some of the most popular built-in validation attributes are:


Attribute Description

[CreditCard] Validates the property has a credit card format

[Compare] Validates 2 properties in a model match. (Useful for password confirmation)

[EmailAddress] Validates the property has an email format.

[Phone] Validates the property has a telephone format.


[Range] Validates the property value falls within the given range.

[RegularExpression] Validates the data matches the specified regular expression.

[Required] Makes the property required. Value cannot be null.

[StringLength] Validates that a string property has at most the given maximum length.

[Url] Validates the property has a URL format.

15
Custom Model Validation

• Validation attributes work for most needs, but not for all
– Sometimes you need to implement your own validation attributes
public class IsBefore : ValidationAttribute
{
private const string DateTimeFormat = "dd/MM/yyyy";
private readonly DateTime date;

public IsBefore(string dateInput)


{
this.date = DateTime.ParseExact(dateInput, DateTimeFormat,
CultureInfo.InvariantCulture);
}

protected override ValidationResult IsValid(object value, ValidationContext


validationContext)
{
if ((DateTime)value >= this.date) return new ValidationResult(this.ErrorMessage);
return ValidationResult.Success;
}
16
}
Custom Model Validation

• Then you can use it in your model


public class RegisterUserModel
{
[Required]
public string Username { get; set; }

[Required]
[StringLength(20)]
public string Password { get; set; }

[Required
public string FirstName { get;
set; }

[Required
public string LastName { get; set; }

[IsBefore("01/01/2000")]
public DateTime BirthDate { get;
set; }
17
}
Custom Model Validation

• You can also use validation directly in the Binding Model


– This is done by using the IValidatableObject interface
public class RegisterUserModel : IValidatableObject
{
public string Username { get; set; }
public string Password { get; set; }
public string ConfirmPassword { get; set; }

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)


{
if(string.IsNullOrEmpty(Username)) yield return new ValidationResult("Username cannot be
empty");
if(string.IsNullOrEmpty(Password)) yield return new ValidationResult("Password cannot be
empty");
if(ConfirmPassword != Password) yield return new ValidationResult("Passwords do not
match");
}
}
18
Incoming Request to MVC

Can you create a Model Binder IActionResult Index(MyInputModel input) {


for MyInputModel? Validation return View();
}

ModelBinderProvider 1

Sorry, can't create a Model Binder for that


Value Providers
Default
Route URL Query FormData

ModelBinderProvider 2 Model Binder


Yes, I can, here you go Input Formatters
Will never be checked [FormBody]
JSON XML
(if applicable)
ModelBinderProvider 3

19
FILES

Uploading and Downloading files

20
Uploading Files

• ASP.NET Core MVC supports File Upload using simple model binding
– For larger files, Streaming is used
<form method="post" enctype="multipart/form-data"
asp-controller="Files" asp-
action="Upload">
<input type="file" name="file">
<button type="submit" value="Upload" />
</form>

– Multiple-file upload is also supported

<form method="post" enctype="multipart/form-data"


asp-controller="Files" asp-
action="Upload">
<input type="file" name="files" multiple >
<button type="submit" value="Upload" />
</form>
21
Uploading Files

• When uploading files using model binding, your action should accept:
– IFormFile (for single file) or IEnumerable<IFormFile> (or List<IFormFile>)
[HttpPost("Upload")]
public async Task<IActionResult> Upload(List<IFormFile> files)
{
var filePath = Path.GetTempFileName(); // Full path to file in temp
location

foreach (var formFile in files.Where(f => f.Length > 0))


{
using (var stream = new FileStream(filePath, FileMode.Create))
{
await formFile.CopyToAsync(stream);
}
} // Copy files to FileSystem using Streams

return Ok(new { count = files.Count, files.Sum(f => f.Length),


filePath});
22
}
Downloading Files

• ASP.NET Core abstracts file system access through File Providers


– File Providers are used throughout the ASP.NET Core framework
• Examples of where ASP.NET Core uses File Providers internally
– IHostingEnvironment exposes the app’s content root and web root
– Static File Middleware uses File Providers to locate static files
– Razor uses File Providers to locate pages and views

23
Downloading Files

• To access physical files, you have to use PhysicalFileProvider


– You’ll have to initialize it with your server physical files folder path
– Then you can extract information about the File

public IActionResult Download(string fileName)


{
// Construct the path to the physical files folder
string filePath = this.env.ContentRootPath +
this.config["FileSystem:FilesFolderPath"];

IFileProvider provider = new PhysicalFileProvider(filePath); // Initialize the


Provider
IFileInfo fileInfo = provider.GetFileInfo(fileName); // Extract the FileInfo

var readStream = fileInfo.CreateReadStream(); // Extact the Stream


var mimeType = "application/octet-stream"; // Set a mimeType

return File(readStream, mimeType, fileName); // Return FileResult


24
} // NOTE: There is no check if the File exists. This action may result in an error

You might also like