Reputation: 33
I have a controller that has a Create
action. Its purpose is to receive a name and data from file form, and IndexViewModel
return IEnumerable<File>
files.
public class HomeController : Controller
{
static List<Models.File> files = new List<Models.File>();
public HomeController() { }
[HttpGet]
public IActionResult Index() => View(new IndexViewModel { Files = files });
[HttpGet]
public IActionResult Create() => View();
[HttpPost]
public IActionResult Create(IFormFile file)
{
var filename =
ContentDispositionHeaderValue.Parse(file.ContentDisposition)
.FileName;
using (var reader = new StreamReader(file.OpenReadStream()))
{
var content = reader.ReadToEnd();
files.Add(new Models.File { Name = filename, Data = content });
}
return RedirectToAction(nameof(Index));
}
}
When I use a form in static html, it's alright, the server receives the data. But when I use the same form in an Angular2 template it doesn't.
import {Component} from 'angular2/core';
import {File} from './file';
@Component({
selector: 'listfile',
template: `
<form method="post" asp-action="Index" asp-controller="Api/File" enctype="multipart/form-data">
<input type="file" name="files" #newFile (keyup.enter)="addFile(newFile.value)"
(blur)="addFile(newFile.value); newFile.value='' ">
<input type="submit" value="Upload" />
</form>
<table class="table">
<th>id</th><th>name</th>
<tr *ngFor="#file of files">
<td>{{file.id}}</td>
<td>{{file.name}}</td>
</tr>
</table>
`
})
export class ListFileComponent {
files = [
new File(1, 'file1'),
new File(2, 'file2')
];
addFile(newFile: string) {
if (newFile) {
this.files.push(new File(this.files.length + 1, newFile.split(/(\\|\/)/g).pop()))
}
}
falert(value) {
alert(value);
}
}
Upvotes: 3
Views: 4200
Reputation: 24535
You have a misconception of the Angular2 templating and the MVC pre-processing. Here is a post that might clear that up. You have ASP.NET tag helpers that will not be rendered on the server, and instead will be sent to the client as is.
You are using the form post which passes form data, instead you should be using the Web API with Angular2's Http service.
You have many options, but two of them are the most practical at this point:
templateUrl
instead of the template
and point to the /controller/action
that would pre-process the tag helpers and return the HTML as desired (this would then serve as an Angular2 template./home/index
. Then you use the templateUrl
to point to local .html
files that serve as the template. And build out an API that will support all the interactions you need.I hope this clears things up!
.html
you'll need to remove the ASP.NET tag helpers.
@Component({
selector: 'listfile',
template: `
<form (submit)="" >
<input type="file" name="files" #newFile (keyup.enter)="addFile(newFile.value)"
(blur)="addFile(newFile.value); newFile.value='' ">
<input type="submit" value="Upload" />
</form>
<table class="table">
<th>id</th><th>name</th>
<tr *ngFor="#file of files">
<td>{{file.id}}</td>
<td>{{file.name}}</td>
</tr>
</table>
`
})
export class ListFileComponent {
// ...
constructor(private http: Http) { }
onSubmit() {
const body = JSON.stringify({ this.files });
this.http
.post('api/file/create',
body,
{ headers: new Headers({ "Content-Type": "application/json" }) })
.map(response => response.json())
.subscribe(json => { /* handle it */ });
}
}
Then you'd have to change your API signature to more accurately accept the data.
Upvotes: 4