設計Web API的官方MS或最佳體系結構實踐是什麼?它採用複雜類型並返回複雜類型?接受複雜類型並返回複雜類型的Web API?
難度: 傳遞複雜類型通過HTTP沒有參考到中央數據類型,同時保持RESTful的。
目前: 我成功地這樣做,但我的老闆介紹最佳做法爭論,如果我有正確的做到了這一點。微軟聲稱你可以傳入一個複雜的類型,就像一個[FromBody]屬性的參數,但我沒有任何運氣(一個複雜類型的工作示例將會很棒)。
類型模型的知識: 客戶端應用程序和Web API都必須包含類的中央庫的引用。圍繞這是使用WSDL來傳遞每個請求的類型信息,我的老闆不喜歡這樣,因爲我們將有庫DLL的不同彙編(從一個客戶端應用程序到下),我可以看到的唯一途徑(不理想在遠程位置移動,因此REST),任何建議。
目前代碼(工作):
控制器調用API
[Authorize]
public async Task<ActionResult> Index()
{
InstallerPinModel currentInstaller = new InstallerPinModel();
currentInstaller.userName = "from Controller";
Task<WebResponse> response = checkPinTime(currentInstaller);//checkPinTime calls API
//I found the following two lines are very helpful for debugging
//while(response.IsCompleted == false)
//Thread.Sleep(100);
Stream responseResultsStream = response.Result.GetResponseStream();
int responseResultContentLength = (int)response.Result.ContentLength;
byte[] responseResultContentAsBytes = new byte[responseResultContentLength];
responseResultsStream.Read(responseResultContentAsBytes, 0, responseResultContentLength);//Pull Data Stream into Byte[] responseResultContentAsBytes
string responseResultsAsString = System.Text.Encoding.UTF8.GetString(responseResultContentAsBytes);
JavaScriptSerializer serializesJS = new JavaScriptSerializer();
currentInstaller = serializesJS.Deserialize<InstallerPinModel>(responseResultsAsString);
if(currentInstaller.userName == "from API")
returnView = GoalView;
else
returnView = TimedOutView;
}
return View();
}
public Task<WebResponse> checkPinTime(InstallerPinModel incomingUser)//Function to call Post Web API
{
string requestData = new JavaScriptSerializer().Serialize(incomingUser);//Just slightly different syntax
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] requestDataAsBytes = encoding.GetBytes(requestData);
WebRequest request = WebRequest.Create("http://localhost:51366/api/InstallerPin");
request.Method = "POST";
request.ContentLength = requestDataAsBytes.Length;
request.ContentType = "application/x-www-form-urlencoded";
Stream requestDataStream = request.GetRequestStream();
requestDataStream.Write(requestDataAsBytes, 0, requestDataAsBytes.Length);
requestDataStream.Close();
Task<WebResponse> response = request.GetResponseAsync();
return response;
}
的Web API
public async Task<HttpResponseMessage> Post()
{
//ReadIncoming
InstallerPinModel incomingInstallerPIN = new InstallerPinModel();
Task<byte[]> requestContentByteArray = Request.Content.ReadAsByteArrayAsync();
ASCIIEncoding encoding = new ASCIIEncoding();
string requestContentAsString = encoding.GetString(await requestContentByteArray);
JavaScriptSerializer serializesJS = new JavaScriptSerializer();
incomingInstallerPIN = serializesJS.Deserialize<InstallerPinModel>(requestContentAsString);
//This is where the post would take place
//Send Responspe Object
InstallerPinModel outgoingInstallerPIN = new InstallerPinModel();
outgoingInstallerPIN = incomingInstallerPIN;
outgoingInstallerPIN.userName = "from API";
//BuildOutgoing
string responseAsString = serializesJS.Serialize(outgoingInstallerPIN);
StringContent responseContent = new StringContent(responseAsString);
await responseContent.LoadIntoBufferAsync();
HttpResponseMessage returnableResponseMessage = new HttpResponseMessage();
returnableResponseMessage.Content = responseContent;
return returnableResponseMessage;
}
路由
config.Routes.MapHttpRoute(
name: "noParamsInURL",
routeTemplate: "api/{controller}",
defaults: new { }
);//Route for InstallerPinController
//(Default) Route for standard API Controllers
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}/{application}",
defaults: new { id = RouteParameter.Optional, application = RouteParameter.Optional });
類型型號
public class InstallerPinModel
{
public string userName {get; set;}
public int pin {get; set;}
public int newPin { get; set; }
}
請確保在API和客戶端應用程序中都包含對類型模型的引用。