2015-01-29 2 views
1

У меня есть контроллер Web API определяется как следующим образом:HTTP Post с FormData не достигается в WebAPI

[HttpPost] 
public class EmailActivitiesController : ApiController 
{ 
    public HttpResponseMessage EmailAClientWithNewMailMessage(FormDataCollection aFormData) 
    { 
    } 
} 

, который вызывается с помощью следующего JQuery:

var aFormData = {}; 
    $.support.cors = true; 
    $.ajax({ 
     cache: false, 
     url: '/api/EmailActivities/EmailAClientWithNewMailMessage', 
     type: "POST", 
     dataType: "json", 
     data: aFormData, 
     success: function (callback) { 
      //Platform.LoadingPanelHide(); 
      alert("Successfully sent the email."); 
     }, 
     error: function (data) { 
      var errorObject = JSON.parse(data); 

      //Platform.LoadingPanelHide(); 
      alert('There was a problem sending the email message to the individual selected.\n\n' + errorObject.responseText.message); 
     } 
    }); 

и что все работы и метод API достигнуты. Однако, как только я заселить aFormData, как показано ниже:

var aFormData = {}; 

    aFormData['aMessageInfo'] = "test"; 

    //And sending via form data 
    $.support.cors = true; 
    $.ajax({ 
     cache: false, 
     url: '/api/EmailActivities/EmailAClientWithNewMailMessage', 
     type: "POST", 
     dataType: "json", 
     data: aFormData, 
     success: function (callback) { 
      //Platform.LoadingPanelHide(); 
      alert("Successfully sent the email."); 
     }, 
     error: function (data) { 
      var errorObject = JSON.parse(data); 

      //Platform.LoadingPanelHide(); 
      alert('There was a problem sending the email message to the individual selected.\n\n' + errorObject.responseText.message); 
     } 
    }); 

то метод не будет достигнуто, и я receieve вместо этого HttpResonseCode.OK со следующим ответом JSON:

{ 
"result": null, 
"success": false, 
"error": { 
"code": 0, 
"message": "An internal error occured during your request!", 
"details": null, 
"validationErrors": null 
}, 
"unAuthorizedRequest": false 
} 

Для жизни меня я не может понять, почему это происходит. Кто-нибудь получил какие-либо идеи.

UPDATE

Вот запрос POST. enter image description here

И журнал исключение:

ERROR 2015-01-29 15:51:08,250 [17 ] Default         - Processing of the HTTP request resulted in an exception. Please see the HTTP response returned by the 'Response' property of this exception for details. 
System.Web.Http.HttpResponseException: Processing of the HTTP request resulted in an exception. Please see the HTTP response returned by the 'Response' property of this exception for details. 
    at System.Web.Http.ModelBinding.FormatterParameterBinding.ReadContentAsync(HttpRequestMessage request, Type type, IEnumerable`1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken) 
    at System.Web.Http.ModelBinding.FormatterParameterBinding.ReadContentAsync(HttpRequestMessage request, Type type, IEnumerable`1 formatters, IFormatterLogger formatterLogger) 
    at System.Web.Http.ModelBinding.FormatterParameterBinding.<ExecuteBindingAsyncCore>d__0.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.GetResult() 
    at System.Web.Http.Controllers.HttpActionBinding.<ExecuteBindingAsyncCore>d__0.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.GetResult() 
    at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() 
    at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__0.MoveNext() 

UPDATE # 2

Я теперь пошли с предложенным подходом с использованием DTO следующим образом:

var aMessageInfo = { 
      subject: Base64.encode($("#txtSendEmailSubject").val()), 
      body: Base64.encode($("#txtSendEmailBody").val()) 
     }; 

$.support.cors = true; 
     $.ajax({ 
      cache: false, 
      url: '/api/EmailActivities/Dono2', 
      type: "POST", 
      dataType: "json", 
      contentType: "application/json; charset=utf-8", 
      data: JSON.stringify(aMessageInfo), 
      success: function (callback) { 
       //Platform.LoadingPanelHide(); 
       alert("Successfully sent the email."); 
      }, 
      error: function (data) { 
       var errorObject = JSON.parse(data); 

       //Platform.LoadingPanelHide(); 
       alert('There was a problem sending the email message to the individual selected.\n\n' + errorObject.responseText.message); 
      } 
     }); 

, а затем в WebAPI он работает, если у меня есть только:

public class EmailActivitiesController : ApiController 
    { 
    [HttpPost] 
     public HttpResponseMessage Dono2(MessageInfo aMessageInfo) 
     { 
     } 
    } 

, но как только у меня есть EmailAClientWithNewMailMessage как метод:

