You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在现有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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:36:16