2013-12-06 1 views
1

Я пытаюсь отправить запрос POST с помощью Fiddler, как так:Как десериализации JSON типу .net и возвращает его в виде строки

POST http://localhost:50196/api/values/json HTTP/1.1 
User-Agent: Fiddler 
Content-Type: application/json; 
Host: localhost:50196 
Content-Length: 73 

{"ssn":1605789787,"creditScore":598,"loanAmount":10.0,"loanDuration":360} 

Это мой контроллер WebAPI, где я десериализации его к. NET, который является моим POCO. Затем я получаю ssn и генерирую скорость, которую я тогда хочу вернуть.

public class ValuesController : ApiController 
{ 
    [ActionName("json")] 
    public string Post(string request) 
    { 
     var json = JsonConvert.DeserializeObject<JsonModel>(request); 
     var ss = json.Ssn; 

     var random = new Random(); 
     var interestRate = random.Next(100, 500); 
     var rate = interestRate/100; 

     var delta = "{\"ssn\":" + ss + ",\"interestRate\":" + rate + "}"; 

     return delta; 

    } 

} 

ПОКО:

public class JsonModel 
{ 
    [JsonProperty("ssn")] 
    public string Ssn { get; set; } 
    [JsonProperty("creditScore")] 
    public int CreditScore { get; set; } 
    [JsonProperty("loanAmount")] 
    public decimal LoanAmount { get; set; } 
    [JsonProperty("loanDuration")] 
    public int LoanDuration { get; set; } 
} 

WebAPI конфигурации:

public static void Register(HttpConfiguration config) 
    { 
     // Web API configuration and services 

     // Web API routes 
     config.MapHttpAttributeRoutes(); 

     config.Routes.MapHttpRoute(
      name: "DefaultApi", 
      routeTemplate: "api/{controller}/{action}/{id}", 
      defaults: new { id = RouteParameter.Optional }, 
      constraints: new {action = @"[a-zA-Z]+", id = @"\*"} 
     ); 
    } 

Это ошибка, я получаю:

[HttpException]: Контроллер для пути '/api/values ​​/ json ' не был обнаружен или не реализован IController. веды System.Web.Mvc.DefaultControllerFactory.GetControllerInstance (RequestContext RequestContext, Тип controllerType) веды System.Web.Mvc.DefaultControllerFactory.CreateController (RequestContext RequestContext, String controllerName) веды System.Web.Mvc.MvcHandler.ProcessRequestInit (HttpContextBase HttpContext, IController & контроллер, IControllerFactory & завод) вед System.Web.Mvc.MvcHandler.BeginProcessRequest (HttpContextBase HttpContext, AsyncCallback обратного вызова, объект состояние) вед System.Web.Mvc.MvcHandler.BeginProcessRequest (HttpContext HttpContext, Обратный вызов AsyncCallback, состояние объекта) ved
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest (HttpContext контекст, AsyncCallback CB, объект ExtraData) вед
System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() вед System.Web.HttpApplication.ExecuteStep (IExecutionStep шаг, Boolean & completedSynchronously)

ответ

1

Во-первых, вы полностью отсутствуете в ASP.Возможности привязки модели .NET MVC здесь, вместо того, чтобы принимать строку JSON в действии и затем десериализовать, просто ожидайте модель и пусть структура сделает привязку для вас, например.

public HttpResponseMessage Post(JsonModel model) 
{ 
    ... 
} 

Во-вторых, ваше исключение связано с проблемой маршрутизации. Вы пытаетесь опубликовать сообщение api/values/json, что эквивалентно api/{controller}/{action}. Однако, как вы видите, у вас нет действия, которое сопоставляется с этим конкретным маршрутом, потому что ваш единственный маршрут ожидает параметр id (но ваше действие содержит параметр request).

Переключение на использование модели непосредственно в представлении должно быть достаточно, чтобы исправить эту проблему, и должно работать проводкой непосредственно на api/values/json.


Я думал, что { id = RouteParameter.Optional } была необязательной, как в нем будет принимать ID

Это вообще было бы дело, однако, в вашем пути у вас есть ограничение, установленное на id, который говорит он должен содержать значение - это означает, что значение по умолчанию устарело.

+0

Я думал, что '{id = RouteParameter.Optional}' был необязательным, так как в нем принималось бы без ID. Спасибо за ваш ответ, ура. – brk

+0

@twice - см. Мое обновление – James

+0

Спасибо за ваше дальнейшее объяснение, оценили :) – brk

1

Я думаю, что ваш контроллер может принимать тип POCO напрямую, не нужно сериализовать из строки вручную:

public HttpResponseMessage Post(HttpRequestMessage request, [FromBody]JsonModel) 

Я не уверен, что это проблема. При использовании WebAPI я бы держался подальше от атрибута ActionName. Я думаю, что намного чище иметь отдельный контроллер для каждого типа с помощью простых методов Get/Post и т. Д. Таким образом, в вашем случае:

Контроллер:

public HttpResponseMessage Post(HttpRequestMessage request, [FromBody]JsonModel) 
{} 

Тогда вы просто отправлять сообщения:

api/values 

... и, наконец, ваш маршрут конфигурации:

routeTemplate: "api/{controller}/{id}" 
Смежные вопросы