2017-04-21 56 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和發送文件爲文本字符串。

相關問題