2014-03-03 35 views
2

我正在做一个小测试床的应用程序,在这个应用程序中给应用程序一个音符名称,符号和八度音,并且它会发出音符响起的频率。为什么不把这个javascript对象转换成C#类对象?

我遇到了通过AJAX发送到服务器的JavaScript对象的问题。但是,它根本不会映射到课程上。

发送者的代码是一段JavaScript代码:

$someContainer.on('click', '.raise-pitch', function (e) { 
    e.preventDefault(); 

    var $line = $(this).parents('.item-line'), 
     // Cache GUI elements for this line. Not pertinent. 

    var data = { 
     'model': { 
      'NoteName': $noteName.val(), 
      'Sign': $noteSign.val(), 
      'Octave': $noteOctave.val() 
     }, 
     'steps': 1 
    }; 
    var dataString = JSON.stringify(data); 

    $.ajax({ 
     type: 'POST', 
     url: '@Url.Action("AlterPitch", "Home")', 
     data: dataString, 
     async: true, 
     dataType: 'json', 
     success: function (result) { 
      // Unimportant things. 
     } 
    }); 
}); 

data对象,你可以看到,我有两两件事:modelsteps。这些步骤决定了我们改变音符的距离。我已经验证了note name,signoctave的值正在使其成为数据对象。 steps是预先确定的。

data对象,然而,映射到一个视图模型在C#的一面,它看起来像这样:

public class NoteViewModel 
{ 
    public enum NoteSign 
    { 
     Natural, 
     Sharp, 
     Flat 
    } 

    public string NoteName { get; set; } 
    public NoteSign Sign { get; set; } 
    public int Octave { get; set; } 
    public float Frequency { get; set; } 

    private static readonly Dictionary<string, float> FrequencyLookup = new Dictionary<string, float> 
     { 
      {"C", 16.35f}, 
      {"C#", 17.32f}, 
      {"D", 18.35f}, 
      {"D#", 19.45f}, 
      {"E", 20.60f}, 
      {"F", 21.83f}, 
      {"F#", 23.12f}, 
      {"G", 24.50f}, 
      {"G#", 25.96f}, 
      {"A", 27.50f}, 
      {"A#", 29.14f}, 
      {"B", 30.87f} 
     }; 

    // Methods...not important for reasons below. 
} 

...本身被封装在一个独特的视角模式:

public class AlterPitchViewModel 
{ 
    public NoteViewModel model; 
    public int steps; 

    public NoteViewModel AlterPitch() 
    { 
     model.ChangeStep(steps); 
     return model; 
    } 
} 

...或者至少它应该。我把我的控制器方法断点:

[HttpPost] 
public ActionResult AlterPitch(AlterPitchViewModel model) 
{ 
    return Json(model.AlterPitch(), JsonRequestBehavior.AllowGet); 
} 

...但是,该模型为空,这导致了NullReference例外。

该模型不会序列化为在此上下文中发送的对象。很明显,我仍然在做错事。 问题是...什么?

+2

缺少方法顶部的[HttpPost]属性? – Askolein

+0

@Askolein - 帮助。尽管如此,请求的“模型”部分出现了奇怪的结果,导致404错误。 –

+1

您是否试图将对象串联化并将请求内容类型设置为json? – Andrei

回答

1

这种方法适用于我。

服务器端:

首先,创建您的视图模型

public class TestViewModel 
{ 
    public string Id { get; set; } 
    public string Description { get; set; } 
} 

然后,在控制器:

[HttpPost] 
public ActionResult TestingViewModel(TestViewModel udata) 
{ 
    // Stuff. 
} 

客户端:

function CallTestingViewModel() { 

    // We create the javascript object based on the 
    // definition of our C# ViewModel class. 
    var udata = { 
     Id: 1, 
     Description: 'This is a test.' 
    }; 

    // Calling the C# method via AJAX. 
    $.when(GenericAjaxCall('Home/TestingViewModel', false, udata)).then(function (result) { 
     // do stuff 
    }); 

} 


// Return the AJAX call as a Promise Object 
function GenericAjaxCall(controllerUrl, async, clientData) { 
    return $.ajax({ 
     type: 'POST', 
     async: async, 
     url: controllerUrl, 
     data: JSON.stringify(clientData), 
     contentType: 'application/json;', 
     dataType: 'json' 
    }); 
} 

希望它有帮助。

+0

我确实尝试过这种模式,但我仍然在向服务器发送问题时遇到问题。我试图更多地使用这种模式,因为Promise模式看起来更具可读性和组织性 - 感谢您向我展示了这一点! –

+0

你得到了什么确切的错误?您能否提供关于Chrome在开发人员工具中提供的标题和响应的信息? – eliashdezr

+0

我改进了我的对象,没有使用嵌套对象,并且我所有的问题都消失了(使用上面给出的promise对象配置帮助简化了我的代码。)也许我不能将嵌套对象发送到服务器,对于某些原因。 –

1

你的HttpPost方法必须有一个唯一的参数,它是你的ViewModel。我的建议是:为每个帖子创建一个视图模型WebMethod

所以在这里:

​​

并相应地调整你的Javascript。无需将您的JavaScript模型实例命名为ASP方法中的参数 - >一个对象到达并且只有一个参数可用,因此没有歧义。

+0

尽管我同意这是一个很好的体系结构决策,但我还是遇到了HTTP 404问题,这是无法解决的。但是,这是一个很好的建议,谢谢! –

+0

404?这是一个路由问题。不是由于您的POST问题。 – Askolein

相关问题