2017-04-21 43 views
0

我在客户端使用AngularJS将表单提交给服务器端的控制器。如何将包含文件的表单提交给FOSRestBundle控制器

由于我们正在将文件存储在应用程序中,并且用户提供了有关该文件的一些元数据,因此工作流无法拆分为较小的任务。

我已经使用Angular的$ http服务上的请求转换构建了提交数据。 Web服务客户端的当前状态:

function _save(dataModel, formfile) 
{ 
    $http({ 
     url : basePath + (dataModel.id ? ("/" + dataModel.id) : ""), 
     method : "POST", 
     headers : { 
      'Content-Type' : undefined 
     }, 
     transformRequest : function(data) 
     { 
      var formData = new FormData(); 
      formData.append("dto", angular.toJson(data.model)); 
      formData.append("file", data.file); 
      return formData; 
     }, 
     data : { 
      model : dataModel, 
      file : formfile 
     } 
    }).then(function(response) 
    { 
    }); 
} 

不幸的是,我得到这样的回应:

415不支持的媒体类型

我一直没能确定的哪些组件Symfony堆栈提供了该回复,也不提及multipart/form-data或附加到该文件的Content-Type: application/octet-stream规范。

有什么我可以做的调试和解决这个问题?我怀疑这是一个配置问题。以下是我已经添加到默认的Symfony配置config.yml的元素:

# Nelmio CORS Configuration 
nelmio_cors: 
    defaults: 
     allow_credentials: false 
     allow_origin: ['*'] 
     allow_headers: ['*'] 
     allow_methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'] 
     max_age: 3600 
     hosts: [] 
     origin_regex: false 

# FOSRest Configuration 
fos_rest: 
    body_listener: true 
    body_converter: 
     enabled: true 
     validate: true 
     validation_errors_argument: validationErrors # This is the default value 
    format_listener: 
     rules: 
      - { path: '^/', priorities: ['json'], fallback_format: json, prefer_extension: false } 
    param_fetcher_listener: true 
    view: 
     view_response_listener: 'force' 
     formats: 
      json: true 
      html: false 
# 
# Needed for being able to use ParamConverter 
sensio_framework_extra: 
    request: { converters: true } 

回答

0

我实现的解决方案归结于由ParamConverter注释手工处理那些通常处理(该项目)的任务(反序列化和验证):

  1. 改变控制器
  2. 手动签名反序列化数据
  3. 手动验证数据

此外,似乎该错误消息是由JMSSerializer发送。

现在:

/** 
* @Rest\Post("") 
*/ 
public function postAction(Request $request) 
{ 
    // 
    // Deserialisation 
    $dto = $this->deserializeDto($request); 
    if ($dto == null) { 
    return $this->view("Invalid 'dto' parameter contents.", response::HTTP_BAD_REQUEST); 
    } 

    // 
    // Validation: the name ('Nom') and a file are required 
    $validationErrors = [ ]; 
    if ($dto->getNom() === null || strlen($dto->getNom()) == 0) { 
    $validationErrors[] = "'Nom' is missing"; 
    } 
    $file = $request->files->get("file"); 
    if ($file === null) { 
    $validationErrors[] = "No file provided"; 
    } 
    if (count($validationErrors) > 0) { 
    $view = $this->view($validationErrors, response::HTTP_BAD_REQUEST); 
    return $view; 
    } 

    // 
    // processing 
    return $this->doSave($dto, $request); 
} 

以前(我可能有这样的事情):

/** 
* @Rest\Post("") 
* @ParamConverter("dto", converter="fos_rest.request_body", options={"validator"={"groups"={"edit"}}}) 
* @Rest\QueryParam(name="dto", nullable=false) 
*/ 
public function postAction(Request $request, Document $dto, ConstraintViolationListInterface $validationErrors) 
{ 
.... 
} 

可能有这样做(包括验证部分)的一个更好的办法,但我需要在这一点上前进;重构将在稍后进行。

0

我已经解决了这个文件转换成一个base64字符串使用JavaScript和发送文件为文本字符串。

相关问题