Dus*_*sda 9 c# asp.net-mvc asp.net-mvc-routing
我有一个搜索Api,我正在努力,需要在一个Html块中返回搜索结果(使用客户端已经定义的样式).我还想在Json中返回结果,以便我们最终将使用的未来Api内容.目前,路线看起来像这样:
/api/1/search/json?param1=blah¶m2=blah&etc
/api/1/search/html?param1=blah¶m2=blah&etc
Run Code Online (Sandbox Code Playgroud)
作为参考,此处的模式为/ {area}/1/{controller}/{action}.
我喜欢一些Api的外观,我看到返回的结果会有不同的格式,具体取决于它们在url中的'扩展',la:
/api/1/search.json?param1=blah¶m2=blah&etc
Run Code Online (Sandbox Code Playgroud)
但是,我还没有想出如何配置Asp.Net的Mvc路由来支持这种风格.ApiAreaRegistration.cs中的常规路由是:
context.MapRoute(
"Api_default",
"Api/1/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional });
Run Code Online (Sandbox Code Playgroud)
我尝试了以下定义的一般,但不起作用:
//search api
context.MapRoute(
"searchJson",
"api/1/{controller}.{action}",
new { controller = "SearchController" });
Run Code Online (Sandbox Code Playgroud)
如何配置路由以启用.format样式的URL?
context.MapRoute(
"Api_default",
"{area}/1/{controller}.{format}",
new { action = "Index", id = UrlParameter.Optional });
Run Code Online (Sandbox Code Playgroud)
可能就是你想要的.然后你可以根据传入的参数返回不同的结果.
在Api区域的上下文中,SearchController将如下所示:
public class SearchController : Controller
{
public ActionResult Index(string format, SearchModel search)
{
var results = searchFacade.SearchStuff(search);
if(format.Equals("xml"))
return Xml(results); //using an XmlResult or whatever
if(format.Equals("html"))
return View(results);
return Json(results, JsonRequestBehavior.AllowGet);
}
}
Run Code Online (Sandbox Code Playgroud)
路由有点棘手,因为你在可选的参数之后插入了一个必需的参数 - 一般来说,我建议使用Accept-Type标题,它更加RESTful并且不那么棘手.但是,对于某些客户而言,这可能会有问题.
路由必须将带有id且没有id的表单考虑在内:
context.MapRoute(
"Api_default",
"Api/1/{controller}/{action}/{id}.{format}",
new { action = "Index" });
context.MapRoute(
"Api_default_2",
"Api/1/{controller}/{action}.{format}",
new { action = "Index" });
Run Code Online (Sandbox Code Playgroud)
由于除输出序列化外,结果通常没有差异,因此您可能不希望路由到不同的操作.定制ActionResult可能会有所帮助.这样,不同的序列化逻辑可以集中并且易于扩展.
public class RestResult<T> : ActionResult
{
public T Data { get; set; }
public RestResult(T data)
{
Data = data;
}
private string SerializeToJson()
{
MemoryStream ms = new MemoryStream();
YourFavouriteJsonSerializer.SerializeToStream(Data, Data.GetType(), ms);
var temp = Encoding.UTF8.GetString(ms.ToArray());
return temp;
}
public override void ExecuteResult(ControllerContext context)
{
string resultString = string.Empty;
string resultContentType = string.Empty;
// alternatively, use the route value dictionary
// or the accept-type, as suggested.
var extension = SomeExtensionParserMethod(context.RequestContext.HttpContext.Request.RawUrl);
string result = string.Empty;
if (extension == "json")
{
result = SerializeJson()
}
else if(...)
// etc
context.RequestContext.HttpContext.Response.Write(resultString);
context.RequestContext.HttpContext.Response.ContentType = resultContentType;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5749 次 |
| 最近记录: |