Good and full implementation of RSS feeds in ASP.net MVC - asp.net-mvc

I've seen a few examples of RSS Feeds in ASP.NET MVC, like this, and some samples in projects (like Oxite), but none of them are complete.
Eg. None of them check for the header
If-Modified-Since
in the request, to save bandwidth.
I do not want to reinvent the wheel, so I stop here asking for some directions.

I haven't seen it implement HTTP_IF_MODIFIED_SINCE, but I would look into using the SyndicationFeed class. It makes it very simple to handle feeds without any parsing. I am currently using it for Atom feeds, but it is supposed to work for RSS as well:
function SyndicationFeed GetFeed(string url) {
XmlReader reader = XmlReader.Create(url);
SyndicationFeed feed = SyndicationFeed.Load(reader);
return feed;
}
public ActionResult ShowFeed()
{
string feedUrl = "somefeedurl";
SyndicationFeed feed = GetFeed(feedUrl);
return View(feed);
}
...then in the view:
<%foreach (var item in ViewData.Model.Items) { %>
<li><%=item.Title.Text %></li>
<% } %>

If you use HttpContext.Response.Cache.SetCacheability, SetExpires and SetMaxAge then the ASP.NET caching system will take care of this for you - it understands the If-Modified-Since header. This blog entry shows how you can create an MVC Action Filter to do the necessary in MVC.

I ended up with this. Please comment or edit the post if you find any error or better way to do it.
RssController
Imports System.ServiceModel.Syndication
Imports System.Xml
Imports System.Web.HttpContext
Function MasterRSS()
Dim baseURL As String = "http://www.mysite.com"
Dim feed As New SyndicationFeed("MySite - Master RSS", "", New Uri(baseURL))
''//Add a custom attribute.
Dim xqName As New XmlQualifiedName("CustomAttribute")
feed.AttributeExtensions.Add(xqName, "Value")
Dim sp As New SyndicationPerson("jerry#mysite.com", "Jerry Seinfeld", "http://Jerry.blog.com")
feed.Authors.Add(sp)
Dim category As New SyndicationCategory("Category")
feed.Categories.Add(category)
feed.Contributors.Add(New SyndicationPerson("cosmo#mysite.com", "Cosmo Kramer", "http://kramer.blog.com"))
feed.Copyright = New TextSyndicationContent("MySite 2008")
feed.Description = New TextSyndicationContent("My description")
''//Add a custom element.
Dim doc As New XmlDocument()
Dim feedElement As XmlElement = doc.CreateElement("CustomElement")
feedElement.InnerText = "Some text"
feed.ElementExtensions.Add(feedElement)
feed.Generator = "Custom"
feed.Id = "MySiteFeedID"
feed.ImageUrl = New Uri("http://www.mysite.com/content/images/logo.png")
''//Items
Dim ModifiedSince As Date
If Not Date.TryParse(Current.Request.Headers("If-Modified-Since"), ModifiedSince) Then
ModifiedSince = Date.Today.AddDays(-30) ''//Or whatever make sense to you.
Else
ModifiedSince.AddMinutes(-5) ''//Just in case, we do not want to miss any item.
End If
''//the list of items.
Dim items As New List(Of SyndicationItem)()
Dim db As New mainDataContext
Dim textContent As TextSyndicationContent, Item As SyndicationItem
''//Then send the list of post, comments, whatever.
Dim Posts = (From p In db.Posts Where c.Date >= ModifiedSince Order By p.Date Descending)
For Each Post In Posts
Dim sb As New StringBuilder
sb.AppendFormat("<p>{0}</p>", Post.FullText)
textContent = New TextSyndicationContent(sb.ToString, TextSyndicationContentKind.Html)
Item = New SyndicationItem("Post " + Post.PostID.ToString, textContent, New Uri(baseURL + "/Post/View/" + Post.PostID.ToString), "Post" + Post.PostID.ToString, Post.Date)
items.Add(Item)
Next
If items.Count = 0 Then
''//send a 304 to the browser.
Return View("304")
End If
feed.Items = items
feed.Language = "es-ar"
feed.LastUpdatedTime = (From i In items Select i.LastUpdatedTime Order By LastUpdatedTime Descending).FirstOrDefault
''//Not needed in this sample.
''//Dim link As New SyndicationLink(New Uri("http://server/link"), "alternate", "Link Title", "text/html", 1000)
''//feed.Links.Add(link)
ViewData("feed") = feed
Return View("Rss")
End Function
Rss View (rss.aspx)
Dim htmlwriter As System.IO.Stream = Response.OutputStream
Dim rssWriter As System.Xml.XmlWriter = System.Xml.XmlWriter.Create(htmlwriter)
Dim feed As System.ServiceModel.Syndication.SyndicationFeed = ViewData("feed")
Dim rssFormatter As New System.ServiceModel.Syndication.Rss20FeedFormatter(feed)
rssFormatter.WriteTo(rssWriter)
rssWriter.Close()
This way, you can reuse the view

