我正在尝试构建一个用于发布文件的Asp.net web api。我在下面找到了以下示例 https://code.msdn.microsoft.com/AngularJS-with-Web-API-22f62a6e
Web API方法是:
[RoutePrefix("api/photo")]
public class PhotoController : ApiController
{
private IPhotoManager photoManager;
public PhotoController()
: this(new LocalPhotoManager(HttpRuntime.AppDomainAppPath + @"\Album"))
{
}
public PhotoController(IPhotoManager photoManager)
{
this.photoManager = photoManager;
}
// GET: api/Photo
public async Task<IHttpActionResult> Get()
{
var results = await photoManager.Get();
return Ok(new { photos = results });
}
// POST: api/Photo
public async Task<IHttpActionResult> Post()
{
// Check if the request contains multipart/form-data.
if(!Request.Content.IsMimeMultipartContent("form-data"))
{
return BadRequest("Unsupported media type");
}
try
{
var photos = await photoManager.Add(Request);
return Ok(new { Message = "Photos uploaded ok", Photos = photos });
}
catch (Exception ex)
{
return BadRequest(ex.GetBaseException().Message);
}
}
文件上传器html代码:(我添加了一个文本输入<input type="text" id="test" value="testit" />
进行测试。
<form name="newPhotosForm" role="form" enctype="multipart/form-data" ng-disabled="appStatus.busy || photoManagerStatus.uploading">
<div class="form-group" ng-hide="hasFiles">
<label for="newPhotos">select and upload new photos</label>
<input type="file" id="newPhotos" class="uploadFile" accept="image/*" eg-files="photos" has-files="hasFiles" multiple>
<input type="text" id="test" value="testit" /> <!--- Added a text input for test -->
</div>
<div class="form-group" ng-show="hasFiles && !photoManagerStatus.uploading">
<ul class="list-inline">
<li><strong>files:</strong></li>
<li ng-repeat="photo in photos"> {{photo.name}}</li>
</ul>
<input class="btn btn-primary" type="button" eg-upload="upload(photos)" value="upload">
<input class="btn btn-warning" type="reset" value="cancel" />
</div>
<div class="form-group" ng-show="photoManagerStatus.uploading">
<p class="help-block">uploading</p>
</div>
</form>
JS upload
函数:
function upload(photos)
{
service.status.uploading = true;
appInfo.setInfo({ busy: true, message: "uploading photos" });
var formData = new FormData();
angular.forEach(photos, function (photo) {
formData.append(photo.name, photo);
});
return photoManagerClient.save(formData)
.$promise
.then(function (result) {
if (result && result.photos) {
result.photos.forEach(function (photo) {
if (!photoExists(photo.name)) {
service.photos.push(photo);
}
});
}
appInfo.setInfo({message: "photos uploaded successfully"});
return result.$promise;
},
function (result) {
appInfo.setInfo({message: "something went wrong: " + result.data.message});
return $q.reject(result);
})
['finally'](
function () {
appInfo.setInfo({ busy: false });
service.status.uploading = false;
});
}
但是,添加的输入test
的值似乎无法传递给Web API代码?
答案 0 :(得分:1)
您需要添加自定义DTO / POCO类,设置值,然后将其作为参数传递给post方法。由于file不是简单类型,因此webAPI的默认MediaTypeFormatter不起作用,因此您需要构建自定义MediaTypeFormatter。
样本POCO类
var p = document.getElementsByTagName('p')[0],
le = p.innerHTML.split('');
p.innerHTML = '';
var lObj = [];
function Particle (relX, relY, velocity, direction, keyframe, spanEl) {
this.relX = relX;
this.relY = relY;
this.velocity = velocity;
this.direction = direction;
this.friction = 0.1;
this.keyframe = keyframe;
this.spanEl = spanEl;
}
var loc = [];
var centX = 800, centY = 250;
var marker = document.getElementsByClassName('marker')[0];
marker.style.left = centX + 'px';
marker.style.top = centY + 'px';
自定义媒体格式化程序如下
Public Class Attachment
{
public string Input {get;set;}
public byte[] Content{get;set;}
}
注册自定义媒体格式化程序:
public class CustomFormatter : MediaTypeFormatter
{
/// <summary>
///
/// </summary>
public CustomFormatter()
{
SupportedMediaTypes.Add(new MediaTypeHeaderValue("multipart/form-data"));
}
public override bool CanReadType(Type type)
{
return type == typeof(Attachment);
}
public override bool CanWriteType(Type type)
{
return false;
}
public async override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
{
var provider = await content.ReadAsMultipartAsync();
var modelContent = provider.Contents
.FirstOrDefault(c => c.Headers.ContentType.MediaType == "application/json");
var attachment = await modelContent.ReadAsAsync<Attachment>();
var fileContents = provider.Contents
.Where(c => c.Headers.ContentType.MediaType == "image/jpeg").FirstOrDefault(); // or whatever is the type of file to upload
attachment.Content = await fileContents.ReadAsByteArrayAsync();
return attachment;
}
}
将POCO传递给您的Web-API控制器
private void ConfigureWebApi(HttpConfiguration config)
{
//other code here
config.Formatters.Add(new CustomFormatter());
}
我没有在Visual Studio中对此进行测试,但这是您需要遵循的方法
更多信息: http://www.asp.net/web-api/overview/formats-and-model-binding/media-formatters
这里有一个样本 http://blog.marcinbudny.com/2014/02/sending-binary-data-along-with-rest-api.html#.V5MDDzV7qYg