我正在使用ASP.NET MVC 3編寫一個RESTful Web服務。我正在分別使用基本的GET/POST/PUT映射來檢索/創建/更新操作。它適用於我的一個域類型,但是我爲另一個類型實現了完全相同的一組操作,並且我從本地ASP.NET開發服務器獲得了401未經授權的響應。MVC3 401 POST請求後重定向時未經授權的響應
首先,這裏是在路由創建MyApiAreaRegistration.cs的RegisterArea方法的相關部分(我已刪除了簡潔的更新方法):
// student detail
context.MapRoute(
"StudentDetailV1",
"MyApi/v1/family/{email}/student/{id}",
new { controller = "Student", action = "StudentDetail" },
new { httpMethod = new HttpMethodConstraint("GET") }
);
// create student
context.MapRoute(
"CreateStudentV1",
"MyApi/v1/family/{email}/student",
new { controller = "Student", action = "CreateStudent" },
new { httpMethod = new HttpMethodConstraint("POST") }
);
// family detail
context.MapRoute(
"FamilyDetailV1",
"MyApi/v1/family/{email}",
new { controller = "Student", action = "FamilyDetail" },
new { httpMethod = new HttpMethodConstraint("GET") }
);
// create family
context.MapRoute(
"CreateFamilyV1",
"MyApi/v1/family",
new { controller = "Student", action = "CreateFamily" },
new { httpMethod = new HttpMethodConstraint("POST") }
);
而在StudentController:
/// <summary>
/// return json representation of FamilyDto
/// </summary>
/// <param name="email"></param>
/// <returns></returns>
[HttpGet]
public ActionResult FamilyDetail(string email)
{
Family f = _studentDataAccess.GetFamilyByEmail(email.Trim());
if (f == null)
{
return HttpNotFound();
}
FamilyDto familyDto = FamilyDtoAssembler.GetDtoFromFamily(f);
return Json(familyDto, JsonRequestBehavior.AllowGet);
}
[HttpPost]
public ActionResult CreateFamily(FamilyDto familyDto)
{
if (string.IsNullOrWhiteSpace(familyDto.Email))
{
return new HttpStatusCodeResult(409, "Email address is required.");
}
// check for already existing family with that email.
Family f = _studentDataAccess.GetFamilyByEmail(familyDto.Email.Trim());
if (f != null)
{
return new HttpStatusCodeResult(409, "Email address must be unique.");
}
// turn family into a Family object with Parents
Family family = FamilyDtoAssembler.GetFamilyFromDto(familyDto);
// save family via dal (username = family email)
_studentDataAccess.CreateFamily(family, family.Email);
// return redirect to family detail
return RedirectToRoute("FamilyDetailV1", new { email = family.Email });
}
[HttpPost]
public ActionResult CreateStudent(string email, StudentDto studentDto)
{
if (string.IsNullOrWhiteSpace(email))
{
return HttpNotFound();
}
Family family = _studentDataAccess.GetFamilyByEmail(email.Trim());
if (family == null)
{
return HttpNotFound();
}
Student s = StudentDtoAssembler.GetStudentFromDto(_repository, studentDto);
s.Family = family;
_studentDataAccess.CreateStudent(s, email);
return RedirectToRoute("StudentDetailV1", new { email = email, id = s.Id });
}
[HttpGet]
public ActionResult StudentDetail(string email, int id)
{
Student s = _studentDataAccess.GetStudent(id);
if (s == null || s.Family.Email != email)
{
return HttpNotFound();
}
StudentDto studentDto = GeneralDtoAssembler.GetSingleStudentDto(s, s.MatsRegistrations);
return Json(studentDto, JsonRequestBehavior.AllowGet);
}
現在,當我使用Fiddler爲「創建家庭」操作製作POST請求時,如果適當的JSON請求主體與家庭DTO的定義相匹配,則該操作返回一個302響應,該響應會重定向到Family Detail操作爲新創建的家庭。這工作正是我想要的。但問題是「創建學生」行爲。當我通過它在它工作正常調試步驟,並返回RedirectToRoute結果,但是我曾經看到提琴手如下回應:
HTTP/1.1 401 Unauthorized
Server: ASP.NET Development Server/10.0.0.0
Date: Tue, 17 Apr 2012 16:42:10 GMT
X-AspNet-Version: 4.0.30319
jsonerror: true
Cache-Control: private
Content-Type: application/json; charset=utf-8
Content-Length: 105
Connection: Close
{"Message":"Authentication failed.","StackTrace":null,"ExceptionType":"System.InvalidOperationException"}
我已經試過所有我能想到的,從改變身份驗證模式從web.config中的「Windows」到「None」,重新排序路由,返回RedirectToAction而不是RedirectToRoute,並且沒有任何效果。請注意,如果我只是從CreateStudent直接返回Json結果而不是RedirectToRoute結果,那麼它可以正常工作(200狀態,我看到結果就好)。但是我不明白爲什麼CreateStudent和CreateFamily的行爲不同,現在已經讓我瘋狂了2天。哈;的LP?
如果您直接在瀏覽器中「GET/MyApi/v1/family/email @ foo.com/student/123」,會發生什麼情況?是否正在執行'StudentDetail'動作或者您是否獲得401? – 2012-04-17 17:12:31
是的,Darin,如果您直接使用Fiddler或瀏覽器請求'StudentDetail'動作,則執行正確。 – technivore 2012-04-17 17:16:32
我認爲SO需要15個代表來回答你自己的問題,所以如果你能得到另一個upvote你應該能夠。 – 2012-04-17 18:49:59