2014-03-03 33 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

相關問題