Webpack Angular2不会从http Post

时间:2017-01-31 02:30:28

标签: angularjs webpack

我正在尝试使用webpack使用http Post验证用户登录。我能够传递用户信息并再次验证用户db表。服务器代码工作正常。但是,我偶然发现将响应(一个对象)从服务器传递回客户端。类似的代码在DotNet Core中使用Angular2 SPA(从chsakell Cross-platform SPA中提取和修改代码,使用ASP.NET核心1.0,Angular 2和TypeScript)。但它在webpack中使用Angular2的DotNet Core失败了。我希望有人可以帮助确定问题所在。

System.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.SpaServices.Webpack;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers;
using UCHICUDRS.Formatters;
using System.Security.Claims;
using UCHICUDRS.Models;
using UCHICUDRS.Infrastructure.Repositories;
using UCHICUDRS.Infrastructure.Services;
using Newtonsoft.Json.Serialization;
using UCHICUDRS.Infrastructure.Mappings;

namespace UCHICUDRS
{
    public class Startup
    {
        private static string _applicationPath = string.Empty;
        private static string _contentRootPath = string.Empty;

        public Startup(IHostingEnvironment env)
        {
            _applicationPath = env.WebRootPath;
            _contentRootPath = env.ContentRootPath;

            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                .AddEnvironmentVariables();
            Configuration = builder.Build();
        }

        public IConfigurationRoot Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<UCHICUDRSContext>(options =>
               options.UseSqlServer(Configuration["Data:UCHICUDRSConnection:ConnectionString"]));

            // Repositories                services.AddScoped<ILogRepository, LogRepository>();
            services.AddScoped<IRoleRepository, RoleRepository>();                services.AddScoped<IUserRepository, UserRepository>();
            services.AddScoped<IUserRequestRepository, UserRequestRepository>();
            services.AddScoped<IUserGroupRepository, UserGroupRepository>();
            services.AddScoped<IUserRoleRepository, UserRoleRepository>();

            // Services
            services.AddScoped<IMembershipService, MembershipService>();
            services.AddScoped<IEncryptionService, EncryptionService>();

            services.AddAuthentication();

            // Polices
            services.AddAuthorization(options =>
            {
                // inline policies
                options.AddPolicy("Administrator", policy =>
                {
                    policy.RequireClaim(ClaimTypes.Role, "Administrator");
                });

                options.AddPolicy("Manager", policy =>
                {
                    policy.RequireClaim(ClaimTypes.Role, "Manager");
                });

                options.AddPolicy("User", policy =>
                {
                    policy.RequireClaim(ClaimTypes.Role, "User");
                });

                options.AddPolicy("No Access", policy =>
                {
                    policy.RequireClaim(ClaimTypes.Role, " No Access");
                });
            });
/*
            // Add MVC services to the services container
            // Causing http header error
            services.AddMvc()
            .AddJsonOptions(opt =>
            {
                var resolver = opt.SerializerSettings.ContractResolver;
                if (resolver != null)
                {
                    var res = resolver as DefaultContractResolver;
                    res.NamingStrategy = null;
                }
            });
*/
            // Add framework services. 
            services.AddMvc();
            services.AddMvc(options =>
            {
                // The custom formatters need to be added to the MVC middleware, so that it knows how to handle media types 'text/csv'. 
                options.InputFormatters.Add(new CsvInputFormatter());
                options.OutputFormatters.Add(new CsvOutputFormatter());
                options.FormatterMappings.SetMediaTypeMappingForFormat("csv", MediaTypeHeaderValue.Parse("text/csv"));
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions {
                    HotModuleReplacement = true
                });
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            AutoMapperConfiguration.Configure();

            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AutomaticAuthenticate = true,
                AutomaticChallenge = true
            });

            app.UseStaticFiles();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");

                routes.MapSpaFallbackRoute(
                    name: "spa-fallback",
                    defaults: new { controller = "Home", action = "Index" });
            });
        }
    }
}


operationResult.ts

