【发布时间】:2017-05-30 23:15:00
【问题描述】:
我正在构建一个 Web API 并实现了注册和登录。我有一个名为 Task 的模型,如下所示:
public class User_Task
{
[Key]
public long TaskId { get; set; }
public string What { get; set; }
public string How_often { get; set; }
public string How_important { get; set; }
[ForeignKey("FeatureId")]
public long? FeatureId { get; set; }
public virtual ICollection<Step> Steps { get; set; }
public User_Task()
{
}
}
它的存储库:
public class User_TaskRepository : IUser_TaskRepository
{
private readonly WebAPIDataContext _context;
public User_TaskRepository(WebAPIDataContext context)
{
_context = context;
}
public IEnumerable<User_Task> GetAll()
{
return _context.User_Tasks.Include(task => task.Steps).ToList();
}
public void Add(User_Task item)
{
_context.User_Tasks.Add(item);
_context.SaveChanges();
}
public User_Task Find(long key)
{
return _context.User_Tasks.Include(task => task.Steps).FirstOrDefault(t => t.TaskId == key);
}
public void Remove(long key)
{
var entity = _context.User_Tasks.First(t => t.TaskId == key);
_context.User_Tasks.Remove(entity);
_context.SaveChanges();
}
public void Update(User_Task item)
{
_context.User_Tasks.Update(item);
_context.SaveChanges();
}
}
public interface IUser_TaskRepository
{
void Add(User_Task item);
IEnumerable<User_Task> GetAll();
User_Task Find(long key);
void Remove(long key);
void Update(User_Task item);
}
它是控制器:
[Route("api/[controller]")]
public class User_TaskController : Controller
{
private readonly IUser_TaskRepository _taskRepository;
//Controller
public User_TaskController(IUser_TaskRepository taskRepository)
{
_taskRepository = taskRepository;
}
//Get methods
[HttpGet]
public IEnumerable<User_Task> GetAll()
{
return _taskRepository.GetAll();
}
[HttpGet("{id}", Name = "GetTask")]
public IActionResult GetById(long id)
{
var item = _taskRepository.Find(id);
if (item == null)
{
return NotFound();
}
return new ObjectResult(item);
}
//Create
[HttpPost]
public IActionResult Create([FromBody] User_Task item)
{
if (item == null)
{
return BadRequest();
}
_taskRepository.Add(item);
return CreatedAtRoute("GetTask", new { id = item.TaskId }, item);
}
//Update
[HttpPut("{id}")]
public IActionResult Update(long id, [FromBody] User_Task item)
{
if (item == null)
{
return BadRequest();
}
var task = _taskRepository.Find(id);
if (task == null)
{
return NotFound();
}
task.What = item.What;
task.How_often = item.How_often;
task.How_important = item.How_important;
UpdateTaskSteps(item.Steps, task.Steps);
_taskRepository.Update(task);
return new NoContentResult();
}
private void UpdateTaskSteps(ICollection<Step> steps, ICollection<Step> taskSteps)
{
foreach (var step in steps)
{
Step taskStep = taskSteps.FirstOrDefault(x => x.StepId == step.StepId);
if (taskStep != null)
{
// Update
taskStep.What = step.What;
}
else
{
// Create
taskSteps.Add(new Step
{
What = step.What,
TaskId = step.TaskId
});
}
}
}
//Delete
[HttpDelete("{id}")]
public IActionResult Delete(long id)
{
var task = _taskRepository.Find(id);
if (task == null)
{
return NotFound();
}
_taskRepository.Remove(id);
return new NoContentResult();
}
}
现在我有 ApplicationUser 模型如下:
public class ApplicationUser : IdentityUser
{
// Extended Properties
public string FirstName { get; set; }
public string LastName { get; set; }
public ApplicationUser()
{
}
}
还有另一个利益相关者模型:
public class Stakeholder
{
public int Id { get; set; }
public string IdentityId { get; set; }
public ApplicationUser Identity { get; set; } // navigation property
public Stakeholder()
{
}
}
如何确保每个任务都是针对登录用户(即利益相关者)创建的?我将不得不使用利益相关者的外键更新我的任务模型?我该怎么做?如何更新我的控制器方法,以便我可以发回属于发出请求的用户/利益相关者的任务?
更新:startup.cs
public class Startup
{
private const string SecretKey = "iNivDmHLpUA223sqsfhqGbMRdRj1PVkH"; // todo: get this from somewhere secure
private readonly SymmetricSecurityKey _signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(SecretKey));
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, 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)
{
// Add framework services.
services.AddDbContext<WebAPIDataContext>(options =>
{
options.UseMySql(Configuration.GetConnectionString("MysqlConnection"),
b => b.MigrationsAssembly("Vision_backlog_backend"));
});
services.AddSingleton<IJwtFactory, JwtFactory>();
// jwt wire up
// Get options from app settings
var jwtAppSettingOptions = Configuration.GetSection(nameof(JwtIssuerOptions));
// Configure JwtIssuerOptions
services.Configure<JwtIssuerOptions>(options =>
{
options.Issuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)];
options.Audience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)];
options.SigningCredentials = new SigningCredentials(_signingKey, SecurityAlgorithms.HmacSha256);
});
services.AddScoped<IProfileRepository, ProfileRepository>();
services.AddScoped<IUser_TaskRepository, User_TaskRepository>();
services.AddScoped<IFeatureRepository, FeatureRepository>();
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader());
});
// api user claim policy
services.AddAuthorization(options =>
{
options.AddPolicy("ApiUser", policy => policy.RequireClaim(Constants.Strings.JwtClaimIdentifiers.Rol, Constants.Strings.JwtClaims.ApiAccess));
});
services.AddIdentity<ApplicationUser, IdentityRole>
(o =>
{
// configure identity options
o.Password.RequireDigit = false;
o.Password.RequireLowercase = false;
o.Password.RequireUppercase = false;
o.Password.RequireNonAlphanumeric = false;
o.Password.RequiredLength = 6;
})
.AddEntityFrameworkStores<WebAPIDataContext>()
.AddDefaultTokenProviders();
services.AddMvc().AddFluentValidation(fv => fv.RegisterValidatorsFromAssemblyContaining<Startup>());
services.AddAutoMapper();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
});
}
// 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();
// global policy - assign here or on each controller
app.UseCors("CorsPolicy");
var jwtAppSettingOptions = Configuration.GetSection(nameof(JwtIssuerOptions));
var tokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)],
ValidateAudience = true,
ValidAudience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)],
ValidateIssuerSigningKey = true,
IssuerSigningKey = _signingKey,
RequireExpirationTime = false,
ValidateLifetime = false,
ClockSkew = TimeSpan.Zero
};
app.UseJwtBearerAuthentication(new JwtBearerOptions
{
AutomaticAuthenticate = true,
AutomaticChallenge = true,
TokenValidationParameters = tokenValidationParameters
});
app.UseMvc();
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger();
// Enable middleware to serve swagger-ui (HTML, JS, CSS etc.), specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});
}
}
【问题讨论】:
标签: asp.net-core entity-framework-core asp.net-core-webapi asp.net-core-identity