这是我的代码,如有需要,请随意更正
public class Employee
{
public int EmployeeId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string ImagePath { get; set; }
public string Address { get; set; }
public int DeptId { get; set; }
public Dept Dept { get; set; }
}
我的种子数据
context.Employees.AddOrUpdate(x => x.EmployeeId,
new Employee()
{
EmployeeId = 1,
LastName = "Carson",
FirstName = "Alexander",
ImagePath = "images/CarsonAlex.png",
Address = "Brazil",
DeptId = 2
},
new Employee()
{
EmployeeId = 2,
LastName = "Arturo",
FirstName = "Olivetto",
ImagePath = "images/ArturoOliva.png",
Address = "Brazil",
DeptId = 1
},
new Employee()
{
EmployeeId = 3,
LastName = "Alonso",
FirstName = "Meredith",
ImagePath = "images/MeredithAlonso.png",
Address = "Brazil",
DeptId = 3
}
);
我的 View 模型类
public class EmployeeDetailVm
{
public int EmployeeId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string ImagePath { get; set; }
public string Address { get; set; }
public int DeptId { get; set; }
public string DeptName { get; set; }
}
岗位员工api Controller
[ResponseType(typeof(EmployeeDetailVm))]
public IHttpActionResult PostEmployee(EmployeeDetailVm employees)
{
var employee = new Employee
{
EmployeeId = employees.EmployeeId,
LastName = employees.LastName,
FirstName = employees.FirstName,
ImagePath = employees.ImagePath,
Address = employees.Address,
DeptId = employees.DeptId
};
if (employees != null)
{
// Extract the image from the image string
string regEx = "data:(.+);base64,(.+)";
Match match = Regex.Match(employees.ImagePath, regEx);
if (match.Success)
{
// Get the content-type of the file and the content
string imageType = match.Groups[1].Value;
string base64Image = match.Groups[2].Value;
if (imageType != null && base64Image != null)
{
// Verify the content-type is an image
string imageRegEx = "image/(.+)";
match = Regex.Match(imageType, imageRegEx);
}
if (match.Success)
{
// Get the file extension from the content-type
string fileExtension = match.Groups[1].Value;
// Get the byte-array of the file from the base64 string
byte[] image = Convert.FromBase64String(base64Image);
string path = HttpContext.Current.Server.MapPath("~/images");
string fileName = employees.FirstName + employees.LastName;
// Generate a unique name for the file (add an index to it if it already exists)
string targetFile = fileName + "." + fileExtension;
int index = 0;
while (File.Exists(Path.Combine(path, targetFile)))
{
index++;
targetFile = fileName + index + "." + fileExtension;
}
// Write the image to the target file, and update the agent with the new image path
File.WriteAllBytes(Path.Combine(path, targetFile), image);
employees.ImagePath = "images/" + targetFile;
db.Employees.Add(employee);
db.SaveChanges();
employees.EmployeeId = employee.EmployeeId;
return Ok(employees);
}
}
}
throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, "Could not deserialize Employee"));
}
这是 knockout 的 View 模型
var employeeUrl = "http://localhost:50081/api/employees";
var deptUrl = "http://localhost:50081/api/depts";
var EmployeeViewModel = function () {
var self = this;
self.error = ko.observable();
self.employeeList = ko.observableArray();
self.listDepts = ko.observableArray();
self.newEmployee = {
LastName: ko.observable(),
FirstName: ko.observable(),
ImagePath: ko.observable(),
Address: ko.observable(),
Dept: ko.observable()
}
self.ajaxHelper = function(uri, method, data) {
self.error('');
return $.ajax({
type: method,
url: uri,
dataType: 'json',
contentType: 'application/json',
data: data ? JSON.stringify(data) : null
}).error(function(jqXhr, textStatus, errorThrown) {
self.error(errorThrown + ': ' + jqXhr.responseText);
});
},
self.getDepts = function() {
self.ajaxHelper(deptUrl, 'GET').done(function (data) {
self.listDepts(data);
});
},
self.getAllEmployee = function() {
self.ajaxHelper(employeeUrl, 'GET').done(function(data) {
self.employeeList(data);
});
},
self.addEmployee = function (formElement) {
var employee = {
LastName: self.newEmployee.LastName(),
FirstName: self.newEmployee.FirstName(),
ImagePath: self.newEmployee.ImagePath(),
Address: self.newEmployee.Address(),
DeptId: self.newEmployee.Dept().DeptId
};
self.ajaxHelper(employeeUrl, 'POST', employee).done(function (item) {
self.employeeList.push(item);
});
}
};
$(document).ready(function() {
var employeeVm = new EmployeeViewModel();
ko.applyBindings(employeeVm);
employeeVm.getAllEmployee();
employeeVm.getDepts();
});
这是我在简单的 html 表格上的显示,效果很好
<div class="col-md-6">
<div class="panel panel-default">
<div class="panel-heading">
<h2 class="panel-title">Authors</h2>
</div>
<div class="panel-body">
<table class="table table-striped ">
<thead>
<tr>
<th>Employee Photo </th>
<th>Last Name</th>
<th>First Name </th>
<th>Dept Name </th>
</tr>
</thead>
<tbody data-bind="foreach: employeeList">
<tr>
<td>
<img data-bind="attr:{ src: ImagePath}" width="75" height="75"/>
</td>
<td data-bind="text: LastName"></td>
<td data-bind="text: FirstName"></td>
<td data-bind="text: DeptName"></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
最后是添加表单,
<div class="col-md-6">
<form class="form-horizontal" data-bind="submit: addEmployee" enctype="multipart/form-data">
<div class="form-group">
<label class="col-sm-4 control-label">Dept Name</label>
<div class="col-sm-8">
<select class="form-control" data-bind="options:listDepts, optionsText: 'DeptName', value: newEmployee.Dept"></select>
</div>
</div>
<div class="form-group" data-bind="with: newEmployee">
<label for="inputLastName" class="col-sm-4 control-label">Last Name</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="inputLastName" data-bind="value:LastName"/>
</div>
<label for="inputFirstName" class="col-sm-4 control-label">First Name</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="inputFirstName" data-bind="value:FirstName"/>
</div>
<label for="inputImagePath" class="col-sm-4 control-label">Upload Photo</label>
<div class="col-sm-8">
<input type="file" class="form-control" id="inputImagePath" data-bind="value:ImagePath"/>
</div>
<label for="inputAddress" class="col-sm-4 control-label">Address</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="inputAddress" data-bind="value:Address"/>
</div>
</div>
<div class="col-md-offset-4 col-md-8">
<button type="submit" class="btn btn-default">Submit</button>
</div>
</form>
</div>
在我的浏览器控制台中出现以下错误
发布 http://localhost:50081/api/employees 400(错误请求)
我相信错误可能源于代码行
<input type="file" class="form-control" id="inputImagePath" data-bind="value:ImagePath" />
我是 knockout 的新手,他们的网站上没有太多帮助的文档,
最佳答案
您需要更新您对图像/文件输入的绑定(bind)
<input type="file"
class="form-control"
id="inputImagePath"
data-bind="fileSrc: ImagePath"
accept="image/*">
您可以使用自定义绑定(bind)处理程序来管理将发送到 Controller 的文件数据
ko.bindingHandlers.fileSrc = {
init: function (element, valueAccessor) {
ko.utils.registerEventHandler(element, "change", function () {
var reader = new FileReader();
reader.onload = function (e) {
var value = valueAccessor();
value(e.target.result);
}
// Read in the image file as a data URL.
reader.readAsDataURL(element.files[0]);
});
}
};
鉴于我不知道您的路由是如何配置的,我相信根据您的操作名称 PostEmployee
,如果您将 API 路由配置为使用基于默认约定的路由,那么操作将映射到 api/employees/PostEmployee
。
您的 knockout 代码正试图发布到...
var employeeUrl = "http://localhost:50081/api/employees";
您可以更改帖子的 url 以匹配操作名称或编辑您的 Controller 操作以遵循默认约定...
public class EmployeesController: ApiController {
[HttpPost]
[ResponseType(typeof(EmployeeDetailVm))]
public IHttpActionResult Post(EmployeeDetailVm employees){...}
}
关于c# - 使用 asp.net web api 和 knockout js 处理图像上传的输入表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36529398/