public class EmailActivitiesController : ApiController 
    { 
    [HttpPost] 
     public HttpResponseMessage Dono2(MessageInfo aMessageInfo) 
     { 
     } 


    [HttpPost] 
     public HttpResponseMessage EmailAClientWithNewMailMessage(FormDataCollection aFormData) 
     { 
} 

Я получаю ошибку:

{ 
    "message":"An error has occurred.", 
    "exceptionMessage":"Multiple actions were found that match the request: \r\nDono2 on type MakersLane.WebApi.Controllers.EmailActivitiesController\r\nEmailAClientWithNewMailMessage on type MakersLane.WebApi.Controllers.EmailActivitiesController", 
    "exceptionType":"System.InvalidOperationException", 
    "stackTrace":" at System.Web.Http.Controllers.ApiControllerActionSelector.ActionSelectorCacheItem.SelectAction(HttpControllerContext controllerContext)\r\n at System.Web.Http.Controllers.ApiControllerActionSelector.SelectAction(HttpControllerContext controllerContext)\r\n at Abp.WebApi.Controllers.Dynamic.Selectors.AbpApiControllerActionSelector.SelectAction(HttpControllerContext controllerContext)\r\n at System.Web.Http.ApiController.ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()" 
} 

Сейчас пока есть два действия на контроллере Dono2 и EmailClientWithNewMessage Я не понимаю, почему они не могут быть разделены, поскольку у них явно разные имена, и хотя у обоих есть один параметр, они называются по-разному и имеют разные типы.

Может ли кто-нибудь объяснить, почему это происходит?

+1

Можете ли вы разместить HTTP-запрос, отправленный по сети? –

+0

@JoelGregory Добавил FireBug того, что появляется на проводе .... Если вы хотите что-то еще, дайте мне знать, и я добавлю его, – TheEdge

ответ

1

Вы просмотрели файл Logs/logs.txt? Там будет исключение.

Приветствия Джефф

+0

Забытый ABP теперь регистрировал исключения. Выложили журнал для чего он стоит. Все еще не уверен, что это ABP или что-то еще. Я понимаю, что я работаю со старой версией ABP viz 0.4.1, но не хочу обновляться до тех пор, пока не узнаю, что это ABP – TheEdge

2

Я не на окна машины поэтому не может проверить эту запись сейчас, но я буду предлагать альтернативное решение ниже. Это проблема с отображением из строки запроса отправленного в POST к FormDataCollection и я думаю может быть решена с помощью объекта JSON как это:

{ aFormData : { aMessageInfo : "test" } }

, но я не могу подтвердить. Я считаю, что следующее решение будет лучше, поэтому используйте его, если вам не нужно использовать FormDataCollection.

Я бы рекомендовал использовать вид модели вместо FormDataCollection как отображение значений становится утомительным:

public class Message 
{ 
    public string Client { get; set; } 
    public string Content { get; set; } 
} 

Затем измените свой контроллер:

public HttpResponseMessage EmailAClientWithNewMailMessage(Message data) 
{ 
    // use the deserialised object here 
    return data.Client; 
} 

И ваш JQuery будет выглядеть следующим образом (обратите внимание на добавление параметра типа контента и вызова JSON.stringify):

var aFormData = {}; 

aFormData['aMessageInfo'] = "test"; 

//And sending via form data 
$.support.cors = true; 
$.ajax({ 
    cache: false, 
    url: '/api/EmailActivities/EmailAClientWithNewMailMessage', 
    type: "POST", 
    dataType: "json", 
    contentType: "application/json; charset=utf-8", 
    data: JSON.stringify(aFormData), 
    success: function (callback) { 
     //Platform.LoadingPanelHide(); 
     alert("Successfully sent the email."); 
    }, 
    error: function (data) { 
     var errorObject = JSON.parse(data); 

     //Platform.LoadingPanelHide(); 
     alert('There was a problem sending the email message to the individual selected.\n\n' + errorObject.responseText.message); 
    } 
}); 
1

Я думаю, что Джоэл прав. У меня были проблемы с передачей строк в качестве параметров и, таким образом, перенос всех моих входов в объекты DTO, и он работает нормально.

Приветствия Джефф

0

Проблема заключается в том, что: система АВР настроена на работу только с данными JSON. Когда вы меняете такой код, он работает:

$.ajax({ 
    cache: false, 
    url: '/api/EmailActivities/EmailAClientWithNewMailMessage', 
    type: "POST", 
    contentType: 'application/json', 
    dataType: "json", 
    data: JSON.stringify({ aMessageInfo: 'test' }), 
    success: function (callback) { 
     //Platform.LoadingPanelHide(); 
     alert("Successfully sent the email."); 
    }, 
    error: function (data) { 
     var errorObject = JSON.parse(data); 

     //Platform.LoadingPanelHide(); 
     alert('There was a problem sending the email message to the individual selected.\n\n' + errorObject.responseText.message); 
    } 
}); 

Я добавил contentType. Таким образом, вызывается метод, но данные формы не поступают в этот метод. Возможно, FormDataCollection не любит сообщения JSON.

Почему вы не используете простой класс DTO вместо FormDataCollection? Это более естественно для проектов ABP.

В AbpWebApiModule он очищает все форматирующие элементы и добавляет JSON и обычный текст.

 private static void InitializeFormatters() 
     { 
      GlobalConfiguration.Configuration.Formatters.Clear(); 
      var formatter = new JsonMediaTypeFormatter(); 
      formatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 
      GlobalConfiguration.Configuration.Formatters.Add(formatter); 
      GlobalConfiguration.Configuration.Formatters.Add(new PlainTextFormatter()); 
     } 

Может быть, вы можете использовать GlobalConfiguration.Configuration.Formatters.Add для добавления других форматтеров.

Как я нашел проблему? ABP определяет событие для обработки исключений (начиная с v0.3.2):

enter image description here

Это может помочь вам, находя ошибки.

EventBus.Default.Register<AbpHandledExceptionData>(
    data => 
    { 
     //use data.Exception to see exception details 
    }); 
+0

. Я принял ваш совет, чтобы передать простой DTO (не добавлял дополнительные форматы).Однако можете ли вы взглянуть на «Обновление № 2» и сообщить мне, почему существует ошибка с тем, что ABP не может определить селекторов отдельно? – TheEdge

Смежные вопросы