MVC5プロジェクトソリューション内にWebAPIコントローラーがあります。 WebAPIには、特定のフォルダー内のすべてのファイルをJsonリストとして返すメソッドがあります。
[{"name":"file1.Zip", "path":"c:\\"}, {...}]
HomeControllerからこのメソッドを呼び出し、Json応答をList<QDocument>
に変換し、このリストをRazorビューに返します。このリストは空の場合があります:フォルダーにファイルがない場合は[]
。
これはAPIControllerです:
public class DocumentsController : ApiController
{
#region Methods
/// <summary>
/// Get all files in the repository as Json.
/// </summary>
/// <returns>Json representation of QDocumentRecord.</returns>
public HttpResponseMessage GetAllRecords()
{
// All code to find the files are here and is working perfectly...
return new HttpResponseMessage()
{
Content = new StringContent(JsonConvert.SerializeObject(listOfFiles), Encoding.UTF8, "application/json")
};
}
}
これが私のHomeControllerです。
public class HomeController : Controller
{
public Index()
{
// I want to call APi GetAllFiles and put the result to variable:
var files = JsonConvert.DeserializeObject<List<QDocumentRecord>>(API return Json);
}
}
最後に、これが必要な場合のモデルです:
public class QDocumentRecord
{
public string id {get; set;}
public string path {get; set;}
.....
}
それでは、どうすればこの呼び出しを行うことができますか?
HomeControllerからこのメソッドを呼び出し、Json応答をListに変換します
いいえ、しません。コードが手の届く範囲にある場合、HTTP呼び出しと(デ)シリアル化のオーバーヘッドを追加したくありません。同じアセンブリ内でも同じです!
あなたのApiControllerは、とにかく (私の好みの)規約 に反しています。具体的な型を返します。
_public IEnumerable<QDocumentRecord> GetAllRecords()
{
listOfFiles = ...
return listOfFiles;
}
_
それが望ましくなく、HttpResponseMessage
を返す必要があると確信している場合でも、 自分でJsonConvert.SerializeObject()
_を呼び出す必要はありません はまったくありません。
_return Request.CreateResponse<List<QDocumentRecord>>(HttpStatusCode.OK, listOfFiles);
_
繰り返しになりますが、ビジネスロジックをコントローラーに含めたくないので、それを作業を行うクラスに抽出します。
_public class FileListGetter
{
public IEnumerable<QDocumentRecord> GetAllRecords()
{
listOfFiles = ...
return listOfFiles;
}
}
_
どちらにしても、このクラスまたはApiControllerをMVCコントローラーから直接呼び出すことができます。
_public class HomeController : Controller
{
public ActionResult Index()
{
var listOfFiles = new DocumentsController().GetAllRecords();
// OR
var listOfFiles = new FileListGetter().GetAllRecords();
return View(listOfFiles);
}
}
_
しかし、本当に、本当にHTTPリクエストを行う必要がある場合は、HttpWebRequest
、WebClient
、HttpClient
、またはRestSharp
を使用できます。存在します。
ここでは非常に遅いですが、以下のコードを共有すると考えられます。同じソリューションでWebApiをまったく別のプロジェクトとして使用している場合、以下のようにMVCコントローラーから同じものを呼び出すことができます。
public class ProductsController : Controller
{
// GET: Products
public async Task<ActionResult> Index()
{
string apiUrl = "http://localhost:58764/api/values";
using (HttpClient client=new HttpClient())
{
client.BaseAddress = new Uri(apiUrl);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await client.GetAsync(apiUrl);
if (response.IsSuccessStatusCode)
{
var data = await response.Content.ReadAsStringAsync();
var table = Newtonsoft.Json.JsonConvert.DeserializeObject<System.Data.DataTable>(data);
}
}
return View();
}
}
ApiController呼び出し-DocumentsControllerにあるコードを、HomeControllerとDocumentControllerの両方から呼び出すことができるクラスに単純に移動してみませんか。両方のコントローラーから呼び出すクラスにこれを引き出します。あなたの質問のこのもの:
//ファイルを見つけるためのすべてのコードはここにあり、完全に機能しています...
同じWebサイト上の別のコントローラーからAPIコントローラーを呼び出すことは意味がありません。
これにより、将来コードに戻り、ファイルを見つけてそこでロジックを実行するための共通のクラスが1つできるようになります...
さて、あなたはそれを多くの方法で行うことができます...それらの1つは HttpRequest を作成することです独自のMVCから独自のwebapiを呼び出すことはお勧めしません(アイデアは冗長です...)、ただし、 こちらはエンドツーエンドのチュートリアルです 。
コントローラ:
public JsonResult GetProductsData()
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:5136/api/");
//HTTP GET
var responseTask = client.GetAsync("product");
responseTask.Wait();
var result = responseTask.Result;
if (result.IsSuccessStatusCode)
{
var readTask = result.Content.ReadAsAsync<IList<product>>();
readTask.Wait();
var alldata = readTask.Result;
var rsproduct = from x in alldata
select new[]
{
Convert.ToString(x.pid),
Convert.ToString(x.pname),
Convert.ToString(x.pprice),
};
return Json(new
{
aaData = rsproduct
},
JsonRequestBehavior.AllowGet);
}
else //web api sent error response
{
//log response status here..
var pro = Enumerable.Empty<product>();
return Json(new
{
aaData = pro
},
JsonRequestBehavior.AllowGet);
}
}
}
public JsonResult InupProduct(string id,string pname, string pprice)
{
try
{
product obj = new product
{
pid = Convert.ToInt32(id),
pname = pname,
pprice = Convert.ToDecimal(pprice)
};
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:5136/api/product");
if(id=="0")
{
//insert........
//HTTP POST
var postTask = client.PostAsJsonAsync<product>("product", obj);
postTask.Wait();
var result = postTask.Result;
if (result.IsSuccessStatusCode)
{
return Json(1, JsonRequestBehavior.AllowGet);
}
else
{
return Json(0, JsonRequestBehavior.AllowGet);
}
}
else
{
//update........
//HTTP POST
var postTask = client.PutAsJsonAsync<product>("product", obj);
postTask.Wait();
var result = postTask.Result;
if (result.IsSuccessStatusCode)
{
return Json(1, JsonRequestBehavior.AllowGet);
}
else
{
return Json(0, JsonRequestBehavior.AllowGet);
}
}
}
/*context.InUPProduct(Convert.ToInt32(id),pname,Convert.ToDecimal(pprice));
return Json(1, JsonRequestBehavior.AllowGet);*/
}
catch (Exception ex)
{
return Json(0, JsonRequestBehavior.AllowGet);
}
}
public JsonResult deleteRecord(int ID)
{
try
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:5136/api/product");
//HTTP DELETE
var deleteTask = client.DeleteAsync("product/" + ID);
deleteTask.Wait();
var result = deleteTask.Result;
if (result.IsSuccessStatusCode)
{
return Json(1, JsonRequestBehavior.AllowGet);
}
else
{
return Json(0, JsonRequestBehavior.AllowGet);
}
}
/* var data = context.products.Where(x => x.pid == ID).FirstOrDefault();
context.products.Remove(data);
context.SaveChanges();
return Json(1, JsonRequestBehavior.AllowGet);*/
}
catch (Exception ex)
{
return Json(0, JsonRequestBehavior.AllowGet);
}
}