如何在现有ASP.NET MVC项目中实现API控制器?及.NET Core站点Xamarin授权问题
嘿,针对你的两个问题,我来给你详细解答下:
1. 在已有ASP.NET MVC项目中实现API控制器
这里分两种情况,取决于你的项目是基于ASP.NET Framework还是ASP.NET Core:
针对ASP.NET Framework(非Core)的MVC项目
- 先确认项目是否引用了
Microsoft.AspNet.WebApi相关NuGet包,如果没有,先通过NuGet安装。 - 创建继承自
ApiController的控制器,示例代码:
public class ProductsApiController : ApiController { // GET api/products public IEnumerable<string> Get() { return new string[] { "手机", "电脑" }; } // GET api/products/5 public string Get(int id) { return $"编号为{id}的商品"; } }
- 添加Web API路由配置:在
App_Start文件夹新建WebApiConfig.cs:
public static class WebApiConfig { public static void Register(HttpConfiguration config) { // 启用属性路由 config.MapHttpAttributeRoutes(); // 配置默认API路由 config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); } }
- 在
Global.asax.cs的Application_Start方法中注册路由:
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); // 新增这行 FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); }
之后就可以通过/api/ProductsApi这样的路径访问你的API了。
针对ASP.NET Core MVC项目
Core里MVC和Web API已经统一,实现起来更简单:
- 创建继承自
ControllerBase的控制器,加上[ApiController]特性和路由标记:
[ApiController] [Route("api/[controller]")] public class ProductsApiController : ControllerBase { [HttpGet] public IActionResult GetProducts() { return Ok(new string[] { "耳机", "平板" }); } }
Core项目默认已经配置好路由体系,只要控制器带有[ApiController]特性,就能直接通过/api/ProductsApi访问,无需额外配置路由(特殊需求可调整Program.cs中的路由逻辑)。
2. Xamarin应用调用ASP.NET Identity令牌接口的实现与优化
看你已经在Account Controller里写了Token接口的雏形,先补全一个典型的JWT令牌实现(推荐用JWT,比传统Bearer Token更灵活),再讲Xamarin侧的调用方式和注意事项:
补全Token接口的完整实现(ASP.NET Core Identity)
// POST: /Account/Token [HttpPost] [AllowAnonymous] public async Task<IActionResult> Token(LoginViewModel model) { if (!ModelState.IsValid) { return BadRequest(ModelState); } var user = await _userManager.FindByEmailAsync(model.Email); if (user == null) { return Unauthorized("邮箱或密码错误"); } var result = await _signInManager.CheckPasswordSignInAsync(user, model.Password, lockoutOnFailure: false); if (!result.Succeeded) { return Unauthorized("邮箱或密码错误"); } // 构建JWT声明 var claims = new List<Claim> { new Claim(ClaimTypes.NameIdentifier, user.Id), new Claim(ClaimTypes.Email, user.Email), // 可添加自定义声明,比如用户角色 new Claim(ClaimTypes.Role, "User") }; // 从配置文件读取JWT密钥、颁发者、受众(需在appsettings.json中配置) var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:SecretKey"])); var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); // 生成JWT令牌 var token = new JwtSecurityToken( issuer: _configuration["Jwt:Issuer"], audience: _configuration["Jwt:Audience"], claims: claims, expires: DateTime.Now.AddHours(2), signingCredentials: creds ); return Ok(new { AccessToken = new JwtSecurityTokenHandler().WriteToken(token), ExpiresAt = token.ValidTo }); }
Xamarin应用侧的调用示例
用HttpClient发起请求,获取令牌后保存并用于后续接口调用:
// 定义令牌响应模型 public class TokenResponse { public string AccessToken { get; set; } public DateTime ExpiresAt { get; set; } } // 获取令牌的方法 public async Task<string> GetAuthToken(string email, string password) { using (var client = new HttpClient()) { client.BaseAddress = new Uri("https://你的网站域名/"); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); // 构造登录参数 var loginForm = new FormUrlEncodedContent(new[] { new KeyValuePair<string, string>("Email", email), new KeyValuePair<string, string>("Password", password) }); // 发送POST请求 var response = await client.PostAsync("Account/Token", loginForm); if (response.IsSuccessStatusCode) { var tokenResult = await response.Content.ReadFromJsonAsync<TokenResponse>(); // 用Xamarin.Essentials的SecureStorage安全存储令牌,避免明文泄露 await SecureStorage.SetAsync("AuthToken", tokenResult.AccessToken); return tokenResult.AccessToken; } else { var errorMsg = await response.Content.ReadAsStringAsync(); throw new Exception($"登录失败:{errorMsg}"); } } }
关键注意事项
- 强制启用HTTPS:生产环境必须用HTTPS,防止令牌在传输过程中被窃听。
- 令牌安全存储:绝对不要把令牌存在明文文件或SharedPreferences里,用
Xamarin.Essentials.SecureStorage是最佳选择。 - 实现刷新令牌:如果令牌有效期较短,建议添加刷新令牌逻辑,避免用户频繁登录。
- 跨域配置:本地调试时如果Xamarin应用和Web站点存在跨域问题,需要在Web项目中配置CORS:
// 在Program.cs中添加CORS配置 builder.Services.AddCors(options => { options.AddPolicy("AllowXamarin", policy => policy.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader()); }); // 启用CORS中间件 app.UseCors("AllowXamarin");
内容的提问来源于stack exchange,提问作者WhatTheDeuce
相关产品推荐
相关产品推荐

