Как разместить файл JSON в ASP.NET MVC Action?

Мой iphone-клиент отправляет следующий json в мою службу mvc. При отправке данных из html-формы он автоматически преобразует данные формы в UserModel и передает объект моему методу Create, но когда я отправляю строку JSON в теле моего запроса из iphone, он возвращается как null.

Каким будет самое чистое решение для преобразования из JSON в Object.

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

Тело моей просьбы:

{
   "firstName" : "Some Name",
   "lastName" : "Some Last Name",
   "age" : "age"
}

Моя модель и результат действия

public class UserModel
{
   public int Id { get; set; }
   public string FirstName { get; set; }
   public string LastName { get; set; }
   public int Age { get; set; }
}

[HttpPost]
public Create ActionResult(UserModel user)
{
   // user is null
   userStorage.create(user);
   return SuccessResultForModel(user);
}

Ответ 1

Вам нужно установить HTTP-заголовок, принять, на "application/json", чтобы MVC знал, что вы передаете JSON и выполняет работу по его интерпретации.

accept: application/json

см. больше информации здесь: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

UPDATE: Рабочий пример кода с использованием MVC3 и jQuery

Код контроллера

namespace MvcApplication1.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public JsonResult PostUser(UserModel data)
        {
            // test here!
            Debug.Assert(data != null);
            return Json(data);
        }
    }

    public class UserModel
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
    }
}

Просмотр кода

@{ ViewBag.Title = "Index"; }
<script src="../../Scripts/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
    var sample = {};
    sample.postData = function () {
        $.ajax({
            type: "POST", url: "@Url.Action("PostUser")",
            success: function (data) { alert('data: ' + data); },
            data: { "firstName": "Some Name", "lastName": "Some Last Name", "age": "30" },
            accept: 'application/json'
        });
    };
    $(document).ready(function () {
        sample.postData();
    });
</script>

<h2>Index</h2>

Ответ 2

Попробуйте изменить метод на это, чтобы узнать, получаете ли вы имя FirstName или LastName

public Create ActionResult(string FirstName, string LastName)

Ответ 3

Поздно, но надеюсь, что это поможет кому-то.

Что было бы самым чистым решением для преобразования из JSON в Object?

<script src="https://code.jquery.com/jquery-3.1.0.js"></script>

$.post("http://localhost:52161/Default/PostRawJson/", { json: {
   "firstName" : "Some Name",
   "lastName" : "Some Last Name",
   "age" : "age"
}});


public void PostRawJson(string json)
{
    var person = System.Web.Helpers.Json.Decode(json);
    person.firstname...
}

Таким образом вы получаете чистый объект JSON для работы с вашим контроллером по запросу.

Ответ 4

Недавно я придумал гораздо более простой способ опубликовать JSON с дополнительным шагом перехода от модели в моем приложении. Обратите внимание, что вы должны сделать модель [JsonObject] для вашего контроллера, чтобы получить значения и выполнить преобразование.

Запрос:

 var model = new MyModel(); 

 using (var client = new HttpClient())
 {
     var uri = new Uri("XXXXXXXXX"); 
     var json = new JavaScriptSerializer().Serialize(model);
     var stringContent = new StringContent(json, Encoding.UTF8, "application/json");
     var response = await Client.PutAsync(uri,stringContent).Result;
     ...
     ...
  }

Модель:

[JsonObject]
[Serializable]
public class MyModel
{
    public Decimal Value { get; set; }
    public string Project { get; set; }
    public string FilePath { get; set; }
    public string FileName { get; set; }
}

Серверная сторона:

[HttpPut]     
public async Task<HttpResponseMessage> PutApi([FromBody]MyModel model)
{
    ...
    ... 
}

Ответ 5

На основании ответа Гленна Ферриса, который, казалось, работал, пока я не посмотрел на то, что на самом деле отправлялось контроллеру - и это был не JSON.

Следовательно, настроен немного ниже:

Это с MVC 4, а jQuery 1.7 ish

Метод действия контроллера (объект UserModel как в вопросе):

[HttpPost]
public ActionResult Create(UserModel user)
{
    Debug.Assert(data != null);
    return Json(data);
}

Код jQuery для отправки запроса:

<script>
    $(function () {
        $.ajax({
            type: "POST",
            url: "@Url.Action("Create")",
            /* jQuery will not send JSON unless you explicitly tell it to */
            data: JSON.stringify({ "firstName": "Some Name", "lastName": "Some Last Name", "age": "30" }),
            /* contentType is important for MVC to be able to unpack the json */
            contentType: 'application/json'
            accept: 'application/json',
        }).done( function(data) {
            /* this callback gets used when successful */
            console.log("response: " + data);
        }).fail(function (jqxhr, status, error) {
            /* for debugging: this callback gets used in case of errors */
            console.log("error :" + error);
        }).always(function () {
            /* for debugging: this callback always gets called at the end either way*/
            console.log("complete");
        });
    });

</script>

Действие контроллера MVC легко.

Сложность в том, чтобы убедиться, что вы действительно отправляете JSON для его тестирования.

Метод jQuery ajax() при использовании с POST обычно кодирует параметры, используя формат строки запроса в теле запроса. MVC может с радостью распаковать это.

Для фактической отправки JSON с помощью ajax() вы должны использовать JSON.stringify().

А чтобы MVC правильно интерпретировал этот запрос, вам нужно установить contentType