Передайте JSON в MVC 3 Action - PullRequest
       4

Передайте JSON в MVC 3 Action

8 голосов
/ 12 августа 2011

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

Это мой POST к моему действию, адрес может иметь 3 поля или 20, он будет варьироваться в каждом сообщении.

Обновление : я расскажу немного подробнее.Я пытаюсь использовать API-интерфейс LinkedIn, в конце этой страницы мне будет отправлен файл JSON, который будет выглядеть как JSON: ссылка .Мне нужно создать Action, который будет принимать этот JSON, который будет варьироваться для каждого человека.

var address =
    {
        Address: "123 rd",   
        City: "Far Away",
        State: "Over There"           
    };


    $.ajaxSetup({ cache: false });
    $.ajax({
        type: "POST",
        contentType: "application/json; charset=utf-8",
        url: "/Account/GetDetails/",
        data: JSON.stringify(address),
        dataType: "json",
        success: function () {

            alert("Success from JS");
        }
    });

Это мое действие в MVC, мне нужно подать заявку на получение любого объекта JSON и доступ к его полям..

 [HttpPost]
    public ActionResult GetDetails(object address)
    {         
        //address object comes in as null            

        @ViewBag.Successs = true;

        return View();

    }

Ответы [ 9 ]

5 голосов
/ 12 августа 2011

Я не верю, что никто не говорит это, поэтому я попробую.Сделайте так, чтобы ваш код был таким

 public class Personal
 {
      public string Address { get; set; }
      public string City { get; set; }
      public string State { get; set; }
      //other properties here
 }

[HttpPost]
public ActionResult GetDetails(Personal address)
{         
    //Should be able to get it.            

    @ViewBag.Successs = true;

    return View();

}

В общем, вы можете добавить эти возможные свойства в класс Personal (или как вы его можете назвать).Но в соответствии с API API вам потребуется инструмент для генерации класса данных из-за его сложности.Я думаю, что xsd.exe может помочь, если вы можете получить xsd файл для этого (или вы даже можете создать xsd файл из xml)

4 голосов
/ 12 августа 2011
  1. Удалить data: JSON.stringify(address) с data: address

  2. Метод действия

    [HttpPost]
    public ActionResult GetDetails(string Address, string City, string State, string PropName)
    {         
       //access variable here
    }
    

Как вы сказаливаш объект данных может содержать 20 объектов, чтобы избежать создания 20 параметров, вы можете использовать набор форм, как показано ниже

[HttpPost]
public ActionResult GetDetails(FormCollection address)
{        
      string city= address["city"] ;
      string anotherPro=address["prop"];          
}
2 голосов
/ 12 августа 2011

Не уверен, что это сработает (никогда сам этого не делал), но вы можете попробовать следующую подпись:

public ActionResult LinkedIn(dynamic address)

Я на самом деле очень заинтересован, чтобы посмотреть, что будет потом. Или, как предложено в комментарии Кристофа Класа, используйте FormCollection.

Во-вторых, когда такие вещи происходят, всегда проверяйте, действительно ли браузер отправляет ожидаемые вами данные на сервер. IE9 и Chrome поддерживают это из коробки, в противном случае вы можете использовать такой инструмент, как Fiddler .

РЕДАКТИРОВАТЬ : только что попробовал для себя с параметром dynamic, и это не сработало. Тип времени выполнения параметра - object, поэтому все отправленные вами данные потеряны. Вы бы лучше используйте FormCollection.

1 голос
/ 13 августа 2011

Вот как я это делаю.У меня есть MyProject.Model.Entities, и я сериализирую их, используя атрибут [ParamSerializationFilter] для данного метода действия.

Полный код здесь: https://gist.github.com/3b18a58922fdd8d5a963

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (!Enum.GetNames(typeof(AllowedMethods)).Any(n => n == filterContext.HttpContext.Request.HttpMethod))
            throw new InvalidOperationException("Invalid Request: HttpMethod");

        foreach (var param in filterContext.ActionDescriptor.GetParameters())
        {
            if (ModelTypes.Contains(param.ParameterType))
            {
                if ((filterContext.HttpContext.Request.ContentType ?? string.Empty) == ("application/json"))
                {
                    filterContext.ActionParameters[param.ParameterName] =
                        JsonSerializer.DeserializeFromStream(param.ParameterType, filterContext.HttpContext.Request.InputStream);
                }
                else if (filterContext.HttpContext.Request.ContentType.Contains("xml"))
                {
                    filterContext.ActionParameters[param.ParameterName] =
                    XmlSerializer.DeserializeFromStream(param.ParameterType, filterContext.HttpContext.Request.InputStream);
                }
            }
        }
    }
1 голос
/ 12 августа 2011

Мое мнение - все ответы вроде правильные.

Поскольку вы не знаете, сколько сообщений вы отправляете, используйте formcollection на сервере. Но также удалите stringfy из вызова ajax. Это означает, что данные будут отправлены с использованием www-кодировки.

Если вы хотите отправить n объектов адреса, измените параметр действия mvc на массив объектов адреса и используйте stringfy.

1 голос
/ 12 августа 2011

Вам нужно обернуть свой объект JSON в имя параметра, который вы ожидаете в своем методе действия.Примерно так:

var data = { address: { address: '123 Test Way', city: 'Parts Unknown', state: 'TX' } };


$.ajax({
        type: "POST",
        contentType: "application/json; charset=utf-8",
        url: "/Account/GetDetails/",
        data: JSON.stringify(data),
        dataType: "json",
        success: function () {

            alert("Success from JS");
        }

Затем в вашем методе действия сделайте следующее:

public ActionResult GetDetails(dynamic address) {}
1 голос
/ 12 августа 2011

Может быть просто опечатка, но вы звоните GetDetails ActionResult, но ваш код LinkedIn?

1 голос
/ 12 августа 2011

Я полагаю, вы можете использовать FormCollection для этого.

public ActionResult LinkedIn(FormCollection address)
{
    var street = address["street"];
    ...
    return View();
}
0 голосов
/ 12 августа 2011

Ты слишком много работаешь! Вы можете передать JSON Literal непосредственно на сервер и получить доступ к элементам через параметры метода действия, например:

var address =
    {
        Address: "123 rd",   
        City: "Far Away",
        State: "Over There"           
    };


    $.ajaxSetup({ cache: false });
    $.ajax({
        type: "POST",
        contentType: "application/json; charset=utf-8",
        url: "/Account/GetDetails/",
        data: address,
        dataType: "json",
        success: function () {

            alert("Success from JS");
        }
    });

[HttpPost]
    public ActionResult LinkedIn(string Address, string City, string State)
    {                    
        // now you have everything you want as params
        @ViewBag.Successs = true;

        return View();

    }

Примечание. Это будет работать только в том случае, если ваши параметры действий названы точно так же, как атрибуты JSON Literal.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...