Angular - چگونه با Angular2 دادهها را به یک Controller در ASP.NET ارسال کنیم


من یک کنترلر دارم که یک اکشن Create دارد. هدف آن دریافت نام و دادهها از فرم فایل است و IndexViewModel فایلهای IEnumerable<File> را بازمیگرداند.

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));
    }
}

وقتی از یک فرم در HTML استاتیک استفاده میکنم، مشکلی نیست و سرور دادهها را دریافت میکند. اما وقتی از همان فرم در یک قالب Angular2 استفاده میکنم، این اتفاق نمیافتد.

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);
    }
}

پاسخ شماره ۱

شما درک نادرستی از قالببندی Angular2 و پیشپردازش MVC دارید. این یک پست است که ممکن است آن را روشن کند. شما ASP.NET تگهای کمکی دارید که در سرور رندر نخواهند شد و در عوض به صورت همانگونه به کلاینت ارسال خواهند شد.

شما از فرم post استفاده میکنید که دادههای فرم را منتقل میکند، به جای آن باید از Web API با سرویس Http در Angular2 استفاده کنید.

شما گزینههای زیادی دارید، اما دو مورد از آنها در این مرحله عملیتر هستند:

  1. شما میتوانید انتخاب کنید که از قدرت MVC برای پیشپردازش آن استفاده کنید و یک نما جزئی فرم را بازگرداند. در کامپوننت خود از templateUrl به جای template استفاده میکنید و به /controller/action اشاره میکنید که تگهلپرها را پیشپردازش کرده و HTML مورد نظر را بازگرداند (این سپس به عنوان یک قالب Angular2 استفاده خواهد شد).
  2. شما میتوانید شروع به استفاده از Angular2 به عنوان یک SPA واقعی کنید، و فقط از MVC برای ارائه یک صفحه واحد استفاده کنید... /home/index. سپس از templateUrl برای اشاره به فایلهای .html محلی که به عنوان قالب عمل میکنند استفاده میکنید. و یک API بسازید که تمام تعاملات مورد نیاز شما را پشتیبانی کند.

امیدوارم این مسئله را روشن کند!


اگر قصد دارید از .html داخلی یا ایستا استفاده کنید، باید ASP.NET تگهلپرها را حذف کنید.

@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 */ });
    }
}

سپس باید امضای API خود را تغییر دهید تا دادهها را با دقت بیشتری بپذیرد.