2015-05-27 17 views
24

Muszę wysłać do kontrolera Api w/JSON (najlepiej) z JEDNĄ prośbą.Post JSON z danymi I plikiem do Web Api - jQuery/MVC

Problem polega na przekazywaniu danych ORAZ pliku (zdjęcie przesłane). Moja właściwość jest pusta (zero).

Oglądałem sporo blogów, ale nie udało mi się uzyskać danych obrazu przekazanych.

public class SomeModel 
{ 
    public string Name { get; set; } 
    public string Email { get; set; } 
    public string City { get; set; } 
    public HttpPostedFileBase Image { get; set; } 
    public string Title { get; set; } 
    public string Description { get; set; } 
    public string CountryCode { get; set; } 
} 


    [HttpPost] 
    public void CreateContestEntry(SomeModel model) 
    { 
     // model.Image is always null 
     // .. get image here - the other properties no issues 
    } 

jQuery

// create model for controller 
    var model = { 
     Name: $.trim($contestForm.find('[name="nombre"]').val()) + ' ' + $.trim($contestForm.find('[name="apellido"]').val()), 
     Email: $.trim($contestForm.find('[name="email"]').val().toLowerCase()), 
     City: $.trim($contestForm.find('[name="cuidad"]').val()), 
     Title: $.trim($contestForm.find('[name="title"]').val()), 
     Description: $.trim($contestForm.find('[name="description"]').val()), 
     CountryCode: 'co', 
     Image: $contestForm.find('[name="file-es"]')[0].files[0] // this has the file for sure 
    }; 

    $.ajax({ 
     url: '/Umbraco/api/ControllerName/CreateContestEntry', 
     type: 'POST', 
     dataType: 'json', 
     data: JSON.stringify(model), 
     //data: $('#test-form').serialize(), // tried this and using FormData() 
     processData: false, 
     async: false, 
     contentType: 'application/json; charset=utf-8', 
     complete: function (data) { 

     }, 
     error: function (response) { 
      console.log(response.responseText); 
     } 
    }); 

enter image description here

Blogi Sprawdziliśmy:


Kiedy próbowałem zbliżyć się FormData i $('#form1').serialize() mój provider.FileData i provider.FormData były zawsze pusty, jak również. Usunąłem z tej metody parametr model, a punkty przerwania uderzały, kiedy je przełączałem.

[HttpPost] 
    public void CreateContestEntry() 
    { 
     string root = HttpContext.Current.Server.MapPath("~/App_Data"); 
     var provider = new MultipartFormDataStreamProvider(root); 

     try 
     { 
      // Read the form data. 
      Request.Content.ReadAsMultipartAsync(provider); 

      // This illustrates how to get the file names. 
      foreach (MultipartFileData file in provider.FileData) 
      { 
       // empty 
      } 

      foreach (var key in provider.FormData.AllKeys) 
      { 
       foreach (var val in provider.FormData.GetValues(key)) 
       { 
        // empty 
       } 
      } 
      //return Request.CreateResponse(HttpStatusCode.OK); 
     } 
     catch(Exception ex) 
     { 

     } 
    } 

ROZWIĄZANIE:

Idąc off @ odpowiedź Musy, oto kod Api Controller. Zmapowałem NameValueCollection do mojego modelu.

[HttpPost] 
    public void CreateContestEntry() 
    { 
     try 
     { 
      // get variables first 
      NameValueCollection nvc = HttpContext.Current.Request.Form; 
      var model = new WAR2015ContestModel(); 

      // iterate through and map to strongly typed model 
      foreach (string kvp in nvc.AllKeys) 
      { 
       PropertyInfo pi = model.GetType().GetProperty(kvp, BindingFlags.Public | BindingFlags.Instance); 
       if (pi != null) 
       { 
        pi.SetValue(model, nvc[kvp], null); 
       } 
      } 

      model.Image = HttpContext.Current.Request.Files["Image"]; 
     } 
     catch(Exception ex) 
     { 

     } 
    } 

Odpowiedz

20

Nie można załadować pliku (czyli dowolnych danych binarnych) za pomocą JSON, ponieważ JSON jest formatem tekstowym. będziesz musiał użyć wieloczęściowych danych formularzy.

// create model for controller 
var model = new FormData(); 
model.append('Name', $.trim($contestForm.find('[name="nombre"]').val()) + ' ' + $.trim($contestForm.find('[name="apellido"]').val())); 
model.append('Email', $.trim($contestForm.find('[name="email"]').val().toLowerCase())); 
model.append('City', $.trim($contestForm.find('[name="cuidad"]').val())); 
model.append('Title', $.trim($contestForm.find('[name="title"]').val())); 
model.append('Description', $.trim($contestForm.find('[name="description"]').val())); 
model.append('CountryCode', 'co'); 
model.append('Image', $contestForm.find('[name="file-es"]')[0].files[0]); // this has the file for sure 

$.ajax({ 
    url: '/Umbraco/api/ControllerName/CreateContestEntry', 
    type: 'POST', 
    dataType: 'json', 
    data: model, 
    processData: false, 
    contentType: false,// not json 
    complete: function (data) { 
     var mediaId = $.parseJSON(data.responseText); //? 

    }, 
    error: function (response) { 
     console.log(response.responseText); 
    } 
}); 
+0

Błąd odbierania na "var model = new FormData();" Uncaught TypeError: object nie jest funkcją. I tak, skomentowałem mój poprzedni obiekt modelu, więc nie kopiowałem zmiennej. –

+0

Jakiej przeglądarki używasz? Czy zdefiniowałeś FormData gdzieś indziej w twoim kodzie? – Musa

+0

Chrome - dodaj ten plik js jest ogromny - szukał 'FormData()' i pojawia się kilka razy, ale dla innych zmiennych zdefiniowanych gdzie indziej. Żadne metody nie są nazwane tak –

Powiązane problemy