System. reflection. ambiguousmatchexception is thrown when store. Sync of extjs is submitted to the action of Asp.net MVC.

Source: Internet
Author: User

the store in extjs can submit data in batches during sync. The so-called batch refers to if the CREATE, update, and delete objects are recorded in the store at the same time, submit in three installments. At the time of submission, multiple objects will be combined into strings in JSON format. When only one data is to be submitted, the JSON string is as follows:

{< SPAN class = "str"> "ID" :  "a6d671ca-5480-4b5b-bf7a-b8459c0f598b" ,  "mobilepin" :  "" ,  "email" :  "111@ee.com" ,  "password" :  "" ,  "createdate" :  null ,  "lastlogindate" :  null ,  "lastpasswordchangeddate" :  null ,  "comment" :  "" ,  "username" :  "user1" ,  "mobilealias" :  "" ,  "lastactivitydate" :  null ,  "displayname" :  "" ,  "rememberme" :  false }

If multiple data entries exist, the JSON string is:

 [{ "ID" :  "a6d671ca-5480-4b5b-bf7a-b8459c0f598b" ,  "mobilepin" :  "" ,  "email" :  "111@ee.com" ,  "password" :  "" ,  "createdate" :  null ,  "lastlogindate" :  null ,  "lastpasswordchangeddate" :  null ,  "comment" :  "" ,  "username" :  "user1" ,  "mobilealias" :  "" ,  "lastactivitydate" :  null ,  "displayname" :  "" ,  "rememberme" :  false }] 

In the action of the controller, if the method signature is public jsonresult createuser (userdataobject user), only 1st data entries can be received when multiple data entries are passed in; when the method signature is private list <userdataobject> processusers (list <userdataobject> users), there is no problem when there are multiple data entries. If there is only one data entry, users is null.

I thought of writing both methods directly in action, but the result is system. reflection. ambiguousmatchexception, that is, the MVC actionselector can no longer distinguish which method to call.

Find the MVCCodeIt is found that in the runselectionfilters method of asyncactionmethodselector, The atrriters method on the action will be searched. attributes such as httppost will be filtered to determine whether they meet the context of the current call.

After knowing this, I think we can write a custom attribute and decide which method is available and which method is unavailable based on the content of the current request, there are two key points to achieve this:

1. How to implement this attribute.

2. How to obtain and solve the post content of the request.

 

1st problems are well solved, because I have not systematically read MVC information, so I can check httppost to know That it inherits actionmethodselectorattribute, and there is an abstract method isvalidforrequest in this class.

After obtaining the request for 2nd questions, determine whether the current post type is application/JSON and deserialize the post data in JSON format. Tests show that if a single object is used, the deserialized object is a dictionay <string, Object> object, and multiple objects get an object []. The source code is provided below:

 Public   Class Jsonmodelpostattriattribute: actionmethodselectorattribute { Public   Enum Parametertype {single, multiple} Private Parametertype _ parametertype; Public Parametertype methodparametertype {get { Return _ Parametertype;} set {_ parametertype = Value ;}} Public Jsonmodelpostattribute () {_ parametertype = parametertype. Single ;} Public Jsonmodelpostattribute (parametertype type) {_ parametertype = type ;} Public   Override   Bool Isvalidforrequest (controllercontext, system. reflection. methodinfo) {var c = getdeserializedobject (controllercontext ); If (C = Null ){ Return   True ;} If (Methodparametertype = parametertype. Single ){ Return C Is Dictionary < String , Object > ;} Else { Return C Is   Object [] ;}} Private   Static   Object Getdeserializedobject (controllercontext ){ If (! Controllercontext. httpcontext. Request. contenttype. startswith ( "Application/JSON" , Stringcomparison. ordinalignorecase )){// Not JSON request                  Return   Null ;} Controllercontext. httpcontext. Request. inputstream. Seek (0, seekorigin. Begin); streamreader reader = New Streamreader (controllercontext. httpcontext. Request. inputstream ); String Bodytext = reader. readtoend (); controllercontext. httpcontext. Request. inputstream. Seek (0, seekorigin. Begin ); If (String. isnullorempty (bodytext )){ // No JSON data                  Return   Null ;} Javascriptserializer serializer =New Javascriptserializer (); Object Jsondata = serializer. deserializeobject (bodytext ); Return Jsondata ;}}

Note that after inputstream is read, the position must be set to 0 again. Otherwise, the subsequent jsonvalueproviderfactory will not be able to reverse the instance, even if it can enter the correct action, the parameter is also null.

The following is the test code snippet in controller:

[Allowanonymous] [httppost] [jsonmodelpost (jsonmodelpostattriple. parametertype. Multiple)] Public Jsonresult createuser (list <userdataobject> Users) {processusers (users ); Return   This . JSON ( New {Success = True , User = users}, jsonrequestbehavior. allowget );} Private List <userdataobject> processusers (list <userdataobject> Users ){ Int I = 1; Foreach (VAR user In Users) {user. ID = guid. Empty. tostring (); User. Username = "Server name" + I ++ ;} Return Users;} [allowanonymous] [httppost] [jsonmodelpost (jsonmodelpostattribute. parametertype. Single)] Public Jsonresult createuser (userdataobject user) {var list = New List <userdataobject> ( New Userdataobject [] {user}); processusers (list ); Return   This . JSON ( New {Success = True , User = list [0]}, jsonrequestbehavior. allowget );}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.