export class OperationResult {
    Succeeded: boolean;
    Message: string;
    RetData: any;
 
    constructor(succeeded: boolean, message: string, retData: any) {
        this.Succeeded = succeeded;
        this.Message = message;
        this.RetData = retData;
    }
}


    login.component.ts
    import { Component, OnInit } from '@angular/core';
    import { ViewChild } from '@angular/core';    // for showModelMsg
    import { Router, ActivatedRoute, RouterLink } from '@angular/router';
    // import {FORM_DIRECTIVES, REACTIVE_FORM_DIRECTIVES} from '@angular/forms';
    import {FormBuilder, FormGroup, Validators} from '@angular/forms';

    import { Login } from '../../../core/models/login';
    import { User } from '../../../core/models/user';
    import { Role } from '../../../core/models/role';
    import { OperationResult } from '../../../core/models/operationResult';
    import { MembershipService } from '../../../core/services/membership.service';
     
    @Component({
        selector: 'login',
        providers: [MembershipService, NotificationService],
        template: require('./login.component.html'),
        styles: [require('./account.component.css')]
    })
    export class LoginComponent implements OnInit {
        private _user: Login = new Login('', '', false);

        private notificationService: NotificationService;  // alertify is no longer be supported so when it put inside the constructor, the html won't display
        // private router: Router;
        private route: ActivatedRoute;

        constructor(private membershipService: MembershipService, private router: Router) { }

        ngOnInit() {
            this._user.Username = '';
            this._user.Password = '';
            this._user.RememberMe = false;
        }

        login(): void {
            var _authenticationResult: OperationResult = new OperationResult(false, '', null);
            var _creds: User;
            this.membershipService.login(this._user)
                .subscribe(res => {  
                    _authenticationResult.Succeeded = res.Succeeded;
                    _authenticationResult.Message = res.Message;
                    _authenticationResult.RetData = res.RetData;
                    _creds = _authenticationResult.RetData;
                },
                error => console.error('Error: ' + error),  // error from http call
                () => {  
                    if (_authenticationResult.Succeeded) {
                        this.notificationService.printSuccessMessage('Welcome back ' + this._user.Username + '!');
                        localStorage.setItem('user', JSON.stringify(_creds));
                        this.router.navigate(['home']);
                    }
                    else {
                        this.showModelMsg("Login Failed", _authenticationResult.Message);
                    }
                });
        };
    }


    membership.service.ts
    import { Http, Response, Request } from '@angular/http';
    import { Injectable } from '@angular/core';
    import { DataService } from './data.service';
    import { Login } from '../models/login';
    import { Registration } from '../models/registration';
    import { Role } from '../models/role';
    import { User } from '../models/user';
    import { Observable } from "rxjs/Observable";
     
    @Injectable()
    export class MembershipService {
        private _accountLoginAPI: string = 'api/account/authenticate/';
        private _res: Observable<any>;
        public redirectUrl: string;   // store the URL so we can redirect after loggin in

        constructor(public accountService: DataService) { }
     
     
        login(creds: Login) {
            this.accountService.set(this._accountLoginAPI);
            return this.accountService.post(JSON.stringify(creds));
        }
    }


    data.service.ts
    import { Http, Response } from '@angular/http';
    import { Headers, RequestOptions } from '@angular/http';
    import { Injectable } from '@angular/core';
    // import { Observable } from 'rxjs/Observable';
    import 'rxjs/add/operator/catch';
    import { Observable } from 'rxjs/Rx';
    import { OperationResult } from '../models/operationResult';
     
    @Injectable()
    export class DataService {
     
        public _pageSize: number;
        public _baseUri: string;
        public _headers: Headers;
        public _options: RequestOptions;
     
        constructor(public http: Http) {
            this.init();
        }

        init() {
            this._headers = new Headers({ 'content-type': 'application/json' });
            this._options = new RequestOptions({ headers: this._headers });
        }
     
        post(data?: any, mapJson: boolean = true) {
            var _authenticationResult: OperationResult = new OperationResult(false, '', null);
            if (mapJson)  {
                var res = this.http.post(this._baseUri, data, this._options)
                                    .map(response => <any>(<Response>response).json());
                return res;
            }
            else
                return this.http.post(this._baseUri, data, this._options)
                    .map(response => response.json())
                    .catch(this.handleError);
        }
    }