Related

How do I get User's Role within code portion of _LoginPartial?

I am using MVC Entity Framework and I need to get a user's role within the _LoginPartial for some role-specific functionality within the nav bar. What is the best way to get that there?
I've tried using Dim myRoles = Roles.GetRolesForUser(), but that comes up with nothing. Which is wrong, because I use role-specific functionality elsewhere and that works fine.
Following the link in Marco's comment, it mentions using ClaimsIdentity, but for me it says ClaimsIdentity is not declared (Rick left a comment there this past August explaining it's not working for him like something changed in the past 2 years).
I had also tried this, which is similar to code in a controller I have elsewhere which does work:
Dim context As IOwinContext = New OwinContext
Dim manager = New AppUserManager(New UserStore(Of AppUser(context.Get(Of MyAppIdentityDbContext)()))
Dim userInfo = manager.FindById(curUserID)
Dim userRole As String = userInfo.Roles(0).RoleId
myRole = db.Roles.Where(Function(x) x.Id = userRole).FirstOrDefault().Name
But at runtime I get an error on the "Dim manager" line that says
An exception of type 'System.ArgumentNullException' occurred in
Microsoft.AspNet.Identity.EntityFramework.dll but was not handled in
user code Additional information: Value cannot be null.
I have no idea what value it's talking about.
Thanks to Marco's help and the other question he linked, I got it using the following code:
#Imports Microsoft.AspNet.Identity
#Imports System.Security.Claims
#Code
Dim db = New MyAppIdentityDbContext
Dim curUserID = User.Identity.GetUserId()
Dim myFirstName As String = (From users In db.Users Where users.Id = curUserID Select users.FirstName).FirstOrDefault
Dim myRole As String = ""
If curUserID IsNot Nothing AndAlso curUserID <> "" Then
Dim userID = CType(User.Identity, ClaimsIdentity)
Dim claims = userID.Claims
Dim roleType = userID.RoleClaimType
Dim myRoles = claims.Where(Function(c) c.Type = roleType).ToList()
myRole = (myRoles.FirstOrDefault.ToString)
'Here myRole contains whole https string - need to strip it to actual value
Dim lastInd = myRole.LastIndexOf(" ")
myRole = myRole.Substring(lastInd + 1, myRole.Length - (lastInd + 1))
End If
End Code

GMail API retrieve From, To, etc. from a message?

How I can do to retrieve, from, to, subject, etc. from a message with this code ? Actually I can retrive list of message in a folder (label) but i want to retrieve fron, to, sender, etc. to display in a grid
Private Sub LoadMailGrid(ByVal FolderName As String)
Dim request As Google.Apis.Gmail.v1.UsersResource.MessagesResource.ListRequest = myGMailService.Users.Messages.List("xxxxxxx#gmail.com")
request.Q = "label: " + folderName
Dim messagesList As ListMessagesResponse = request.Execute()
Dim SubjectList As List(Of GMailMessageSummary) = New List(Of GMailMessageSummary)
Dim mail As GMailMessageSummary
For Each Message In messagesList.Messages
mail = New GMailMessageSummary
mail.MessageID = Message.Id
**mail.From = Message.**
mail.Subject = "Courriel " + x.ToString
mail.Received = Today
SubjectList.Add(mail)
Next
grdGMail.DataSource = SubjectList
grdGMail.DataBind()
End Sub
List message just returns the message Ids and thread ids, not the full content (since that could be an entire email which could be huge like 25MB). So if you want certain info on all of them then call messages.get() in the loop. If you only want headers like To, From, Subject then you can call messages.get(format=METADATA), or however it looks in the language you're using.
https://developers.google.com/gmail/api/v1/reference/users/messages/get

How to Fill Drop Down List using Model in MVC

Function GetStateName() As List(Of SelectListItem)
Dim ListRoomMaster As List(Of MiscMaster) = New List(Of MiscMaster)
Dim rm As New MiscMaster
Using conn As New SqlConnection(connectionString)
Dim sSql = "Select * From dropdown"
Dim cmd As SqlCommand = New SqlCommand(sSql, conn)
conn.Open()
Dim rst As SqlDataReader = cmd.ExecuteReader
Do While rst.Read
rm.m_ddlId = rst!id
rm.ddlValue = rst!name
ListRoomMaster.Add(rm)
Loop
End Using
Dim Listxyz = (
From p In Enumerable.Range(0, 20)
Select New SelectListItem With {.Text = p.ToString(), .Value = p.ToString()})
Return Listxyz.ToList()
End Function
This is the code for GetStateName() Which I am calling from controller Before Viewing This Displays The Drop Down List With 0 to 19 numbers I know I have Miss Something But Don't Know Where to change as most of code are for Linq
This Is Controller Code
Function Index() As ActionResult
objMisc.StateValue = objMisc.GetStateName()
'objMisc.StateValue = obj
Return View(objMisc)
End Function
What I Exactly Want Is Fetching data from DataBase using query
DataBase Have field like follow
id | Value
1 | xyz
2 | abx
3 | kvd
I want to populate drop down List As xyz,abx,kvd
And when abx is selected I want to store 2 in database
If you are working with MVC then you can also get the Data directly in the Razor View from your Model. Because you are doing a SQL Query manually which isnt the puropse of MVC.
Your should return the Model and then you can simply do this:
#Html.DropDownListFor(m => m.column, Model.dropdown)
Let's make a couple of models:
public NameCode(string name)
{
Name = name;
Code = name;
}
public NameCodeCollection(IEnumerable<NameCodeItem> list) : base(list)
{
}
In razor:
#Html.DropDownListFor(m => m.modelid, new SelectList(Model.modeltext, "Name", "Code"))
Use the namecodecollection to feed your dropdown list & read from it.

Add menu item to Quickbooks

Is it possible to add a menu item to Quickbooks using the QBSDK?
I have found a couple of old examples that I can't make work.
I have created a custom application for my company and am trying to simplify it by making a menu item in Quickbooks.
Any help would be greatly appreciated.
Here is what I have tried so far, but I get an error message at the subAdd.SubscriberID.SetValue(Me.appGUID.ToString).
The error is: * Invalid GUID format. Must use zero for Custom Fields, or a GUID generated with GuidGen.exe for private data extensions.*
{
Dim subRq As ISubscriptionMsgSetRequest
subRq = MySessionManager.CreateSubscriptionMsgSetRequest(4, 0)
' Add a UIExtension subscription to our request
Dim subAdd As IUIExtensionSubscriptionAdd
subAdd = subRq.AppendUIExtensionSubscriptionAddRq
'
' set up the subscription request with the required information, we're adding to
' the file menu in this case, and just for fun, we're making it a cascading menu
subAdd.SubscriberID.SetValue(Me.appGUID.ToString) "<-----error happens here
subAdd.COMCallbackInfo.AppName.SetValue(Me.appName)
subAdd.COMCallbackInfo.ORProgCLSID.ProgID.SetValue("MenuEventContext.QBMenuListener")
subAdd.MenuExtensionSubscription.AddToMenu.SetValue("atmFile")
'
' For the cascade fun, we're just going to add items to the cascade menu...
Dim subMenu As IMenuItem
For i = 1 To 5
subMenu = subAdd.MenuExtensionSubscription.ORMenuSubmenu.Submenu.MenuItemList.Append
'
' this is the text that the user will see in QuickBooks:
subMenu.MenuText.SetValue("Sub Item " & i)
'
' this is the tag we'll get in our event handler to know which menu item was
' selected:
subMenu.EventTag.SetValue("SubMenu" & i)
Next i
'
' Send the request and get the response, since we're sending only one request there
' will be only one response in the response list
Dim subRs As ISubscriptionMsgSetResponse
subRs = MySessionManager.DoSubscriptionRequests(subRq)
Dim resp As IResponse
'
' Check the response and display an appropriate message to the user.
resp = subRs.ResponseList.GetAt(0)
If (resp.StatusCode = 0) Then
MsgBox("Successfully added to QuickBooks File menu, restart QuickBooks to see results")
Else
MsgBox("Could not add to QuickBooks menu: " & resp.StatusMessage)
End If
MySessionManager.CloseConnection()
MySessionManager = Nothing
Exit Sub
handleError:
MsgBox("Encountered error subscribing: " & Err.Description)
If Not MySessionManager Is Nothing Then
MySessionManager.CloseConnection()
End If
End Sub
The answer is yes.
The only purpose of UIExtensionSubscription is to add menu items to the top menus. Clicking the menus will then start your app, if it isn't already running, and pass it information about the current focused Quickbooks window.
Your application must be com accessible and registered.
As for your sample make sure you are passing { } around your GUID. I don't use function call unsure if you might need to cast to a string first or not.
There is a sample console app in C# in the current QBPOSSDK download from Intuit. I would thoroughly read the programmers guide and look at that sample.
One of my working requests, pretty close to the intuit sample:
Private Shared Function GetUIExtensionSubscriptionAddXML(ByVal strMenuName As String, ByVal strMainMenuName As String) As String
'strMainMenuName would be "Company" for example
'Create the qbXML request
Dim requestXMLDoc As New XmlDocument()
requestXMLDoc.AppendChild(requestXMLDoc.CreateXmlDeclaration("1.0", Nothing, Nothing))
requestXMLDoc.AppendChild(requestXMLDoc.CreateProcessingInstruction("qbxml", "version=""5.0"""))
Dim qbXML As XmlElement = requestXMLDoc.CreateElement("QBXML")
requestXMLDoc.AppendChild(qbXML)
'subscription Message request
Dim qbXMLMsgsRq As XmlElement = requestXMLDoc.CreateElement("QBXMLSubscriptionMsgsRq")
qbXML.AppendChild(qbXMLMsgsRq)
'UI Extension Subscription ADD request
Dim uiExtSubscriptionAddRq As XmlElement = requestXMLDoc.CreateElement("UIExtensionSubscriptionAddRq")
qbXMLMsgsRq.AppendChild(uiExtSubscriptionAddRq)
'UI Extension Subscription ADD
Dim uiExtEventSubscriptionAdd As XmlElement = requestXMLDoc.CreateElement("UIExtensionSubscriptionAdd")
uiExtSubscriptionAddRq.AppendChild(uiExtEventSubscriptionAdd)
'Add Subscription ID
uiExtEventSubscriptionAdd.AppendChild(requestXMLDoc.CreateElement("SubscriberID")).InnerText = MySubscriberGUID
'Add COM CallbackInfo
Dim comCallbackInfo As XmlElement = requestXMLDoc.CreateElement("COMCallbackInfo")
uiExtEventSubscriptionAdd.AppendChild(comCallbackInfo)
'Appname and CLSID
comCallbackInfo.AppendChild(requestXMLDoc.CreateElement("AppName")).InnerText = App_Name
comCallbackInfo.AppendChild(requestXMLDoc.CreateElement("CLSID")).InnerText = MyCLSID
' MenuEventSubscription
Dim menuExtensionSubscription As XmlElement = requestXMLDoc.CreateElement("MenuExtensionSubscription")
uiExtEventSubscriptionAdd.AppendChild(menuExtensionSubscription)
'Add To menu
menuExtensionSubscription.AppendChild(requestXMLDoc.CreateElement("AddToMenu")).InnerText = strMainMenuName
Dim menuItem As XmlElement = requestXMLDoc.CreateElement("MenuItem")
menuExtensionSubscription.AppendChild(menuItem)
'Add Menu Name
menuItem.AppendChild(requestXMLDoc.CreateElement("MenuText")).InnerText = strMenuName
menuItem.AppendChild(requestXMLDoc.CreateElement("EventTag")).InnerText = "menu_" & strMenuName.Replace(" ", "_")
Dim displayCondition As XmlElement = requestXMLDoc.CreateElement("DisplayCondition")
menuItem.AppendChild(displayCondition)
displayCondition.AppendChild(requestXMLDoc.CreateElement("VisibleIf")).InnerText = "InventoryEnabled"
displayCondition.AppendChild(requestXMLDoc.CreateElement("EnabledIf")).InnerText = "InventoryEnabled"
Dim strRetString As String = requestXMLDoc.OuterXml
WriteLocalLog("GetUIExtensionSubscriptionAddXML: " & strRetString)
Return strRetString
End Function

How to handle concurrency clash in ASP.Net MVC using post-redirect-get?

I use a post-redirect-get (PRG) pattern to save an entity in ASP.Net MVC 2. The controller methods are 'Save' (inserts or updates database) and 'Edit' (retrieves user input). In 'Save', I do modification check before saving by checking a 'version' column of the entity. If someone else has modified the entity, the 'version' column will not match and I will send error message to the user.
To maintain error messages, I use ModelState.Merge in 'Edit' method. The problem with this mechanism is that the user input is maintained and the user doesn't see the modification made by the other user. I avoid this problem by clearing ModelState before adding the concurrency clash message.
But I feel this solution is not optimal. How would you handle concurrency clash in ASP.Net MVC?
Here is the Edit method:
Public Function Edit() As ActionResult
Dim theevent As AEvents
If TempData("ModelState") IsNot Nothing And Not ModelState.Equals(TempData("ModelState")) Then
ModelState.Merge(CType(TempData("ModelState"), ModelStateDictionary))
End If
If RouteData.Values.ContainsKey("id") Then
theevent = NHibGet.EventWithPricingsByCode(RouteData.Values("id"))
Else
theevent = New AEvents
End If
Dim InputTemplate As New EventEdit With {.EventDate = theevent.EventDate, .EventName = theevent.EventName, .IsActive = theevent.IsActive}
If theevent.Template IsNot Nothing Then
InputTemplate.TemplateID = theevent.Template.ID
End If
Dim templates As IList(Of SeatTemplates) = NHibGet.TemplatesActive
ViewData("templates") = templates
ViewData("eventcode") = theevent.Code
ViewData("editversion") = theevent.Version
Return View(InputTemplate)
End Function
And the code for 'Save' is like this:
Public Function Save(ByVal id As Integer, ByVal UserData As EventEdit, ByVal EditVersion As Integer) As ActionResult
Dim theevent As AEvents
If id = 0 Then
theevent = New AEvents
Else
theevent = NHibGet.EventByCode(id)
End If
If theevent.Version <> EditVersion Then
ModelState.Clear()
ModelState.AddModelError("", "The event is modified by someone else")
Return RedirectToAction("Edit", New With {.id = id})
End If
If Not ModelState.IsValid Then
TempData("ModelState") = ModelState
Return RedirectToAction("Edit", New With {.id = id})
End If
theevent.EventDate = UserData.EventDate
theevent.EventName = UserData.EventName
theevent.IsActive = UserData.IsActive
theevent.Template = MvcApplication.CurrentSession.Load(Of SeatTemplates)(UserData.TemplateID)
Using trans As NHibernate.ITransaction = MvcApplication.CurrentSession.BeginTransaction
MvcApplication.CurrentSession.SaveOrUpdate(theevent)
Try
trans.Commit()
Catch ex As NHibernate.ADOException
trans.Rollback()
Throw ex
End Try
End Using
Return RedirectToAction("Edit", New With {.id = theevent.Code})
End Function
I am always in such a case instructs the user to refresh the page. It also gives him the opportunity to review fields values ​​that entered.

Resources