AccountController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using UCHICUDRS.Models;
using UCHICUDRS.ViewModels;
using UCHICUDRS.Infrastructure.Repositories;
using UCHICUDRS.Infrastructure.Services;
using UCHICUDRS.Infrastructure.Core;
using System.Security.Claims;
using Microsoft.AspNetCore.Authentication.Cookies;
using AutoMapper;


namespace UCHICUDRS.Controllers
{   // https://chsakell.com/2016/01/01/cross-platform-single-page-applications-with-asp-net-5-angular-2-typescript/
    [Route("api/[controller]")]
    public class AccountController : Controller
    {
        private readonly IMembershipService _membershipService;
        private readonly IUserRepository _userRepository;
        private readonly IRoleRepository _roleRepository;
        private readonly ILogRepository _loggingRepository;

        public AccountController(IMembershipService membershipService,
            IUserRepository userRepository,
            IRoleRepository roleRepository,
            ILogRepository _errorRepository)
        {
            _membershipService = membershipService;
            _userRepository = userRepository;
            _roleRepository = roleRepository;
            _loggingRepository = _errorRepository;
        }

        [HttpPost("authenticate")]
        public async Task<IActionResult> Login([FromBody] Login user)
        {
            IActionResult _result = new ObjectResult(false);
            GenericResult _authenticationResult = null;
            Console.WriteLine("123");
            try
            {
                MembershipContext _userContext = _membershipService.ValidateUser(user.Username, user.Password);

                if (_userContext.User != null)
                {
                    IEnumerable<Role> _roles = _userRepository.GetRoles(user.Username);
                    List<Claim> _claims = new List<Claim>();
                    foreach (Role role in _roles)
                    {
                        Claim _claim = new Claim(ClaimTypes.Role, role.Name, ClaimValueTypes.String, user.Username);
                        _claims.Add(_claim);
                    }
                    await HttpContext.Authentication.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
                        new ClaimsPrincipal(new ClaimsIdentity(_claims, CookieAuthenticationDefaults.AuthenticationScheme)),
                        new Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties { IsPersistent = user.RememberMe });

                    _authenticationResult = new GenericResult()
                    {
                        Succeeded = true,
                        Message = "Authentication succeeded",
                        RetData = _userContext.User
                    };
                }
                else
                {
                    _authenticationResult = new GenericResult()
                    {
                        Succeeded = false,
                        Message = "Username and Password don't match. Authentication failed.",
                        RetData = null
                    };
                }
            }
            catch (Exception ex)
            {
                _authenticationResult = new GenericResult()
                {
                    Succeeded = false,
                    Message = ex.Message,
                    RetData = null
                };

                _loggingRepository.Add(new Log() { Message = ex.Message, StackTrace = ex.StackTrace, RecIn = DateTime.Now });
                _loggingRepository.Commit();
            }

            _result = new ObjectResult(_authenticationResult);
            return _result;
        }
}


GenericResult.cs
namespace UCHICUDRS.Infrastructure.Core
{
    public class GenericResult
    {
        public bool Succeeded { get; set; }
        public string Message { get; set; }
        public object RetData { get; set; }
    }
}

1 个答案:

答案 0 :(得分:0)

取消注释system.cs中的以下代码

        system.cs
            services.AddMvc()
        .AddJsonOptions(opt =>
        {
            var resolver = opt.SerializerSettings.ContractResolver;
            if (resolver != null)
            {
                var res = resolver as DefaultContractResolver;
                res.NamingStrategy = null;
            }
        });

我对它进行了评论,因为它导致http调用失败。然后我手动将http标头添加到http以使其工作。当我取消注释上述代码时,http post响应将数据传输回客户端。即使代码现在有用,但我也不知道原因。